Explore all UUID Generator open source software, libraries, packages, source code, cloud functions and APIs.

Popular New Releases in UUID Generator

No Popular Releases are available at this moment for UUID Generator

Popular Libraries in UUID Generator

uuid-generator

by furkankahvecii doticonphpdoticon

star image 3 doticon

Pure PHP UUID generator

uuid-generator

by sanikapanika doticonjavadoticon

star image 2 doticon

Generate uuids by just typing uuid to terminal

Trending New libraries in UUID Generator

uuid-generator

by furkankahvecii doticonphpdoticon

star image 3 doticon

Pure PHP UUID generator

uuid-generator

by sanikapanika doticonjavadoticon

star image 2 doticon

Generate uuids by just typing uuid to terminal

Top Authors in UUID Generator

1

sanikapanika

1 Libraries

star icon2

2

furkankahvecii

1 Libraries

star icon3

1

1 Libraries

star icon2

2

1 Libraries

star icon3

Trending Kits in UUID Generator

No Trending Kits are available at this moment for UUID Generator

Trending Discussions on UUID Generator

MySQL + Kubernetes statefulset with defined env variables

How to convert a UUID to a number with less than 40 digits?

Save Variable from a Pre-request script to use in a new Request

YAML/YQ - remove sections that have sub-sections containing a particular attribute match

How can I reference an array when I don't know the name of it?

React Context API context API issues , when adding and removing an items from UI

BLE: How to get correct service UUID and characteristic UUID?

Syntax to manually insert a UUID value in Postgres

QUESTION

MySQL + Kubernetes statefulset with defined env variables

Asked 2022-Mar-08 at 14:56

I'm following Kubernetes's MySQL as a StatefulSet from here. What the tutorial did not cover is how do I specify other environmental variables, like MYSQL_ROOT_PASSWORD, MYSQL_USER and such. I tried doing it myself, but didn't work. Here's the code:

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169

and here is my kubectl get all,secret,configmap's result:

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194

When I tried to describe the mysql-1 pod, it said that:

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195

But when I tried logging in using my defined root password on mysql-0 pod, it works. I have also tried looking a duplicated question here, but the past's tutorial code has changed (FYI, I also tried it too despite the change), so it did not really help. Any help will do! Thanks in advance!

UPDATE I tried adding this:

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195  - name: MYSQL_ROOT_HOST
196    value: "%"
197

on my mysql and xtrabackup containers, also didn't work, here's the get pods --watch return:

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195  - name: MYSQL_ROOT_HOST
196    value: "%"
197NAME                          READY   STATUS     RESTARTS   AGE
198mysql-0                       0/2     Init:0/2   0          7s
199mysql-0                       0/2     Init:1/2   0          18s
200mysql-0                       0/2     PodInitializing   0          19s
201mysql-0                       2/2     Running           0          20s
202mysql-1                       0/2     Pending           0          0s
203mysql-1                       0/2     Pending           0          0s
204mysql-1                       0/2     Pending           0          8s
205mysql-1                       0/2     Init:0/2          0          8s
206mysql-1                       0/2     Init:1/2          0          26s
207mysql-1                       0/2     Init:1/2          0          27s
208mysql-1                       0/2     PodInitializing   0          34s
209mysql-1                       2/2     Running           0          35s
210mysql-2                       0/2     Pending           0          0s
211mysql-2                       0/2     Pending           0          0s
212mysql-1                       1/2     Error             0          37s
213mysql-1                       1/2     Error             1          38s
214mysql-2                       0/2     Pending           0          3s
215mysql-2                       0/2     Init:0/2          0          3s
216mysql-1                       1/2     CrashLoopBackOff   1          53s
217mysql-1                       1/2     Error              2          54s
218mysql-2                       0/2     Init:1/2           0          21s
219mysql-2                       0/2     Init:Error         0          22s
220mysql-2                       0/2     Init:Error         1          23s
221mysql-2                       0/2     Init:CrashLoopBackOff   1          24s
222mysql-1                       1/2     CrashLoopBackOff        2          64s
223mysql-2                       0/2     Init:Error              2          38s
224mysql-1                       1/2     Error                   3          79s
225mysql-2                       0/2     Init:CrashLoopBackOff   2          50s
226mysql-1                       1/2     CrashLoopBackOff        3          92s
227mysql-2                       0/2     Init:Error              3          62s
228mysql-2                       0/2     Init:CrashLoopBackOff   3          74s
229mysql-1                       1/2     Error                   4          2m1s
230mysql-1                       1/2     CrashLoopBackOff        4          2m11s
231mysql-2                       0/2     Init:Error              4          113s
232mysql-2                       0/2     Init:CrashLoopBackOff   4          2m6s
233mysql-1                       1/2     Error                   5          3m29s
234mysql-1                       1/2     CrashLoopBackOff        5          3m41s
235mysql-2                       0/2     Init:Error              5          3m23s
236mysql-2                       0/2     Init:CrashLoopBackOff   5          3m34s
237

For some reason mysql-1 ran for a while, then stopped.

Logs from mysql-1 pod :

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195  - name: MYSQL_ROOT_HOST
196    value: "%"
197NAME                          READY   STATUS     RESTARTS   AGE
198mysql-0                       0/2     Init:0/2   0          7s
199mysql-0                       0/2     Init:1/2   0          18s
200mysql-0                       0/2     PodInitializing   0          19s
201mysql-0                       2/2     Running           0          20s
202mysql-1                       0/2     Pending           0          0s
203mysql-1                       0/2     Pending           0          0s
204mysql-1                       0/2     Pending           0          8s
205mysql-1                       0/2     Init:0/2          0          8s
206mysql-1                       0/2     Init:1/2          0          26s
207mysql-1                       0/2     Init:1/2          0          27s
208mysql-1                       0/2     PodInitializing   0          34s
209mysql-1                       2/2     Running           0          35s
210mysql-2                       0/2     Pending           0          0s
211mysql-2                       0/2     Pending           0          0s
212mysql-1                       1/2     Error             0          37s
213mysql-1                       1/2     Error             1          38s
214mysql-2                       0/2     Pending           0          3s
215mysql-2                       0/2     Init:0/2          0          3s
216mysql-1                       1/2     CrashLoopBackOff   1          53s
217mysql-1                       1/2     Error              2          54s
218mysql-2                       0/2     Init:1/2           0          21s
219mysql-2                       0/2     Init:Error         0          22s
220mysql-2                       0/2     Init:Error         1          23s
221mysql-2                       0/2     Init:CrashLoopBackOff   1          24s
222mysql-1                       1/2     CrashLoopBackOff        2          64s
223mysql-2                       0/2     Init:Error              2          38s
224mysql-1                       1/2     Error                   3          79s
225mysql-2                       0/2     Init:CrashLoopBackOff   2          50s
226mysql-1                       1/2     CrashLoopBackOff        3          92s
227mysql-2                       0/2     Init:Error              3          62s
228mysql-2                       0/2     Init:CrashLoopBackOff   3          74s
229mysql-1                       1/2     Error                   4          2m1s
230mysql-1                       1/2     CrashLoopBackOff        4          2m11s
231mysql-2                       0/2     Init:Error              4          113s
232mysql-2                       0/2     Init:CrashLoopBackOff   4          2m6s
233mysql-1                       1/2     Error                   5          3m29s
234mysql-1                       1/2     CrashLoopBackOff        5          3m41s
235mysql-2                       0/2     Init:Error              5          3m23s
236mysql-2                       0/2     Init:CrashLoopBackOff   5          3m34s
2372021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2382021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2392021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2402021-10-25T03:16:37.231906Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2412021-10-25T03:16:37.234015Z 0 [Note] mysqld (mysqld 5.7.36) starting as process 1 ...
2422021-10-25T03:16:37.237044Z 0 [Note] InnoDB: PUNCH HOLE support available
2432021-10-25T03:16:37.237196Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2442021-10-25T03:16:37.237263Z 0 [Note] InnoDB: Uses event mutexes
2452021-10-25T03:16:37.237345Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2462021-10-25T03:16:37.237416Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2472021-10-25T03:16:37.237489Z 0 [Note] InnoDB: Using Linux native AIO
2482021-10-25T03:16:37.237792Z 0 [Note] InnoDB: Number of pools: 1
2492021-10-25T03:16:37.238102Z 0 [Note] InnoDB: Using CPU crc32 instructions
2502021-10-25T03:16:37.240179Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2512021-10-25T03:16:37.248111Z 0 [Note] InnoDB: Completed initialization of buffer pool
2522021-10-25T03:16:37.251017Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2532021-10-25T03:16:37.263519Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2542021-10-25T03:16:37.307064Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2552021-10-25T03:16:37.307319Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2562021-10-25T03:16:37.307466Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2572021-10-25T03:16:37.353707Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2582021-10-25T03:16:37.354244Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2592021-10-25T03:16:37.354256Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2602021-10-25T03:16:37.355048Z 0 [Note] InnoDB: Waiting for purge to start
2612021-10-25T03:16:37.406335Z 0 [Note] InnoDB: 5.7.36 started; log sequence number 12660776
2622021-10-25T03:16:37.406850Z 0 [Note] Plugin 'FEDERATED' is disabled.
2632021-10-25T03:16:37.413880Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2642021-10-25T03:16:37.426491Z 0 [Note] InnoDB: Buffer pool(s) load completed at 211025  3:16:37
2652021-10-25T03:16:37.427210Z 0 [Note] Salting uuid generator variables, current_pid: 1, server_start_time: 1635131797, bytes_sent: 0, 
2662021-10-25T03:16:37.427438Z 0 [Note] Generated uuid: 'f6f89137-3541-11ec-84bc-f29710c93c86', server_start_time: 281476611842454, bytes_sent: 94355589700272
2672021-10-25T03:16:37.427554Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: f6f89137-3541-11ec-84bc-f29710c93c86.
2682021-10-25T03:16:38.109098Z 0 [Note] Auto generated SSL certificates are placed in data directory.
2692021-10-25T03:16:38.109327Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
2702021-10-25T03:16:38.109395Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
2712021-10-25T03:16:38.109907Z 0 [Warning] CA certificate ca.pem is self signed.
2722021-10-25T03:16:38.354105Z 0 [Note] Auto generated RSA key files are placed in data directory.
2732021-10-25T03:16:38.354795Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2742021-10-25T03:16:38.354968Z 0 [Note] IPv6 is available.
2752021-10-25T03:16:38.355039Z 0 [Note]   - '::' resolves to '::';
2762021-10-25T03:16:38.355125Z 0 [Note] Server socket created on IP: '::'.
2772021-10-25T03:16:38.357907Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2782021-10-25T03:16:38.361720Z 0 [Note] Failed to start slave threads for channel ''
2792021-10-25T03:16:38.366691Z 0 [Note] Event Scheduler: Loaded 0 events
2802021-10-25T03:16:38.367135Z 0 [Note] mysqld: ready for connections.
281Version: '5.7.36'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2822021-10-25T03:16:39.011694Z 3 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2832021-10-25T03:16:39.759020Z 5 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2842021-10-25T03:16:56.006754Z 7 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2852021-10-25T03:17:21.016988Z 9 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2862021-10-25T03:18:03.010443Z 11 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2872021-10-25T03:19:30.984929Z 13 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2882021-10-25T03:22:25.011291Z 15 [Note] Access denied for user 'root'@'localhost' (using password: NO)
289

UPDATE

What I have tried again is stripping down a lot of optional code(I think...), and here is the result:

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195  - name: MYSQL_ROOT_HOST
196    value: "%"
197NAME                          READY   STATUS     RESTARTS   AGE
198mysql-0                       0/2     Init:0/2   0          7s
199mysql-0                       0/2     Init:1/2   0          18s
200mysql-0                       0/2     PodInitializing   0          19s
201mysql-0                       2/2     Running           0          20s
202mysql-1                       0/2     Pending           0          0s
203mysql-1                       0/2     Pending           0          0s
204mysql-1                       0/2     Pending           0          8s
205mysql-1                       0/2     Init:0/2          0          8s
206mysql-1                       0/2     Init:1/2          0          26s
207mysql-1                       0/2     Init:1/2          0          27s
208mysql-1                       0/2     PodInitializing   0          34s
209mysql-1                       2/2     Running           0          35s
210mysql-2                       0/2     Pending           0          0s
211mysql-2                       0/2     Pending           0          0s
212mysql-1                       1/2     Error             0          37s
213mysql-1                       1/2     Error             1          38s
214mysql-2                       0/2     Pending           0          3s
215mysql-2                       0/2     Init:0/2          0          3s
216mysql-1                       1/2     CrashLoopBackOff   1          53s
217mysql-1                       1/2     Error              2          54s
218mysql-2                       0/2     Init:1/2           0          21s
219mysql-2                       0/2     Init:Error         0          22s
220mysql-2                       0/2     Init:Error         1          23s
221mysql-2                       0/2     Init:CrashLoopBackOff   1          24s
222mysql-1                       1/2     CrashLoopBackOff        2          64s
223mysql-2                       0/2     Init:Error              2          38s
224mysql-1                       1/2     Error                   3          79s
225mysql-2                       0/2     Init:CrashLoopBackOff   2          50s
226mysql-1                       1/2     CrashLoopBackOff        3          92s
227mysql-2                       0/2     Init:Error              3          62s
228mysql-2                       0/2     Init:CrashLoopBackOff   3          74s
229mysql-1                       1/2     Error                   4          2m1s
230mysql-1                       1/2     CrashLoopBackOff        4          2m11s
231mysql-2                       0/2     Init:Error              4          113s
232mysql-2                       0/2     Init:CrashLoopBackOff   4          2m6s
233mysql-1                       1/2     Error                   5          3m29s
234mysql-1                       1/2     CrashLoopBackOff        5          3m41s
235mysql-2                       0/2     Init:Error              5          3m23s
236mysql-2                       0/2     Init:CrashLoopBackOff   5          3m34s
2372021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2382021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2392021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2402021-10-25T03:16:37.231906Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2412021-10-25T03:16:37.234015Z 0 [Note] mysqld (mysqld 5.7.36) starting as process 1 ...
2422021-10-25T03:16:37.237044Z 0 [Note] InnoDB: PUNCH HOLE support available
2432021-10-25T03:16:37.237196Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2442021-10-25T03:16:37.237263Z 0 [Note] InnoDB: Uses event mutexes
2452021-10-25T03:16:37.237345Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2462021-10-25T03:16:37.237416Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2472021-10-25T03:16:37.237489Z 0 [Note] InnoDB: Using Linux native AIO
2482021-10-25T03:16:37.237792Z 0 [Note] InnoDB: Number of pools: 1
2492021-10-25T03:16:37.238102Z 0 [Note] InnoDB: Using CPU crc32 instructions
2502021-10-25T03:16:37.240179Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2512021-10-25T03:16:37.248111Z 0 [Note] InnoDB: Completed initialization of buffer pool
2522021-10-25T03:16:37.251017Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2532021-10-25T03:16:37.263519Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2542021-10-25T03:16:37.307064Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2552021-10-25T03:16:37.307319Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2562021-10-25T03:16:37.307466Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2572021-10-25T03:16:37.353707Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2582021-10-25T03:16:37.354244Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2592021-10-25T03:16:37.354256Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2602021-10-25T03:16:37.355048Z 0 [Note] InnoDB: Waiting for purge to start
2612021-10-25T03:16:37.406335Z 0 [Note] InnoDB: 5.7.36 started; log sequence number 12660776
2622021-10-25T03:16:37.406850Z 0 [Note] Plugin 'FEDERATED' is disabled.
2632021-10-25T03:16:37.413880Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2642021-10-25T03:16:37.426491Z 0 [Note] InnoDB: Buffer pool(s) load completed at 211025  3:16:37
2652021-10-25T03:16:37.427210Z 0 [Note] Salting uuid generator variables, current_pid: 1, server_start_time: 1635131797, bytes_sent: 0, 
2662021-10-25T03:16:37.427438Z 0 [Note] Generated uuid: 'f6f89137-3541-11ec-84bc-f29710c93c86', server_start_time: 281476611842454, bytes_sent: 94355589700272
2672021-10-25T03:16:37.427554Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: f6f89137-3541-11ec-84bc-f29710c93c86.
2682021-10-25T03:16:38.109098Z 0 [Note] Auto generated SSL certificates are placed in data directory.
2692021-10-25T03:16:38.109327Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
2702021-10-25T03:16:38.109395Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
2712021-10-25T03:16:38.109907Z 0 [Warning] CA certificate ca.pem is self signed.
2722021-10-25T03:16:38.354105Z 0 [Note] Auto generated RSA key files are placed in data directory.
2732021-10-25T03:16:38.354795Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2742021-10-25T03:16:38.354968Z 0 [Note] IPv6 is available.
2752021-10-25T03:16:38.355039Z 0 [Note]   - '::' resolves to '::';
2762021-10-25T03:16:38.355125Z 0 [Note] Server socket created on IP: '::'.
2772021-10-25T03:16:38.357907Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2782021-10-25T03:16:38.361720Z 0 [Note] Failed to start slave threads for channel ''
2792021-10-25T03:16:38.366691Z 0 [Note] Event Scheduler: Loaded 0 events
2802021-10-25T03:16:38.367135Z 0 [Note] mysqld: ready for connections.
281Version: '5.7.36'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2822021-10-25T03:16:39.011694Z 3 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2832021-10-25T03:16:39.759020Z 5 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2842021-10-25T03:16:56.006754Z 7 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2852021-10-25T03:17:21.016988Z 9 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2862021-10-25T03:18:03.010443Z 11 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2872021-10-25T03:19:30.984929Z 13 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2882021-10-25T03:22:25.011291Z 15 [Note] Access denied for user 'root'@'localhost' (using password: NO)
289apiVersion: apps/v1
290kind: StatefulSet
291metadata:
292  name: mysql
293spec:
294  selector:
295    matchLabels:
296      app: mysql
297  serviceName: mysql
298  replicas: 3
299  template:
300    metadata:
301      labels:
302        app: mysql
303    spec:
304      initContainers:
305      - name: init-mysql
306        image: mysql:5.7
307        env:
308        - name: MYSQL_ROOT_PASSWORD
309          value: admin123
310        command:
311        - bash
312        - "-c"
313        - |
314          set -ex
315          # Generate mysql server-id from pod ordinal index.
316          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
317          ordinal=${BASH_REMATCH[1]}
318          echo [mysqld] > /mnt/conf.d/server-id.cnf
319          # Add an offset to avoid reserved server-id=0 value.
320          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
321          # Copy appropriate conf.d files from config-map to emptyDir.
322          if [[ $ordinal -eq 0 ]]; then
323            cp /mnt/config-map/primary.cnf /mnt/conf.d/
324          else
325            cp /mnt/config-map/replica.cnf /mnt/conf.d/
326          fi          
327        volumeMounts:
328        - name: conf
329          mountPath: /mnt/conf.d
330        - name: config-map
331          mountPath: /mnt/config-map
332      containers:
333      - name: mysql
334        image: mysql:5.7
335        env:
336        - name: MYSQL_ROOT_PASSWORD
337          value: admin123
338        ports:
339        - name: mysql
340          containerPort: 3306
341        volumeMounts:
342        - name: data
343          mountPath: /var/lib/mysql
344          subPath: mysql
345        - name: conf
346          mountPath: /etc/mysql/conf.d
347        resources:
348          requests:
349            cpu: 100m
350            memory: 500Mi
351      volumes:
352      - name: conf
353        emptyDir: {}
354      - name: config-map
355        configMap:
356          name: mysql
357  volumeClaimTemplates:
358  - metadata:
359      name: data
360    spec:
361      accessModes: ["ReadWriteOnce"]
362      resources:
363        requests:
364          storage: 10Gi
365

From the yaml above, the master pod is running without a problem, but for the slave pods, the process is pretty normal until it ran for a while, then they encountered an error. After that, the state went back to running again. I checked the error from the logs and turned out that they could not authenticate mysql using the user root and the root password that I've set, so they tried authenticating mysql using the user root with no password specified and succeeded. That's weird because I've set the env variables MYSQL_ROOT_PASSWORD already inside the initContainers and the containers themselves, so I tried to exec each of the slave pods. I ran echo $MYSQL_ROOT_PASSWORD and the result is the same as I have specified. So the problem now from the yaml above is the env variable that I've set on the yaml file did not penetrate through the mysql application, but only through the container's environmental system.

ANSWER

Answered 2021-Oct-28 at 03:33

I have solved the problem. Turns out I tweaked some of my first uploaded code because there was a syntax error and typos:

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195  - name: MYSQL_ROOT_HOST
196    value: "%"
197NAME                          READY   STATUS     RESTARTS   AGE
198mysql-0                       0/2     Init:0/2   0          7s
199mysql-0                       0/2     Init:1/2   0          18s
200mysql-0                       0/2     PodInitializing   0          19s
201mysql-0                       2/2     Running           0          20s
202mysql-1                       0/2     Pending           0          0s
203mysql-1                       0/2     Pending           0          0s
204mysql-1                       0/2     Pending           0          8s
205mysql-1                       0/2     Init:0/2          0          8s
206mysql-1                       0/2     Init:1/2          0          26s
207mysql-1                       0/2     Init:1/2          0          27s
208mysql-1                       0/2     PodInitializing   0          34s
209mysql-1                       2/2     Running           0          35s
210mysql-2                       0/2     Pending           0          0s
211mysql-2                       0/2     Pending           0          0s
212mysql-1                       1/2     Error             0          37s
213mysql-1                       1/2     Error             1          38s
214mysql-2                       0/2     Pending           0          3s
215mysql-2                       0/2     Init:0/2          0          3s
216mysql-1                       1/2     CrashLoopBackOff   1          53s
217mysql-1                       1/2     Error              2          54s
218mysql-2                       0/2     Init:1/2           0          21s
219mysql-2                       0/2     Init:Error         0          22s
220mysql-2                       0/2     Init:Error         1          23s
221mysql-2                       0/2     Init:CrashLoopBackOff   1          24s
222mysql-1                       1/2     CrashLoopBackOff        2          64s
223mysql-2                       0/2     Init:Error              2          38s
224mysql-1                       1/2     Error                   3          79s
225mysql-2                       0/2     Init:CrashLoopBackOff   2          50s
226mysql-1                       1/2     CrashLoopBackOff        3          92s
227mysql-2                       0/2     Init:Error              3          62s
228mysql-2                       0/2     Init:CrashLoopBackOff   3          74s
229mysql-1                       1/2     Error                   4          2m1s
230mysql-1                       1/2     CrashLoopBackOff        4          2m11s
231mysql-2                       0/2     Init:Error              4          113s
232mysql-2                       0/2     Init:CrashLoopBackOff   4          2m6s
233mysql-1                       1/2     Error                   5          3m29s
234mysql-1                       1/2     CrashLoopBackOff        5          3m41s
235mysql-2                       0/2     Init:Error              5          3m23s
236mysql-2                       0/2     Init:CrashLoopBackOff   5          3m34s
2372021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2382021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2392021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2402021-10-25T03:16:37.231906Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2412021-10-25T03:16:37.234015Z 0 [Note] mysqld (mysqld 5.7.36) starting as process 1 ...
2422021-10-25T03:16:37.237044Z 0 [Note] InnoDB: PUNCH HOLE support available
2432021-10-25T03:16:37.237196Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2442021-10-25T03:16:37.237263Z 0 [Note] InnoDB: Uses event mutexes
2452021-10-25T03:16:37.237345Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2462021-10-25T03:16:37.237416Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2472021-10-25T03:16:37.237489Z 0 [Note] InnoDB: Using Linux native AIO
2482021-10-25T03:16:37.237792Z 0 [Note] InnoDB: Number of pools: 1
2492021-10-25T03:16:37.238102Z 0 [Note] InnoDB: Using CPU crc32 instructions
2502021-10-25T03:16:37.240179Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2512021-10-25T03:16:37.248111Z 0 [Note] InnoDB: Completed initialization of buffer pool
2522021-10-25T03:16:37.251017Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2532021-10-25T03:16:37.263519Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2542021-10-25T03:16:37.307064Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2552021-10-25T03:16:37.307319Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2562021-10-25T03:16:37.307466Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2572021-10-25T03:16:37.353707Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2582021-10-25T03:16:37.354244Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2592021-10-25T03:16:37.354256Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2602021-10-25T03:16:37.355048Z 0 [Note] InnoDB: Waiting for purge to start
2612021-10-25T03:16:37.406335Z 0 [Note] InnoDB: 5.7.36 started; log sequence number 12660776
2622021-10-25T03:16:37.406850Z 0 [Note] Plugin 'FEDERATED' is disabled.
2632021-10-25T03:16:37.413880Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2642021-10-25T03:16:37.426491Z 0 [Note] InnoDB: Buffer pool(s) load completed at 211025  3:16:37
2652021-10-25T03:16:37.427210Z 0 [Note] Salting uuid generator variables, current_pid: 1, server_start_time: 1635131797, bytes_sent: 0, 
2662021-10-25T03:16:37.427438Z 0 [Note] Generated uuid: 'f6f89137-3541-11ec-84bc-f29710c93c86', server_start_time: 281476611842454, bytes_sent: 94355589700272
2672021-10-25T03:16:37.427554Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: f6f89137-3541-11ec-84bc-f29710c93c86.
2682021-10-25T03:16:38.109098Z 0 [Note] Auto generated SSL certificates are placed in data directory.
2692021-10-25T03:16:38.109327Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
2702021-10-25T03:16:38.109395Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
2712021-10-25T03:16:38.109907Z 0 [Warning] CA certificate ca.pem is self signed.
2722021-10-25T03:16:38.354105Z 0 [Note] Auto generated RSA key files are placed in data directory.
2732021-10-25T03:16:38.354795Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2742021-10-25T03:16:38.354968Z 0 [Note] IPv6 is available.
2752021-10-25T03:16:38.355039Z 0 [Note]   - '::' resolves to '::';
2762021-10-25T03:16:38.355125Z 0 [Note] Server socket created on IP: '::'.
2772021-10-25T03:16:38.357907Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2782021-10-25T03:16:38.361720Z 0 [Note] Failed to start slave threads for channel ''
2792021-10-25T03:16:38.366691Z 0 [Note] Event Scheduler: Loaded 0 events
2802021-10-25T03:16:38.367135Z 0 [Note] mysqld: ready for connections.
281Version: '5.7.36'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2822021-10-25T03:16:39.011694Z 3 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2832021-10-25T03:16:39.759020Z 5 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2842021-10-25T03:16:56.006754Z 7 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2852021-10-25T03:17:21.016988Z 9 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2862021-10-25T03:18:03.010443Z 11 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2872021-10-25T03:19:30.984929Z 13 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2882021-10-25T03:22:25.011291Z 15 [Note] Access denied for user 'root'@'localhost' (using password: NO)
289apiVersion: apps/v1
290kind: StatefulSet
291metadata:
292  name: mysql
293spec:
294  selector:
295    matchLabels:
296      app: mysql
297  serviceName: mysql
298  replicas: 3
299  template:
300    metadata:
301      labels:
302        app: mysql
303    spec:
304      initContainers:
305      - name: init-mysql
306        image: mysql:5.7
307        env:
308        - name: MYSQL_ROOT_PASSWORD
309          value: admin123
310        command:
311        - bash
312        - "-c"
313        - |
314          set -ex
315          # Generate mysql server-id from pod ordinal index.
316          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
317          ordinal=${BASH_REMATCH[1]}
318          echo [mysqld] > /mnt/conf.d/server-id.cnf
319          # Add an offset to avoid reserved server-id=0 value.
320          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
321          # Copy appropriate conf.d files from config-map to emptyDir.
322          if [[ $ordinal -eq 0 ]]; then
323            cp /mnt/config-map/primary.cnf /mnt/conf.d/
324          else
325            cp /mnt/config-map/replica.cnf /mnt/conf.d/
326          fi          
327        volumeMounts:
328        - name: conf
329          mountPath: /mnt/conf.d
330        - name: config-map
331          mountPath: /mnt/config-map
332      containers:
333      - name: mysql
334        image: mysql:5.7
335        env:
336        - name: MYSQL_ROOT_PASSWORD
337          value: admin123
338        ports:
339        - name: mysql
340          containerPort: 3306
341        volumeMounts:
342        - name: data
343          mountPath: /var/lib/mysql
344          subPath: mysql
345        - name: conf
346          mountPath: /etc/mysql/conf.d
347        resources:
348          requests:
349            cpu: 100m
350            memory: 500Mi
351      volumes:
352      - name: conf
353        emptyDir: {}
354      - name: config-map
355        configMap:
356          name: mysql
357  volumeClaimTemplates:
358  - metadata:
359      name: data
360    spec:
361      accessModes: ["ReadWriteOnce"]
362      resources:
363        requests:
364          storage: 10Gi
365$MYSQL_ROOT_PASSWORD ==> $(MYSQL_ROOT_PASSWORD) 
366#when calling env var inside command, you have to add the brackets
367
1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195  - name: MYSQL_ROOT_HOST
196    value: "%"
197NAME                          READY   STATUS     RESTARTS   AGE
198mysql-0                       0/2     Init:0/2   0          7s
199mysql-0                       0/2     Init:1/2   0          18s
200mysql-0                       0/2     PodInitializing   0          19s
201mysql-0                       2/2     Running           0          20s
202mysql-1                       0/2     Pending           0          0s
203mysql-1                       0/2     Pending           0          0s
204mysql-1                       0/2     Pending           0          8s
205mysql-1                       0/2     Init:0/2          0          8s
206mysql-1                       0/2     Init:1/2          0          26s
207mysql-1                       0/2     Init:1/2          0          27s
208mysql-1                       0/2     PodInitializing   0          34s
209mysql-1                       2/2     Running           0          35s
210mysql-2                       0/2     Pending           0          0s
211mysql-2                       0/2     Pending           0          0s
212mysql-1                       1/2     Error             0          37s
213mysql-1                       1/2     Error             1          38s
214mysql-2                       0/2     Pending           0          3s
215mysql-2                       0/2     Init:0/2          0          3s
216mysql-1                       1/2     CrashLoopBackOff   1          53s
217mysql-1                       1/2     Error              2          54s
218mysql-2                       0/2     Init:1/2           0          21s
219mysql-2                       0/2     Init:Error         0          22s
220mysql-2                       0/2     Init:Error         1          23s
221mysql-2                       0/2     Init:CrashLoopBackOff   1          24s
222mysql-1                       1/2     CrashLoopBackOff        2          64s
223mysql-2                       0/2     Init:Error              2          38s
224mysql-1                       1/2     Error                   3          79s
225mysql-2                       0/2     Init:CrashLoopBackOff   2          50s
226mysql-1                       1/2     CrashLoopBackOff        3          92s
227mysql-2                       0/2     Init:Error              3          62s
228mysql-2                       0/2     Init:CrashLoopBackOff   3          74s
229mysql-1                       1/2     Error                   4          2m1s
230mysql-1                       1/2     CrashLoopBackOff        4          2m11s
231mysql-2                       0/2     Init:Error              4          113s
232mysql-2                       0/2     Init:CrashLoopBackOff   4          2m6s
233mysql-1                       1/2     Error                   5          3m29s
234mysql-1                       1/2     CrashLoopBackOff        5          3m41s
235mysql-2                       0/2     Init:Error              5          3m23s
236mysql-2                       0/2     Init:CrashLoopBackOff   5          3m34s
2372021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2382021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2392021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2402021-10-25T03:16:37.231906Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2412021-10-25T03:16:37.234015Z 0 [Note] mysqld (mysqld 5.7.36) starting as process 1 ...
2422021-10-25T03:16:37.237044Z 0 [Note] InnoDB: PUNCH HOLE support available
2432021-10-25T03:16:37.237196Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2442021-10-25T03:16:37.237263Z 0 [Note] InnoDB: Uses event mutexes
2452021-10-25T03:16:37.237345Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2462021-10-25T03:16:37.237416Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2472021-10-25T03:16:37.237489Z 0 [Note] InnoDB: Using Linux native AIO
2482021-10-25T03:16:37.237792Z 0 [Note] InnoDB: Number of pools: 1
2492021-10-25T03:16:37.238102Z 0 [Note] InnoDB: Using CPU crc32 instructions
2502021-10-25T03:16:37.240179Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2512021-10-25T03:16:37.248111Z 0 [Note] InnoDB: Completed initialization of buffer pool
2522021-10-25T03:16:37.251017Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2532021-10-25T03:16:37.263519Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2542021-10-25T03:16:37.307064Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2552021-10-25T03:16:37.307319Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2562021-10-25T03:16:37.307466Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2572021-10-25T03:16:37.353707Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2582021-10-25T03:16:37.354244Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2592021-10-25T03:16:37.354256Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2602021-10-25T03:16:37.355048Z 0 [Note] InnoDB: Waiting for purge to start
2612021-10-25T03:16:37.406335Z 0 [Note] InnoDB: 5.7.36 started; log sequence number 12660776
2622021-10-25T03:16:37.406850Z 0 [Note] Plugin 'FEDERATED' is disabled.
2632021-10-25T03:16:37.413880Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2642021-10-25T03:16:37.426491Z 0 [Note] InnoDB: Buffer pool(s) load completed at 211025  3:16:37
2652021-10-25T03:16:37.427210Z 0 [Note] Salting uuid generator variables, current_pid: 1, server_start_time: 1635131797, bytes_sent: 0, 
2662021-10-25T03:16:37.427438Z 0 [Note] Generated uuid: 'f6f89137-3541-11ec-84bc-f29710c93c86', server_start_time: 281476611842454, bytes_sent: 94355589700272
2672021-10-25T03:16:37.427554Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: f6f89137-3541-11ec-84bc-f29710c93c86.
2682021-10-25T03:16:38.109098Z 0 [Note] Auto generated SSL certificates are placed in data directory.
2692021-10-25T03:16:38.109327Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
2702021-10-25T03:16:38.109395Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
2712021-10-25T03:16:38.109907Z 0 [Warning] CA certificate ca.pem is self signed.
2722021-10-25T03:16:38.354105Z 0 [Note] Auto generated RSA key files are placed in data directory.
2732021-10-25T03:16:38.354795Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2742021-10-25T03:16:38.354968Z 0 [Note] IPv6 is available.
2752021-10-25T03:16:38.355039Z 0 [Note]   - '::' resolves to '::';
2762021-10-25T03:16:38.355125Z 0 [Note] Server socket created on IP: '::'.
2772021-10-25T03:16:38.357907Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2782021-10-25T03:16:38.361720Z 0 [Note] Failed to start slave threads for channel ''
2792021-10-25T03:16:38.366691Z 0 [Note] Event Scheduler: Loaded 0 events
2802021-10-25T03:16:38.367135Z 0 [Note] mysqld: ready for connections.
281Version: '5.7.36'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2822021-10-25T03:16:39.011694Z 3 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2832021-10-25T03:16:39.759020Z 5 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2842021-10-25T03:16:56.006754Z 7 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2852021-10-25T03:17:21.016988Z 9 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2862021-10-25T03:18:03.010443Z 11 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2872021-10-25T03:19:30.984929Z 13 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2882021-10-25T03:22:25.011291Z 15 [Note] Access denied for user 'root'@'localhost' (using password: NO)
289apiVersion: apps/v1
290kind: StatefulSet
291metadata:
292  name: mysql
293spec:
294  selector:
295    matchLabels:
296      app: mysql
297  serviceName: mysql
298  replicas: 3
299  template:
300    metadata:
301      labels:
302        app: mysql
303    spec:
304      initContainers:
305      - name: init-mysql
306        image: mysql:5.7
307        env:
308        - name: MYSQL_ROOT_PASSWORD
309          value: admin123
310        command:
311        - bash
312        - "-c"
313        - |
314          set -ex
315          # Generate mysql server-id from pod ordinal index.
316          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
317          ordinal=${BASH_REMATCH[1]}
318          echo [mysqld] > /mnt/conf.d/server-id.cnf
319          # Add an offset to avoid reserved server-id=0 value.
320          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
321          # Copy appropriate conf.d files from config-map to emptyDir.
322          if [[ $ordinal -eq 0 ]]; then
323            cp /mnt/config-map/primary.cnf /mnt/conf.d/
324          else
325            cp /mnt/config-map/replica.cnf /mnt/conf.d/
326          fi          
327        volumeMounts:
328        - name: conf
329          mountPath: /mnt/conf.d
330        - name: config-map
331          mountPath: /mnt/config-map
332      containers:
333      - name: mysql
334        image: mysql:5.7
335        env:
336        - name: MYSQL_ROOT_PASSWORD
337          value: admin123
338        ports:
339        - name: mysql
340          containerPort: 3306
341        volumeMounts:
342        - name: data
343          mountPath: /var/lib/mysql
344          subPath: mysql
345        - name: conf
346          mountPath: /etc/mysql/conf.d
347        resources:
348          requests:
349            cpu: 100m
350            memory: 500Mi
351      volumes:
352      - name: conf
353        emptyDir: {}
354      - name: config-map
355        configMap:
356          name: mysql
357  volumeClaimTemplates:
358  - metadata:
359      name: data
360    spec:
361      accessModes: ["ReadWriteOnce"]
362      resources:
363        requests:
364          storage: 10Gi
365$MYSQL_ROOT_PASSWORD ==> $(MYSQL_ROOT_PASSWORD) 
366#when calling env var inside command, you have to add the brackets
367-uroot -p$MYQSL_ROOT_PASSWORD ==> -u root --password=$(MYSQL_ROOT_PASSWORD)
368
1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195  - name: MYSQL_ROOT_HOST
196    value: "%"
197NAME                          READY   STATUS     RESTARTS   AGE
198mysql-0                       0/2     Init:0/2   0          7s
199mysql-0                       0/2     Init:1/2   0          18s
200mysql-0                       0/2     PodInitializing   0          19s
201mysql-0                       2/2     Running           0          20s
202mysql-1                       0/2     Pending           0          0s
203mysql-1                       0/2     Pending           0          0s
204mysql-1                       0/2     Pending           0          8s
205mysql-1                       0/2     Init:0/2          0          8s
206mysql-1                       0/2     Init:1/2          0          26s
207mysql-1                       0/2     Init:1/2          0          27s
208mysql-1                       0/2     PodInitializing   0          34s
209mysql-1                       2/2     Running           0          35s
210mysql-2                       0/2     Pending           0          0s
211mysql-2                       0/2     Pending           0          0s
212mysql-1                       1/2     Error             0          37s
213mysql-1                       1/2     Error             1          38s
214mysql-2                       0/2     Pending           0          3s
215mysql-2                       0/2     Init:0/2          0          3s
216mysql-1                       1/2     CrashLoopBackOff   1          53s
217mysql-1                       1/2     Error              2          54s
218mysql-2                       0/2     Init:1/2           0          21s
219mysql-2                       0/2     Init:Error         0          22s
220mysql-2                       0/2     Init:Error         1          23s
221mysql-2                       0/2     Init:CrashLoopBackOff   1          24s
222mysql-1                       1/2     CrashLoopBackOff        2          64s
223mysql-2                       0/2     Init:Error              2          38s
224mysql-1                       1/2     Error                   3          79s
225mysql-2                       0/2     Init:CrashLoopBackOff   2          50s
226mysql-1                       1/2     CrashLoopBackOff        3          92s
227mysql-2                       0/2     Init:Error              3          62s
228mysql-2                       0/2     Init:CrashLoopBackOff   3          74s
229mysql-1                       1/2     Error                   4          2m1s
230mysql-1                       1/2     CrashLoopBackOff        4          2m11s
231mysql-2                       0/2     Init:Error              4          113s
232mysql-2                       0/2     Init:CrashLoopBackOff   4          2m6s
233mysql-1                       1/2     Error                   5          3m29s
234mysql-1                       1/2     CrashLoopBackOff        5          3m41s
235mysql-2                       0/2     Init:Error              5          3m23s
236mysql-2                       0/2     Init:CrashLoopBackOff   5          3m34s
2372021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2382021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2392021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2402021-10-25T03:16:37.231906Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2412021-10-25T03:16:37.234015Z 0 [Note] mysqld (mysqld 5.7.36) starting as process 1 ...
2422021-10-25T03:16:37.237044Z 0 [Note] InnoDB: PUNCH HOLE support available
2432021-10-25T03:16:37.237196Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2442021-10-25T03:16:37.237263Z 0 [Note] InnoDB: Uses event mutexes
2452021-10-25T03:16:37.237345Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2462021-10-25T03:16:37.237416Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2472021-10-25T03:16:37.237489Z 0 [Note] InnoDB: Using Linux native AIO
2482021-10-25T03:16:37.237792Z 0 [Note] InnoDB: Number of pools: 1
2492021-10-25T03:16:37.238102Z 0 [Note] InnoDB: Using CPU crc32 instructions
2502021-10-25T03:16:37.240179Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2512021-10-25T03:16:37.248111Z 0 [Note] InnoDB: Completed initialization of buffer pool
2522021-10-25T03:16:37.251017Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2532021-10-25T03:16:37.263519Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2542021-10-25T03:16:37.307064Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2552021-10-25T03:16:37.307319Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2562021-10-25T03:16:37.307466Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2572021-10-25T03:16:37.353707Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2582021-10-25T03:16:37.354244Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2592021-10-25T03:16:37.354256Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2602021-10-25T03:16:37.355048Z 0 [Note] InnoDB: Waiting for purge to start
2612021-10-25T03:16:37.406335Z 0 [Note] InnoDB: 5.7.36 started; log sequence number 12660776
2622021-10-25T03:16:37.406850Z 0 [Note] Plugin 'FEDERATED' is disabled.
2632021-10-25T03:16:37.413880Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2642021-10-25T03:16:37.426491Z 0 [Note] InnoDB: Buffer pool(s) load completed at 211025  3:16:37
2652021-10-25T03:16:37.427210Z 0 [Note] Salting uuid generator variables, current_pid: 1, server_start_time: 1635131797, bytes_sent: 0, 
2662021-10-25T03:16:37.427438Z 0 [Note] Generated uuid: 'f6f89137-3541-11ec-84bc-f29710c93c86', server_start_time: 281476611842454, bytes_sent: 94355589700272
2672021-10-25T03:16:37.427554Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: f6f89137-3541-11ec-84bc-f29710c93c86.
2682021-10-25T03:16:38.109098Z 0 [Note] Auto generated SSL certificates are placed in data directory.
2692021-10-25T03:16:38.109327Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
2702021-10-25T03:16:38.109395Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
2712021-10-25T03:16:38.109907Z 0 [Warning] CA certificate ca.pem is self signed.
2722021-10-25T03:16:38.354105Z 0 [Note] Auto generated RSA key files are placed in data directory.
2732021-10-25T03:16:38.354795Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2742021-10-25T03:16:38.354968Z 0 [Note] IPv6 is available.
2752021-10-25T03:16:38.355039Z 0 [Note]   - '::' resolves to '::';
2762021-10-25T03:16:38.355125Z 0 [Note] Server socket created on IP: '::'.
2772021-10-25T03:16:38.357907Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2782021-10-25T03:16:38.361720Z 0 [Note] Failed to start slave threads for channel ''
2792021-10-25T03:16:38.366691Z 0 [Note] Event Scheduler: Loaded 0 events
2802021-10-25T03:16:38.367135Z 0 [Note] mysqld: ready for connections.
281Version: '5.7.36'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2822021-10-25T03:16:39.011694Z 3 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2832021-10-25T03:16:39.759020Z 5 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2842021-10-25T03:16:56.006754Z 7 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2852021-10-25T03:17:21.016988Z 9 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2862021-10-25T03:18:03.010443Z 11 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2872021-10-25T03:19:30.984929Z 13 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2882021-10-25T03:22:25.011291Z 15 [Note] Access denied for user 'root'@'localhost' (using password: NO)
289apiVersion: apps/v1
290kind: StatefulSet
291metadata:
292  name: mysql
293spec:
294  selector:
295    matchLabels:
296      app: mysql
297  serviceName: mysql
298  replicas: 3
299  template:
300    metadata:
301      labels:
302        app: mysql
303    spec:
304      initContainers:
305      - name: init-mysql
306        image: mysql:5.7
307        env:
308        - name: MYSQL_ROOT_PASSWORD
309          value: admin123
310        command:
311        - bash
312        - "-c"
313        - |
314          set -ex
315          # Generate mysql server-id from pod ordinal index.
316          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
317          ordinal=${BASH_REMATCH[1]}
318          echo [mysqld] > /mnt/conf.d/server-id.cnf
319          # Add an offset to avoid reserved server-id=0 value.
320          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
321          # Copy appropriate conf.d files from config-map to emptyDir.
322          if [[ $ordinal -eq 0 ]]; then
323            cp /mnt/config-map/primary.cnf /mnt/conf.d/
324          else
325            cp /mnt/config-map/replica.cnf /mnt/conf.d/
326          fi          
327        volumeMounts:
328        - name: conf
329          mountPath: /mnt/conf.d
330        - name: config-map
331          mountPath: /mnt/config-map
332      containers:
333      - name: mysql
334        image: mysql:5.7
335        env:
336        - name: MYSQL_ROOT_PASSWORD
337          value: admin123
338        ports:
339        - name: mysql
340          containerPort: 3306
341        volumeMounts:
342        - name: data
343          mountPath: /var/lib/mysql
344          subPath: mysql
345        - name: conf
346          mountPath: /etc/mysql/conf.d
347        resources:
348          requests:
349            cpu: 100m
350            memory: 500Mi
351      volumes:
352      - name: conf
353        emptyDir: {}
354      - name: config-map
355        configMap:
356          name: mysql
357  volumeClaimTemplates:
358  - metadata:
359      name: data
360    spec:
361      accessModes: ["ReadWriteOnce"]
362      resources:
363        requests:
364          storage: 10Gi
365$MYSQL_ROOT_PASSWORD ==> $(MYSQL_ROOT_PASSWORD) 
366#when calling env var inside command, you have to add the brackets
367-uroot -p$MYQSL_ROOT_PASSWORD ==> -u root --password=$(MYSQL_ROOT_PASSWORD)
368START SLAVE USER='root' PASSWORD=$(MYSQL_ROOT_PASSWORD);" || exit 1 ==> START SLAVE;" || exit 1
369

and

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195  - name: MYSQL_ROOT_HOST
196    value: "%"
197NAME                          READY   STATUS     RESTARTS   AGE
198mysql-0                       0/2     Init:0/2   0          7s
199mysql-0                       0/2     Init:1/2   0          18s
200mysql-0                       0/2     PodInitializing   0          19s
201mysql-0                       2/2     Running           0          20s
202mysql-1                       0/2     Pending           0          0s
203mysql-1                       0/2     Pending           0          0s
204mysql-1                       0/2     Pending           0          8s
205mysql-1                       0/2     Init:0/2          0          8s
206mysql-1                       0/2     Init:1/2          0          26s
207mysql-1                       0/2     Init:1/2          0          27s
208mysql-1                       0/2     PodInitializing   0          34s
209mysql-1                       2/2     Running           0          35s
210mysql-2                       0/2     Pending           0          0s
211mysql-2                       0/2     Pending           0          0s
212mysql-1                       1/2     Error             0          37s
213mysql-1                       1/2     Error             1          38s
214mysql-2                       0/2     Pending           0          3s
215mysql-2                       0/2     Init:0/2          0          3s
216mysql-1                       1/2     CrashLoopBackOff   1          53s
217mysql-1                       1/2     Error              2          54s
218mysql-2                       0/2     Init:1/2           0          21s
219mysql-2                       0/2     Init:Error         0          22s
220mysql-2                       0/2     Init:Error         1          23s
221mysql-2                       0/2     Init:CrashLoopBackOff   1          24s
222mysql-1                       1/2     CrashLoopBackOff        2          64s
223mysql-2                       0/2     Init:Error              2          38s
224mysql-1                       1/2     Error                   3          79s
225mysql-2                       0/2     Init:CrashLoopBackOff   2          50s
226mysql-1                       1/2     CrashLoopBackOff        3          92s
227mysql-2                       0/2     Init:Error              3          62s
228mysql-2                       0/2     Init:CrashLoopBackOff   3          74s
229mysql-1                       1/2     Error                   4          2m1s
230mysql-1                       1/2     CrashLoopBackOff        4          2m11s
231mysql-2                       0/2     Init:Error              4          113s
232mysql-2                       0/2     Init:CrashLoopBackOff   4          2m6s
233mysql-1                       1/2     Error                   5          3m29s
234mysql-1                       1/2     CrashLoopBackOff        5          3m41s
235mysql-2                       0/2     Init:Error              5          3m23s
236mysql-2                       0/2     Init:CrashLoopBackOff   5          3m34s
2372021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2382021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2392021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2402021-10-25T03:16:37.231906Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2412021-10-25T03:16:37.234015Z 0 [Note] mysqld (mysqld 5.7.36) starting as process 1 ...
2422021-10-25T03:16:37.237044Z 0 [Note] InnoDB: PUNCH HOLE support available
2432021-10-25T03:16:37.237196Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2442021-10-25T03:16:37.237263Z 0 [Note] InnoDB: Uses event mutexes
2452021-10-25T03:16:37.237345Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2462021-10-25T03:16:37.237416Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2472021-10-25T03:16:37.237489Z 0 [Note] InnoDB: Using Linux native AIO
2482021-10-25T03:16:37.237792Z 0 [Note] InnoDB: Number of pools: 1
2492021-10-25T03:16:37.238102Z 0 [Note] InnoDB: Using CPU crc32 instructions
2502021-10-25T03:16:37.240179Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2512021-10-25T03:16:37.248111Z 0 [Note] InnoDB: Completed initialization of buffer pool
2522021-10-25T03:16:37.251017Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2532021-10-25T03:16:37.263519Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2542021-10-25T03:16:37.307064Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2552021-10-25T03:16:37.307319Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2562021-10-25T03:16:37.307466Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2572021-10-25T03:16:37.353707Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2582021-10-25T03:16:37.354244Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2592021-10-25T03:16:37.354256Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2602021-10-25T03:16:37.355048Z 0 [Note] InnoDB: Waiting for purge to start
2612021-10-25T03:16:37.406335Z 0 [Note] InnoDB: 5.7.36 started; log sequence number 12660776
2622021-10-25T03:16:37.406850Z 0 [Note] Plugin 'FEDERATED' is disabled.
2632021-10-25T03:16:37.413880Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2642021-10-25T03:16:37.426491Z 0 [Note] InnoDB: Buffer pool(s) load completed at 211025  3:16:37
2652021-10-25T03:16:37.427210Z 0 [Note] Salting uuid generator variables, current_pid: 1, server_start_time: 1635131797, bytes_sent: 0, 
2662021-10-25T03:16:37.427438Z 0 [Note] Generated uuid: 'f6f89137-3541-11ec-84bc-f29710c93c86', server_start_time: 281476611842454, bytes_sent: 94355589700272
2672021-10-25T03:16:37.427554Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: f6f89137-3541-11ec-84bc-f29710c93c86.
2682021-10-25T03:16:38.109098Z 0 [Note] Auto generated SSL certificates are placed in data directory.
2692021-10-25T03:16:38.109327Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
2702021-10-25T03:16:38.109395Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
2712021-10-25T03:16:38.109907Z 0 [Warning] CA certificate ca.pem is self signed.
2722021-10-25T03:16:38.354105Z 0 [Note] Auto generated RSA key files are placed in data directory.
2732021-10-25T03:16:38.354795Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2742021-10-25T03:16:38.354968Z 0 [Note] IPv6 is available.
2752021-10-25T03:16:38.355039Z 0 [Note]   - '::' resolves to '::';
2762021-10-25T03:16:38.355125Z 0 [Note] Server socket created on IP: '::'.
2772021-10-25T03:16:38.357907Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2782021-10-25T03:16:38.361720Z 0 [Note] Failed to start slave threads for channel ''
2792021-10-25T03:16:38.366691Z 0 [Note] Event Scheduler: Loaded 0 events
2802021-10-25T03:16:38.367135Z 0 [Note] mysqld: ready for connections.
281Version: '5.7.36'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2822021-10-25T03:16:39.011694Z 3 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2832021-10-25T03:16:39.759020Z 5 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2842021-10-25T03:16:56.006754Z 7 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2852021-10-25T03:17:21.016988Z 9 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2862021-10-25T03:18:03.010443Z 11 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2872021-10-25T03:19:30.984929Z 13 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2882021-10-25T03:22:25.011291Z 15 [Note] Access denied for user 'root'@'localhost' (using password: NO)
289apiVersion: apps/v1
290kind: StatefulSet
291metadata:
292  name: mysql
293spec:
294  selector:
295    matchLabels:
296      app: mysql
297  serviceName: mysql
298  replicas: 3
299  template:
300    metadata:
301      labels:
302        app: mysql
303    spec:
304      initContainers:
305      - name: init-mysql
306        image: mysql:5.7
307        env:
308        - name: MYSQL_ROOT_PASSWORD
309          value: admin123
310        command:
311        - bash
312        - "-c"
313        - |
314          set -ex
315          # Generate mysql server-id from pod ordinal index.
316          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
317          ordinal=${BASH_REMATCH[1]}
318          echo [mysqld] > /mnt/conf.d/server-id.cnf
319          # Add an offset to avoid reserved server-id=0 value.
320          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
321          # Copy appropriate conf.d files from config-map to emptyDir.
322          if [[ $ordinal -eq 0 ]]; then
323            cp /mnt/config-map/primary.cnf /mnt/conf.d/
324          else
325            cp /mnt/config-map/replica.cnf /mnt/conf.d/
326          fi          
327        volumeMounts:
328        - name: conf
329          mountPath: /mnt/conf.d
330        - name: config-map
331          mountPath: /mnt/config-map
332      containers:
333      - name: mysql
334        image: mysql:5.7
335        env:
336        - name: MYSQL_ROOT_PASSWORD
337          value: admin123
338        ports:
339        - name: mysql
340          containerPort: 3306
341        volumeMounts:
342        - name: data
343          mountPath: /var/lib/mysql
344          subPath: mysql
345        - name: conf
346          mountPath: /etc/mysql/conf.d
347        resources:
348          requests:
349            cpu: 100m
350            memory: 500Mi
351      volumes:
352      - name: conf
353        emptyDir: {}
354      - name: config-map
355        configMap:
356          name: mysql
357  volumeClaimTemplates:
358  - metadata:
359      name: data
360    spec:
361      accessModes: ["ReadWriteOnce"]
362      resources:
363        requests:
364          storage: 10Gi
365$MYSQL_ROOT_PASSWORD ==> $(MYSQL_ROOT_PASSWORD) 
366#when calling env var inside command, you have to add the brackets
367-uroot -p$MYQSL_ROOT_PASSWORD ==> -u root --password=$(MYSQL_ROOT_PASSWORD)
368START SLAVE USER='root' PASSWORD=$(MYSQL_ROOT_PASSWORD);" || exit 1 ==> START SLAVE;" || exit 1
369MASTER_PASSWORD=$(MYSQL_ROOT_PASSWORD), \ ==> MASTER_PASSWORD='$(MYSQL_ROOT_PASSWORD)', \
370# have to put ' before and after getting the env value
371

Also, I noticed that the code from mine only works if you removed the livenessProbe and readinessProbe. Somehow, both of them is called before the env var gets loaded, that's why when readinessProbe executes this command:

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195  - name: MYSQL_ROOT_HOST
196    value: "%"
197NAME                          READY   STATUS     RESTARTS   AGE
198mysql-0                       0/2     Init:0/2   0          7s
199mysql-0                       0/2     Init:1/2   0          18s
200mysql-0                       0/2     PodInitializing   0          19s
201mysql-0                       2/2     Running           0          20s
202mysql-1                       0/2     Pending           0          0s
203mysql-1                       0/2     Pending           0          0s
204mysql-1                       0/2     Pending           0          8s
205mysql-1                       0/2     Init:0/2          0          8s
206mysql-1                       0/2     Init:1/2          0          26s
207mysql-1                       0/2     Init:1/2          0          27s
208mysql-1                       0/2     PodInitializing   0          34s
209mysql-1                       2/2     Running           0          35s
210mysql-2                       0/2     Pending           0          0s
211mysql-2                       0/2     Pending           0          0s
212mysql-1                       1/2     Error             0          37s
213mysql-1                       1/2     Error             1          38s
214mysql-2                       0/2     Pending           0          3s
215mysql-2                       0/2     Init:0/2          0          3s
216mysql-1                       1/2     CrashLoopBackOff   1          53s
217mysql-1                       1/2     Error              2          54s
218mysql-2                       0/2     Init:1/2           0          21s
219mysql-2                       0/2     Init:Error         0          22s
220mysql-2                       0/2     Init:Error         1          23s
221mysql-2                       0/2     Init:CrashLoopBackOff   1          24s
222mysql-1                       1/2     CrashLoopBackOff        2          64s
223mysql-2                       0/2     Init:Error              2          38s
224mysql-1                       1/2     Error                   3          79s
225mysql-2                       0/2     Init:CrashLoopBackOff   2          50s
226mysql-1                       1/2     CrashLoopBackOff        3          92s
227mysql-2                       0/2     Init:Error              3          62s
228mysql-2                       0/2     Init:CrashLoopBackOff   3          74s
229mysql-1                       1/2     Error                   4          2m1s
230mysql-1                       1/2     CrashLoopBackOff        4          2m11s
231mysql-2                       0/2     Init:Error              4          113s
232mysql-2                       0/2     Init:CrashLoopBackOff   4          2m6s
233mysql-1                       1/2     Error                   5          3m29s
234mysql-1                       1/2     CrashLoopBackOff        5          3m41s
235mysql-2                       0/2     Init:Error              5          3m23s
236mysql-2                       0/2     Init:CrashLoopBackOff   5          3m34s
2372021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2382021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2392021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2402021-10-25T03:16:37.231906Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2412021-10-25T03:16:37.234015Z 0 [Note] mysqld (mysqld 5.7.36) starting as process 1 ...
2422021-10-25T03:16:37.237044Z 0 [Note] InnoDB: PUNCH HOLE support available
2432021-10-25T03:16:37.237196Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2442021-10-25T03:16:37.237263Z 0 [Note] InnoDB: Uses event mutexes
2452021-10-25T03:16:37.237345Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2462021-10-25T03:16:37.237416Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2472021-10-25T03:16:37.237489Z 0 [Note] InnoDB: Using Linux native AIO
2482021-10-25T03:16:37.237792Z 0 [Note] InnoDB: Number of pools: 1
2492021-10-25T03:16:37.238102Z 0 [Note] InnoDB: Using CPU crc32 instructions
2502021-10-25T03:16:37.240179Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2512021-10-25T03:16:37.248111Z 0 [Note] InnoDB: Completed initialization of buffer pool
2522021-10-25T03:16:37.251017Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2532021-10-25T03:16:37.263519Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2542021-10-25T03:16:37.307064Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2552021-10-25T03:16:37.307319Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2562021-10-25T03:16:37.307466Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2572021-10-25T03:16:37.353707Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2582021-10-25T03:16:37.354244Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2592021-10-25T03:16:37.354256Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2602021-10-25T03:16:37.355048Z 0 [Note] InnoDB: Waiting for purge to start
2612021-10-25T03:16:37.406335Z 0 [Note] InnoDB: 5.7.36 started; log sequence number 12660776
2622021-10-25T03:16:37.406850Z 0 [Note] Plugin 'FEDERATED' is disabled.
2632021-10-25T03:16:37.413880Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2642021-10-25T03:16:37.426491Z 0 [Note] InnoDB: Buffer pool(s) load completed at 211025  3:16:37
2652021-10-25T03:16:37.427210Z 0 [Note] Salting uuid generator variables, current_pid: 1, server_start_time: 1635131797, bytes_sent: 0, 
2662021-10-25T03:16:37.427438Z 0 [Note] Generated uuid: 'f6f89137-3541-11ec-84bc-f29710c93c86', server_start_time: 281476611842454, bytes_sent: 94355589700272
2672021-10-25T03:16:37.427554Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: f6f89137-3541-11ec-84bc-f29710c93c86.
2682021-10-25T03:16:38.109098Z 0 [Note] Auto generated SSL certificates are placed in data directory.
2692021-10-25T03:16:38.109327Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
2702021-10-25T03:16:38.109395Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
2712021-10-25T03:16:38.109907Z 0 [Warning] CA certificate ca.pem is self signed.
2722021-10-25T03:16:38.354105Z 0 [Note] Auto generated RSA key files are placed in data directory.
2732021-10-25T03:16:38.354795Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2742021-10-25T03:16:38.354968Z 0 [Note] IPv6 is available.
2752021-10-25T03:16:38.355039Z 0 [Note]   - '::' resolves to '::';
2762021-10-25T03:16:38.355125Z 0 [Note] Server socket created on IP: '::'.
2772021-10-25T03:16:38.357907Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2782021-10-25T03:16:38.361720Z 0 [Note] Failed to start slave threads for channel ''
2792021-10-25T03:16:38.366691Z 0 [Note] Event Scheduler: Loaded 0 events
2802021-10-25T03:16:38.367135Z 0 [Note] mysqld: ready for connections.
281Version: '5.7.36'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2822021-10-25T03:16:39.011694Z 3 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2832021-10-25T03:16:39.759020Z 5 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2842021-10-25T03:16:56.006754Z 7 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2852021-10-25T03:17:21.016988Z 9 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2862021-10-25T03:18:03.010443Z 11 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2872021-10-25T03:19:30.984929Z 13 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2882021-10-25T03:22:25.011291Z 15 [Note] Access denied for user 'root'@'localhost' (using password: NO)
289apiVersion: apps/v1
290kind: StatefulSet
291metadata:
292  name: mysql
293spec:
294  selector:
295    matchLabels:
296      app: mysql
297  serviceName: mysql
298  replicas: 3
299  template:
300    metadata:
301      labels:
302        app: mysql
303    spec:
304      initContainers:
305      - name: init-mysql
306        image: mysql:5.7
307        env:
308        - name: MYSQL_ROOT_PASSWORD
309          value: admin123
310        command:
311        - bash
312        - "-c"
313        - |
314          set -ex
315          # Generate mysql server-id from pod ordinal index.
316          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
317          ordinal=${BASH_REMATCH[1]}
318          echo [mysqld] > /mnt/conf.d/server-id.cnf
319          # Add an offset to avoid reserved server-id=0 value.
320          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
321          # Copy appropriate conf.d files from config-map to emptyDir.
322          if [[ $ordinal -eq 0 ]]; then
323            cp /mnt/config-map/primary.cnf /mnt/conf.d/
324          else
325            cp /mnt/config-map/replica.cnf /mnt/conf.d/
326          fi          
327        volumeMounts:
328        - name: conf
329          mountPath: /mnt/conf.d
330        - name: config-map
331          mountPath: /mnt/config-map
332      containers:
333      - name: mysql
334        image: mysql:5.7
335        env:
336        - name: MYSQL_ROOT_PASSWORD
337          value: admin123
338        ports:
339        - name: mysql
340          containerPort: 3306
341        volumeMounts:
342        - name: data
343          mountPath: /var/lib/mysql
344          subPath: mysql
345        - name: conf
346          mountPath: /etc/mysql/conf.d
347        resources:
348          requests:
349            cpu: 100m
350            memory: 500Mi
351      volumes:
352      - name: conf
353        emptyDir: {}
354      - name: config-map
355        configMap:
356          name: mysql
357  volumeClaimTemplates:
358  - metadata:
359      name: data
360    spec:
361      accessModes: ["ReadWriteOnce"]
362      resources:
363        requests:
364          storage: 10Gi
365$MYSQL_ROOT_PASSWORD ==> $(MYSQL_ROOT_PASSWORD) 
366#when calling env var inside command, you have to add the brackets
367-uroot -p$MYQSL_ROOT_PASSWORD ==> -u root --password=$(MYSQL_ROOT_PASSWORD)
368START SLAVE USER='root' PASSWORD=$(MYSQL_ROOT_PASSWORD);" || exit 1 ==> START SLAVE;" || exit 1
369MASTER_PASSWORD=$(MYSQL_ROOT_PASSWORD), \ ==> MASTER_PASSWORD='$(MYSQL_ROOT_PASSWORD)', \
370# have to put ' before and after getting the env value
371command: ["mysql", "-h", "127.0.0.1", "-u", "root", "--password=$(MYSQL_ROOT_PASSWORD)", "-e", "SELECT 1"]
372

it failed because $(MYSQL_ROOT_PASSWORD)'s value was not found, therefore, resulting this error:

1apiVersion: apps/v1
2kind: StatefulSet
3metadata:
4  name: mysql
5spec:
6  selector:
7    matchLabels:
8      app: mysql
9  serviceName: mysql
10  replicas: 3
11  template:
12    metadata:
13      labels:
14        app: mysql
15    spec:
16      initContainers:
17      - name: init-mysql
18        image: mysql:5.7
19        env:
20        - name: MYSQL_ROOT_PASSWORD
21          valueFrom:
22            secretKeyRef:
23              name: mysql-secret
24              key: mysql-root-password
25        command:
26        - bash
27        - "-c"
28        - |
29          set -ex
30          # Generate mysql server-id from pod ordinal index.
31          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
32          ordinal=${BASH_REMATCH[1]}
33          echo [mysqld] > /mnt/conf.d/server-id.cnf
34          # Add an offset to avoid reserved server-id=0 value.
35          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
36          # Copy appropriate conf.d files from config-map to emptyDir.
37          if [[ $ordinal -eq 0 ]]; then
38            cp /mnt/config-map/primary.cnf /mnt/conf.d/
39          else
40            cp /mnt/config-map/replica.cnf /mnt/conf.d/
41          fi          
42        volumeMounts:
43        - name: conf
44          mountPath: /mnt/conf.d
45        - name: config-map
46          mountPath: /mnt/config-map
47      - name: clone-mysql
48        image: gcr.io/google-samples/xtrabackup:1.0
49        command:
50        - bash
51        - "-c"
52        - |
53          set -ex
54          # Skip the clone if data already exists.
55          [[ -d /var/lib/mysql/mysql ]] && exit 0
56          # Skip the clone on primary (ordinal index 0).
57          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
58          ordinal=${BASH_REMATCH[1]}
59          [[ $ordinal -eq 0 ]] && exit 0
60          # Clone data from previous peer.
61          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
62          # Prepare the backup.
63          xtrabackup --prepare --target-dir=/var/lib/mysql          
64        volumeMounts:
65        - name: data
66          mountPath: /var/lib/mysql
67          subPath: mysql
68        - name: conf
69          mountPath: /etc/mysql/conf.d
70      containers:
71      - name: mysql
72        image: mysql:5.7
73        env:
74        - name: MYSQL_ROOT_PASSWORD
75          valueFrom:
76            secretKeyRef:
77              name: mysql-secret
78              key: mysql-root-password
79        ports:
80        - name: mysql
81          containerPort: 3306
82        volumeMounts:
83        - name: data
84          mountPath: /var/lib/mysql
85          subPath: mysql
86        - name: conf
87          mountPath: /etc/mysql/conf.d
88        resources:
89          requests:
90            cpu: 100m
91            memory: 500Mi
92      - name: xtrabackup
93        image: gcr.io/google-samples/xtrabackup:1.0
94        env:
95        - name: MYSQL_ROOT_PASSWORD
96          valueFrom:
97            secretKeyRef:
98              name: mysql-secret
99              key: mysql-root-password
100        ports:
101        - name: xtrabackup
102          containerPort: 3307
103        command:
104        - bash
105        - "-c"
106        - |
107          set -ex
108          cd /var/lib/mysql
109
110          # Determine binlog position of cloned data, if any.
111          if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
112            # XtraBackup already generated a partial "CHANGE MASTER TO" query
113            # because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
114            cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
115            # Ignore xtrabackup_binlog_info in this case (it's useless).
116            rm -f xtrabackup_slave_info xtrabackup_binlog_info
117          elif [[ -f xtrabackup_binlog_info ]]; then
118            # We're cloning directly from primary. Parse binlog position.
119            [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
120            rm -f xtrabackup_binlog_info xtrabackup_slave_info
121            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
122                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
123          fi
124
125          # Check if we need to complete a clone by starting replication.
126          if [[ -f change_master_to.sql.in ]]; then
127            echo "Waiting for mysqld to be ready (accepting connections)"
128            until mysql -h 127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT 1"; do sleep 1; done
129
130            echo "Initializing replication from clone position"
131            mysql -h 127.0.0.1 \
132                  -e "$(<change_master_to.sql.in), \
133                          MASTER_HOST='mysql-0.mysql', \
134                          MASTER_USER='root', \
135                          MASTER_PASSWORD=$MYSQL_ROOT_PASSWORD, \
136                          MASTER_CONNECT_RETRY=10; \
137                        START SLAVE USER='root' PASSWORD=$MYSQL_ROOT_PASSWORD;" || exit 1
138            # In case of container restart, attempt this at-most-once.
139            mv change_master_to.sql.in change_master_to.sql.orig
140          fi
141
142          # Start a server to send backups when requested by peers.
143          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
144            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=$MYSQL_ROOT_PASSWORD"          
145        volumeMounts:
146        - name: data
147          mountPath: /var/lib/mysql
148          subPath: mysql
149        - name: conf
150          mountPath: /etc/mysql/conf.d
151        resources:
152          requests:
153            cpu: 50m
154            memory: 50Mi
155      volumes:
156      - name: conf
157        emptyDir: {}
158      - name: config-map
159        configMap:
160          name: mysql
161  volumeClaimTemplates:
162  - metadata:
163      name: data
164    spec:
165      accessModes: ["ReadWriteOnce"]
166      resources:
167        requests:
168          storage: 10Gi
169NAME                              READY   STATUS                  RESTARTS   AGE
170pod/mysql-0                       2/2     Running                 0          11m
171pod/mysql-1                       1/2     Error                   7          11m
172pod/mysql-2                       0/2     Init:CrashLoopBackOff   6          10m
173
174NAME                         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
175service/kubernetes           ClusterIP      10.245.0.1       <none>           443/TCP          2d23h
176service/mysql                ClusterIP      None             <none>           3306/TCP         43h
177service/mysql-read           ClusterIP      10.245.81.173    <none>           3306/TCP         43h
178
179NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
180deployment.apps/phpmyadmin   1/1     1            1           2d18h
181
182NAME                                    DESIRED   CURRENT   READY   AGE
183replicaset.apps/phpmyadmin-6c57fd98bf   1         1         1       2d18h
184
185NAME                     READY   AGE
186statefulset.apps/mysql   1/3     11m
187
188NAME                         TYPE                                  DATA   AGE
189secret/mysql-pass            Opaque                                1      46h
190secret/mysql-secret          Opaque                                3      2d18h
191
192NAME                         DATA   AGE
193configmap/mysql              4      2d18h
194ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
195  - name: MYSQL_ROOT_HOST
196    value: "%"
197NAME                          READY   STATUS     RESTARTS   AGE
198mysql-0                       0/2     Init:0/2   0          7s
199mysql-0                       0/2     Init:1/2   0          18s
200mysql-0                       0/2     PodInitializing   0          19s
201mysql-0                       2/2     Running           0          20s
202mysql-1                       0/2     Pending           0          0s
203mysql-1                       0/2     Pending           0          0s
204mysql-1                       0/2     Pending           0          8s
205mysql-1                       0/2     Init:0/2          0          8s
206mysql-1                       0/2     Init:1/2          0          26s
207mysql-1                       0/2     Init:1/2          0          27s
208mysql-1                       0/2     PodInitializing   0          34s
209mysql-1                       2/2     Running           0          35s
210mysql-2                       0/2     Pending           0          0s
211mysql-2                       0/2     Pending           0          0s
212mysql-1                       1/2     Error             0          37s
213mysql-1                       1/2     Error             1          38s
214mysql-2                       0/2     Pending           0          3s
215mysql-2                       0/2     Init:0/2          0          3s
216mysql-1                       1/2     CrashLoopBackOff   1          53s
217mysql-1                       1/2     Error              2          54s
218mysql-2                       0/2     Init:1/2           0          21s
219mysql-2                       0/2     Init:Error         0          22s
220mysql-2                       0/2     Init:Error         1          23s
221mysql-2                       0/2     Init:CrashLoopBackOff   1          24s
222mysql-1                       1/2     CrashLoopBackOff        2          64s
223mysql-2                       0/2     Init:Error              2          38s
224mysql-1                       1/2     Error                   3          79s
225mysql-2                       0/2     Init:CrashLoopBackOff   2          50s
226mysql-1                       1/2     CrashLoopBackOff        3          92s
227mysql-2                       0/2     Init:Error              3          62s
228mysql-2                       0/2     Init:CrashLoopBackOff   3          74s
229mysql-1                       1/2     Error                   4          2m1s
230mysql-1                       1/2     CrashLoopBackOff        4          2m11s
231mysql-2                       0/2     Init:Error              4          113s
232mysql-2                       0/2     Init:CrashLoopBackOff   4          2m6s
233mysql-1                       1/2     Error                   5          3m29s
234mysql-1                       1/2     CrashLoopBackOff        5          3m41s
235mysql-2                       0/2     Init:Error              5          3m23s
236mysql-2                       0/2     Init:CrashLoopBackOff   5          3m34s
2372021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2382021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2392021-10-25 03:16:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2402021-10-25T03:16:37.231906Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2412021-10-25T03:16:37.234015Z 0 [Note] mysqld (mysqld 5.7.36) starting as process 1 ...
2422021-10-25T03:16:37.237044Z 0 [Note] InnoDB: PUNCH HOLE support available
2432021-10-25T03:16:37.237196Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2442021-10-25T03:16:37.237263Z 0 [Note] InnoDB: Uses event mutexes
2452021-10-25T03:16:37.237345Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2462021-10-25T03:16:37.237416Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2472021-10-25T03:16:37.237489Z 0 [Note] InnoDB: Using Linux native AIO
2482021-10-25T03:16:37.237792Z 0 [Note] InnoDB: Number of pools: 1
2492021-10-25T03:16:37.238102Z 0 [Note] InnoDB: Using CPU crc32 instructions
2502021-10-25T03:16:37.240179Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2512021-10-25T03:16:37.248111Z 0 [Note] InnoDB: Completed initialization of buffer pool
2522021-10-25T03:16:37.251017Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2532021-10-25T03:16:37.263519Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2542021-10-25T03:16:37.307064Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2552021-10-25T03:16:37.307319Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2562021-10-25T03:16:37.307466Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2572021-10-25T03:16:37.353707Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2582021-10-25T03:16:37.354244Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2592021-10-25T03:16:37.354256Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2602021-10-25T03:16:37.355048Z 0 [Note] InnoDB: Waiting for purge to start
2612021-10-25T03:16:37.406335Z 0 [Note] InnoDB: 5.7.36 started; log sequence number 12660776
2622021-10-25T03:16:37.406850Z 0 [Note] Plugin 'FEDERATED' is disabled.
2632021-10-25T03:16:37.413880Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2642021-10-25T03:16:37.426491Z 0 [Note] InnoDB: Buffer pool(s) load completed at 211025  3:16:37
2652021-10-25T03:16:37.427210Z 0 [Note] Salting uuid generator variables, current_pid: 1, server_start_time: 1635131797, bytes_sent: 0, 
2662021-10-25T03:16:37.427438Z 0 [Note] Generated uuid: 'f6f89137-3541-11ec-84bc-f29710c93c86', server_start_time: 281476611842454, bytes_sent: 94355589700272
2672021-10-25T03:16:37.427554Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: f6f89137-3541-11ec-84bc-f29710c93c86.
2682021-10-25T03:16:38.109098Z 0 [Note] Auto generated SSL certificates are placed in data directory.
2692021-10-25T03:16:38.109327Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.
2702021-10-25T03:16:38.109395Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.
2712021-10-25T03:16:38.109907Z 0 [Warning] CA certificate ca.pem is self signed.
2722021-10-25T03:16:38.354105Z 0 [Note] Auto generated RSA key files are placed in data directory.
2732021-10-25T03:16:38.354795Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2742021-10-25T03:16:38.354968Z 0 [Note] IPv6 is available.
2752021-10-25T03:16:38.355039Z 0 [Note]   - '::' resolves to '::';
2762021-10-25T03:16:38.355125Z 0 [Note] Server socket created on IP: '::'.
2772021-10-25T03:16:38.357907Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2782021-10-25T03:16:38.361720Z 0 [Note] Failed to start slave threads for channel ''
2792021-10-25T03:16:38.366691Z 0 [Note] Event Scheduler: Loaded 0 events
2802021-10-25T03:16:38.367135Z 0 [Note] mysqld: ready for connections.
281Version: '5.7.36'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2822021-10-25T03:16:39.011694Z 3 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2832021-10-25T03:16:39.759020Z 5 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2842021-10-25T03:16:56.006754Z 7 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2852021-10-25T03:17:21.016988Z 9 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2862021-10-25T03:18:03.010443Z 11 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2872021-10-25T03:19:30.984929Z 13 [Note] Access denied for user 'root'@'localhost' (using password: NO)
2882021-10-25T03:22:25.011291Z 15 [Note] Access denied for user 'root'@'localhost' (using password: NO)
289apiVersion: apps/v1
290kind: StatefulSet
291metadata:
292  name: mysql
293spec:
294  selector:
295    matchLabels:
296      app: mysql
297  serviceName: mysql
298  replicas: 3
299  template:
300    metadata:
301      labels:
302        app: mysql
303    spec:
304      initContainers:
305      - name: init-mysql
306        image: mysql:5.7
307        env:
308        - name: MYSQL_ROOT_PASSWORD
309          value: admin123
310        command:
311        - bash
312        - "-c"
313        - |
314          set -ex
315          # Generate mysql server-id from pod ordinal index.
316          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
317          ordinal=${BASH_REMATCH[1]}
318          echo [mysqld] > /mnt/conf.d/server-id.cnf
319          # Add an offset to avoid reserved server-id=0 value.
320          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
321          # Copy appropriate conf.d files from config-map to emptyDir.
322          if [[ $ordinal -eq 0 ]]; then
323            cp /mnt/config-map/primary.cnf /mnt/conf.d/
324          else
325            cp /mnt/config-map/replica.cnf /mnt/conf.d/
326          fi          
327        volumeMounts:
328        - name: conf
329          mountPath: /mnt/conf.d
330        - name: config-map
331          mountPath: /mnt/config-map
332      containers:
333      - name: mysql
334        image: mysql:5.7
335        env:
336        - name: MYSQL_ROOT_PASSWORD
337          value: admin123
338        ports:
339        - name: mysql
340          containerPort: 3306
341        volumeMounts:
342        - name: data
343          mountPath: /var/lib/mysql
344          subPath: mysql
345        - name: conf
346          mountPath: /etc/mysql/conf.d
347        resources:
348          requests:
349            cpu: 100m
350            memory: 500Mi
351      volumes:
352      - name: conf
353        emptyDir: {}
354      - name: config-map
355        configMap:
356          name: mysql
357  volumeClaimTemplates:
358  - metadata:
359      name: data
360    spec:
361      accessModes: ["ReadWriteOnce"]
362      resources:
363        requests:
364          storage: 10Gi
365$MYSQL_ROOT_PASSWORD ==> $(MYSQL_ROOT_PASSWORD) 
366#when calling env var inside command, you have to add the brackets
367-uroot -p$MYQSL_ROOT_PASSWORD ==> -u root --password=$(MYSQL_ROOT_PASSWORD)
368START SLAVE USER='root' PASSWORD=$(MYSQL_ROOT_PASSWORD);" || exit 1 ==> START SLAVE;" || exit 1
369MASTER_PASSWORD=$(MYSQL_ROOT_PASSWORD), \ ==> MASTER_PASSWORD='$(MYSQL_ROOT_PASSWORD)', \
370# have to put ' before and after getting the env value
371command: ["mysql", "-h", "127.0.0.1", "-u", "root", "--password=$(MYSQL_ROOT_PASSWORD)", "-e", "SELECT 1"]
3722021-10-25T03:16:39.011694Z 3 [Note] Access denied for user 'root'@'localhost' (using password: NO)
373

If someone has any additional info between livenessProbe, readinessProbe, and env var, please let me know, because my theory might be wrong. CMIIW. :)

Source https://stackoverflow.com/questions/69702207

QUESTION

How to convert a UUID to a number with less than 40 digits?

Asked 2022-Feb-17 at 17:49

I need to convert a UUID (like ffffffff-ffff-ffff-ffff-ffffffffffff) to a number with as least digits as possible. These UUIDs are being generated by com.fasterxml.uuid.impl.TimeBasedGenerator.java.

1package com.fasterxml.uuid.impl;
2
3import java.util.UUID;
4
5import com.fasterxml.uuid.*;
6
7/**
8 * Implementation of UUID generator that uses time/location based generation
9 * method (variant 1).
10 *<p>
11 * As all JUG provided implementations, this generator is fully thread-safe.
12 * Additionally it can also be made externally synchronized with other
13 * instances (even ones running on other JVMs); to do this,
14 * use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}
15 * (or equivalent).
16 *
17 * @since 3.0
18 */
19public class TimeBasedGenerator extends NoArgGenerator
20{
21    /*
22    /**********************************************************************
23    /* Configuration
24    /**********************************************************************
25     */
26
27    protected final EthernetAddress _ethernetAddress;
28
29    /**
30     * Object used for synchronizing access to timestamps, to guarantee
31     * that timestamps produced by this generator are unique and monotonically increasings.
32     * Some implementations offer even stronger guarantees, for example that
33     * same guarantee holds between instances running on different JVMs (or
34     * with native code).
35     */
36    protected final UUIDTimer _timer;
37
38    /**
39     * Base values for the second long (last 8 bytes) of UUID to construct
40     */
41    protected final long _uuidL2;
42    
43    /*
44    /**********************************************************************
45    /* Construction
46    /**********************************************************************
47     */
48
49    /**
50     * @param ethAddr Hardware address (802.1) to use for generating
51     *   spatially unique part of UUID. If system has more than one NIC,
52     */
53    
54    public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer)
55    {
56        byte[] uuidBytes = new byte[16];
57        if (ethAddr == null) {
58            ethAddr = EthernetAddress.constructMulticastAddress();
59        }
60        // initialize baseline with MAC address info
61        _ethernetAddress = ethAddr;
62        _ethernetAddress.toByteArray(uuidBytes, 10);
63        // and add clock sequence
64        int clockSeq = timer.getClockSequence();
65        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq >> 8);
66        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) clockSeq;
67        long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
68        _uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
69        _timer = timer;
70    }
71    
72    /*
73    /**********************************************************************
74    /* Access to config
75    /**********************************************************************
76     */
77
78    @Override
79    public UUIDType getType() { return UUIDType.TIME_BASED; }
80
81    public EthernetAddress getEthernetAddress() { return _ethernetAddress; }
82    
83    /*
84    /**********************************************************************
85    /* UUID generation
86    /**********************************************************************
87     */
88    
89    /* As timer is not synchronized (nor _uuidBytes), need to sync; but most
90     * importantly, synchronize on timer which may also be shared between
91     * multiple instances
92     */
93    @Override
94    public UUID generate()
95    {
96        final long rawTimestamp = _timer.getTimestamp();
97        // Time field components are kind of shuffled, need to slice:
98        int clockHi = (int) (rawTimestamp >>> 32);
99        int clockLo = (int) rawTimestamp;
100        // and dice
101        int midhi = (clockHi << 16) | (clockHi >>> 16);
102        // need to squeeze in type (4 MSBs in byte 6, clock hi)
103        midhi &= ~0xF000; // remove high nibble of 6th byte
104        midhi |= 0x1000; // type 1
105        long midhiL = (long) midhi;
106        midhiL = ((midhiL << 32) >>> 32); // to get rid of sign extension
107        // and reconstruct
108        long l1 = (((long) clockLo) << 32) | midhiL;
109        // last detail: must force 2 MSB to be '10'
110        return new UUID(l1, _uuidL2);
111    }
112}
113

I expect that every day at least 12 million UUIDs will be generated on a particular machine. I assume that TimeBasedGenerator will be instatiated once when the program starts and thus will have a constant network address and a constant random generator seed time (value now in the code snipped below).

1package com.fasterxml.uuid.impl;
2
3import java.util.UUID;
4
5import com.fasterxml.uuid.*;
6
7/**
8 * Implementation of UUID generator that uses time/location based generation
9 * method (variant 1).
10 *<p>
11 * As all JUG provided implementations, this generator is fully thread-safe.
12 * Additionally it can also be made externally synchronized with other
13 * instances (even ones running on other JVMs); to do this,
14 * use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}
15 * (or equivalent).
16 *
17 * @since 3.0
18 */
19public class TimeBasedGenerator extends NoArgGenerator
20{
21    /*
22    /**********************************************************************
23    /* Configuration
24    /**********************************************************************
25     */
26
27    protected final EthernetAddress _ethernetAddress;
28
29    /**
30     * Object used for synchronizing access to timestamps, to guarantee
31     * that timestamps produced by this generator are unique and monotonically increasings.
32     * Some implementations offer even stronger guarantees, for example that
33     * same guarantee holds between instances running on different JVMs (or
34     * with native code).
35     */
36    protected final UUIDTimer _timer;
37
38    /**
39     * Base values for the second long (last 8 bytes) of UUID to construct
40     */
41    protected final long _uuidL2;
42    
43    /*
44    /**********************************************************************
45    /* Construction
46    /**********************************************************************
47     */
48
49    /**
50     * @param ethAddr Hardware address (802.1) to use for generating
51     *   spatially unique part of UUID. If system has more than one NIC,
52     */
53    
54    public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer)
55    {
56        byte[] uuidBytes = new byte[16];
57        if (ethAddr == null) {
58            ethAddr = EthernetAddress.constructMulticastAddress();
59        }
60        // initialize baseline with MAC address info
61        _ethernetAddress = ethAddr;
62        _ethernetAddress.toByteArray(uuidBytes, 10);
63        // and add clock sequence
64        int clockSeq = timer.getClockSequence();
65        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq >> 8);
66        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) clockSeq;
67        long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
68        _uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
69        _timer = timer;
70    }
71    
72    /*
73    /**********************************************************************
74    /* Access to config
75    /**********************************************************************
76     */
77
78    @Override
79    public UUIDType getType() { return UUIDType.TIME_BASED; }
80
81    public EthernetAddress getEthernetAddress() { return _ethernetAddress; }
82    
83    /*
84    /**********************************************************************
85    /* UUID generation
86    /**********************************************************************
87     */
88    
89    /* As timer is not synchronized (nor _uuidBytes), need to sync; but most
90     * importantly, synchronize on timer which may also be shared between
91     * multiple instances
92     */
93    @Override
94    public UUID generate()
95    {
96        final long rawTimestamp = _timer.getTimestamp();
97        // Time field components are kind of shuffled, need to slice:
98        int clockHi = (int) (rawTimestamp >>> 32);
99        int clockLo = (int) rawTimestamp;
100        // and dice
101        int midhi = (clockHi << 16) | (clockHi >>> 16);
102        // need to squeeze in type (4 MSBs in byte 6, clock hi)
103        midhi &= ~0xF000; // remove high nibble of 6th byte
104        midhi |= 0x1000; // type 1
105        long midhiL = (long) midhi;
106        midhiL = ((midhiL << 32) >>> 32); // to get rid of sign extension
107        // and reconstruct
108        long l1 = (((long) clockLo) << 32) | midhiL;
109        // last detail: must force 2 MSB to be '10'
110        return new UUID(l1, _uuidL2);
111    }
112}
113final long now = 1644575806478L;
114
115final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(),
116  new UUIDTimer(new Random(now), null));
117

How can I turn a UUID into a number with

a) less than 40 digits and

b) so that duplicate UUIDs occur once in 6 months the earliest?

Failed attempt 1

The simplest way to convert a UUID to a number looks like this:

1package com.fasterxml.uuid.impl;
2
3import java.util.UUID;
4
5import com.fasterxml.uuid.*;
6
7/**
8 * Implementation of UUID generator that uses time/location based generation
9 * method (variant 1).
10 *<p>
11 * As all JUG provided implementations, this generator is fully thread-safe.
12 * Additionally it can also be made externally synchronized with other
13 * instances (even ones running on other JVMs); to do this,
14 * use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}
15 * (or equivalent).
16 *
17 * @since 3.0
18 */
19public class TimeBasedGenerator extends NoArgGenerator
20{
21    /*
22    /**********************************************************************
23    /* Configuration
24    /**********************************************************************
25     */
26
27    protected final EthernetAddress _ethernetAddress;
28
29    /**
30     * Object used for synchronizing access to timestamps, to guarantee
31     * that timestamps produced by this generator are unique and monotonically increasings.
32     * Some implementations offer even stronger guarantees, for example that
33     * same guarantee holds between instances running on different JVMs (or
34     * with native code).
35     */
36    protected final UUIDTimer _timer;
37
38    /**
39     * Base values for the second long (last 8 bytes) of UUID to construct
40     */
41    protected final long _uuidL2;
42    
43    /*
44    /**********************************************************************
45    /* Construction
46    /**********************************************************************
47     */
48
49    /**
50     * @param ethAddr Hardware address (802.1) to use for generating
51     *   spatially unique part of UUID. If system has more than one NIC,
52     */
53    
54    public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer)
55    {
56        byte[] uuidBytes = new byte[16];
57        if (ethAddr == null) {
58            ethAddr = EthernetAddress.constructMulticastAddress();
59        }
60        // initialize baseline with MAC address info
61        _ethernetAddress = ethAddr;
62        _ethernetAddress.toByteArray(uuidBytes, 10);
63        // and add clock sequence
64        int clockSeq = timer.getClockSequence();
65        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq >> 8);
66        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) clockSeq;
67        long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
68        _uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
69        _timer = timer;
70    }
71    
72    /*
73    /**********************************************************************
74    /* Access to config
75    /**********************************************************************
76     */
77
78    @Override
79    public UUIDType getType() { return UUIDType.TIME_BASED; }
80
81    public EthernetAddress getEthernetAddress() { return _ethernetAddress; }
82    
83    /*
84    /**********************************************************************
85    /* UUID generation
86    /**********************************************************************
87     */
88    
89    /* As timer is not synchronized (nor _uuidBytes), need to sync; but most
90     * importantly, synchronize on timer which may also be shared between
91     * multiple instances
92     */
93    @Override
94    public UUID generate()
95    {
96        final long rawTimestamp = _timer.getTimestamp();
97        // Time field components are kind of shuffled, need to slice:
98        int clockHi = (int) (rawTimestamp >>> 32);
99        int clockLo = (int) rawTimestamp;
100        // and dice
101        int midhi = (clockHi << 16) | (clockHi >>> 16);
102        // need to squeeze in type (4 MSBs in byte 6, clock hi)
103        midhi &= ~0xF000; // remove high nibble of 6th byte
104        midhi |= 0x1000; // type 1
105        long midhiL = (long) midhi;
106        midhiL = ((midhiL << 32) >>> 32); // to get rid of sign extension
107        // and reconstruct
108        long l1 = (((long) clockLo) << 32) | midhiL;
109        // last detail: must force 2 MSB to be '10'
110        return new UUID(l1, _uuidL2);
111    }
112}
113final long now = 1644575806478L;
114
115final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(),
116  new UUIDTimer(new Random(now), null));
117import java.math.BigInteger;
118import java.util.function.Function;
119
120public class OldUUIDConverter implements Function<String, BigInteger> {
121    @Override
122    public BigInteger apply(final String uuid) {
123        final String uuidWithoutDashes = uuid.replaceAll("-", "");
124        return new BigInteger(uuidWithoutDashes, 16);
125    }
126}
127

For the largest possible UUID (ffffffff-ffff-ffff-ffff-ffffffffffff) it producees the number

1package com.fasterxml.uuid.impl;
2
3import java.util.UUID;
4
5import com.fasterxml.uuid.*;
6
7/**
8 * Implementation of UUID generator that uses time/location based generation
9 * method (variant 1).
10 *<p>
11 * As all JUG provided implementations, this generator is fully thread-safe.
12 * Additionally it can also be made externally synchronized with other
13 * instances (even ones running on other JVMs); to do this,
14 * use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}
15 * (or equivalent).
16 *
17 * @since 3.0
18 */
19public class TimeBasedGenerator extends NoArgGenerator
20{
21    /*
22    /**********************************************************************
23    /* Configuration
24    /**********************************************************************
25     */
26
27    protected final EthernetAddress _ethernetAddress;
28
29    /**
30     * Object used for synchronizing access to timestamps, to guarantee
31     * that timestamps produced by this generator are unique and monotonically increasings.
32     * Some implementations offer even stronger guarantees, for example that
33     * same guarantee holds between instances running on different JVMs (or
34     * with native code).
35     */
36    protected final UUIDTimer _timer;
37
38    /**
39     * Base values for the second long (last 8 bytes) of UUID to construct
40     */
41    protected final long _uuidL2;
42    
43    /*
44    /**********************************************************************
45    /* Construction
46    /**********************************************************************
47     */
48
49    /**
50     * @param ethAddr Hardware address (802.1) to use for generating
51     *   spatially unique part of UUID. If system has more than one NIC,
52     */
53    
54    public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer)
55    {
56        byte[] uuidBytes = new byte[16];
57        if (ethAddr == null) {
58            ethAddr = EthernetAddress.constructMulticastAddress();
59        }
60        // initialize baseline with MAC address info
61        _ethernetAddress = ethAddr;
62        _ethernetAddress.toByteArray(uuidBytes, 10);
63        // and add clock sequence
64        int clockSeq = timer.getClockSequence();
65        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq >> 8);
66        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) clockSeq;
67        long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
68        _uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
69        _timer = timer;
70    }
71    
72    /*
73    /**********************************************************************
74    /* Access to config
75    /**********************************************************************
76     */
77
78    @Override
79    public UUIDType getType() { return UUIDType.TIME_BASED; }
80
81    public EthernetAddress getEthernetAddress() { return _ethernetAddress; }
82    
83    /*
84    /**********************************************************************
85    /* UUID generation
86    /**********************************************************************
87     */
88    
89    /* As timer is not synchronized (nor _uuidBytes), need to sync; but most
90     * importantly, synchronize on timer which may also be shared between
91     * multiple instances
92     */
93    @Override
94    public UUID generate()
95    {
96        final long rawTimestamp = _timer.getTimestamp();
97        // Time field components are kind of shuffled, need to slice:
98        int clockHi = (int) (rawTimestamp >>> 32);
99        int clockLo = (int) rawTimestamp;
100        // and dice
101        int midhi = (clockHi << 16) | (clockHi >>> 16);
102        // need to squeeze in type (4 MSBs in byte 6, clock hi)
103        midhi &= ~0xF000; // remove high nibble of 6th byte
104        midhi |= 0x1000; // type 1
105        long midhiL = (long) midhi;
106        midhiL = ((midhiL << 32) >>> 32); // to get rid of sign extension
107        // and reconstruct
108        long l1 = (((long) clockLo) << 32) | midhiL;
109        // last detail: must force 2 MSB to be '10'
110        return new UUID(l1, _uuidL2);
111    }
112}
113final long now = 1644575806478L;
114
115final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(),
116  new UUIDTimer(new Random(now), null));
117import java.math.BigInteger;
118import java.util.function.Function;
119
120public class OldUUIDConverter implements Function<String, BigInteger> {
121    @Override
122    public BigInteger apply(final String uuid) {
123        final String uuidWithoutDashes = uuid.replaceAll("-", "");
124        return new BigInteger(uuidWithoutDashes, 16);
125    }
126}
127340282366920938463463374607431768211455
128^         ^         ^         ^         ^
129

Because we convert the UUID directly, it won't be repeated if the UUID generator does not produce duplicate UUIDs too frequently.

The criterion b) of the above requirement is satisfied. But criterion a) -- the length of the converted number -- is not.

Failed attempt 2

Someone proposed to only take the first 8 digits of the UUID. Thus the criterion a) will be satisfied.

However, the first 8 digits of the UUID repeat too frequently.

I wrote a simple test program:

1package com.fasterxml.uuid.impl;
2
3import java.util.UUID;
4
5import com.fasterxml.uuid.*;
6
7/**
8 * Implementation of UUID generator that uses time/location based generation
9 * method (variant 1).
10 *<p>
11 * As all JUG provided implementations, this generator is fully thread-safe.
12 * Additionally it can also be made externally synchronized with other
13 * instances (even ones running on other JVMs); to do this,
14 * use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}
15 * (or equivalent).
16 *
17 * @since 3.0
18 */
19public class TimeBasedGenerator extends NoArgGenerator
20{
21    /*
22    /**********************************************************************
23    /* Configuration
24    /**********************************************************************
25     */
26
27    protected final EthernetAddress _ethernetAddress;
28
29    /**
30     * Object used for synchronizing access to timestamps, to guarantee
31     * that timestamps produced by this generator are unique and monotonically increasings.
32     * Some implementations offer even stronger guarantees, for example that
33     * same guarantee holds between instances running on different JVMs (or
34     * with native code).
35     */
36    protected final UUIDTimer _timer;
37
38    /**
39     * Base values for the second long (last 8 bytes) of UUID to construct
40     */
41    protected final long _uuidL2;
42    
43    /*
44    /**********************************************************************
45    /* Construction
46    /**********************************************************************
47     */
48
49    /**
50     * @param ethAddr Hardware address (802.1) to use for generating
51     *   spatially unique part of UUID. If system has more than one NIC,
52     */
53    
54    public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer)
55    {
56        byte[] uuidBytes = new byte[16];
57        if (ethAddr == null) {
58            ethAddr = EthernetAddress.constructMulticastAddress();
59        }
60        // initialize baseline with MAC address info
61        _ethernetAddress = ethAddr;
62        _ethernetAddress.toByteArray(uuidBytes, 10);
63        // and add clock sequence
64        int clockSeq = timer.getClockSequence();
65        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq >> 8);
66        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) clockSeq;
67        long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
68        _uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
69        _timer = timer;
70    }
71    
72    /*
73    /**********************************************************************
74    /* Access to config
75    /**********************************************************************
76     */
77
78    @Override
79    public UUIDType getType() { return UUIDType.TIME_BASED; }
80
81    public EthernetAddress getEthernetAddress() { return _ethernetAddress; }
82    
83    /*
84    /**********************************************************************
85    /* UUID generation
86    /**********************************************************************
87     */
88    
89    /* As timer is not synchronized (nor _uuidBytes), need to sync; but most
90     * importantly, synchronize on timer which may also be shared between
91     * multiple instances
92     */
93    @Override
94    public UUID generate()
95    {
96        final long rawTimestamp = _timer.getTimestamp();
97        // Time field components are kind of shuffled, need to slice:
98        int clockHi = (int) (rawTimestamp >>> 32);
99        int clockLo = (int) rawTimestamp;
100        // and dice
101        int midhi = (clockHi << 16) | (clockHi >>> 16);
102        // need to squeeze in type (4 MSBs in byte 6, clock hi)
103        midhi &= ~0xF000; // remove high nibble of 6th byte
104        midhi |= 0x1000; // type 1
105        long midhiL = (long) midhi;
106        midhiL = ((midhiL << 32) >>> 32); // to get rid of sign extension
107        // and reconstruct
108        long l1 = (((long) clockLo) << 32) | midhiL;
109        // last detail: must force 2 MSB to be '10'
110        return new UUID(l1, _uuidL2);
111    }
112}
113final long now = 1644575806478L;
114
115final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(),
116  new UUIDTimer(new Random(now), null));
117import java.math.BigInteger;
118import java.util.function.Function;
119
120public class OldUUIDConverter implements Function<String, BigInteger> {
121    @Override
122    public BigInteger apply(final String uuid) {
123        final String uuidWithoutDashes = uuid.replaceAll("-", "");
124        return new BigInteger(uuidWithoutDashes, 16);
125    }
126}
127340282366920938463463374607431768211455
128^         ^         ^         ^         ^
129import com.fasterxml.uuid.EthernetAddress;
130import com.fasterxml.uuid.UUIDTimer;
131import com.fasterxml.uuid.impl.TimeBasedGenerator;
132import org.junit.Test;
133
134import java.io.IOException;
135import java.util.HashSet;
136import java.util.Random;
137import java.util.Set;
138
139public class UUIDShortenerTest {
140    @Test
141    public void test() throws IOException {
142        final Set<String> first8DigitsAsLong = new HashSet<>(73000000);
143
144        final long now = 1644575806478L;
145
146        final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(), new UUIDTimer(new Random(now), null));
147
148        for (int i=0; i < Integer.MAX_VALUE; i++) {
149            final String curUuid = sut.generate().toString();
150            final String first8Digits = curUuid.substring(0, 8);
151            if ((i % 1000000L) == 0) {
152                System.out.println(String.format("Counter: %d", i));
153            }
154            if (!first8DigitsAsLong.add(first8Digits)) {
155                System.out.println("Duplicate!");
156                System.out.println(i);
157                break;
158            }
159        }
160    }
161}
162

I ran it 10 times. Every time I wrote down the number of UUID generations after which the first 8 digits are repeated.

Here are the results:

  1. Duplicate first 8 digits found after 74499376 UUID generations.
  2. 44259478
  3. 45365652
  4. 45031094
  5. 45445463
  6. 46250299
  7. 45403800
  8. 44658612
  9. 46098250
  10. 43748051

Let's assume that the first 8 digits are repeated after I generate 75 million UUIDs.

If I generate 12 million UUIDs daily, this means that the first UUID with duplicate first 8 digits will be generated after 62-63 days (75000000/1200000=62.5 days).

These 62.5 days (around two months) are lower than the requirement of 6 months before UUID repetition.

Options I am aware of

There is a number of this I can do to fix the issue.

One would be to increase the number of first digits that I use until the frequency of UUID repetitions reaches the desired level. That is, I can try to use 9 first digits instead of 8 and see if it's good enough. If it doesn't, I can use 10 first digits etc.

Another would be to use the code from failed attempt #1 and encode the resulting number 340282366920938463463374607431768211455 in a numerical system with a greater basis.

Let's say I use numbers 0-9, Latin lowercase and uppercase letters, plus 14 special characters. This results in 10+26+26+14=76 numbers that each digit can have. I assume that the above number in a base 76 system will be shorter than the same number in decimal or hexadecimal system.

Are there any other, better options (e. g. hash functions with sufficient degree of diversity)?

ANSWER

Answered 2022-Feb-17 at 17:13
tl;dr
1package com.fasterxml.uuid.impl;
2
3import java.util.UUID;
4
5import com.fasterxml.uuid.*;
6
7/**
8 * Implementation of UUID generator that uses time/location based generation
9 * method (variant 1).
10 *<p>
11 * As all JUG provided implementations, this generator is fully thread-safe.
12 * Additionally it can also be made externally synchronized with other
13 * instances (even ones running on other JVMs); to do this,
14 * use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}
15 * (or equivalent).
16 *
17 * @since 3.0
18 */
19public class TimeBasedGenerator extends NoArgGenerator
20{
21    /*
22    /**********************************************************************
23    /* Configuration
24    /**********************************************************************
25     */
26
27    protected final EthernetAddress _ethernetAddress;
28
29    /**
30     * Object used for synchronizing access to timestamps, to guarantee
31     * that timestamps produced by this generator are unique and monotonically increasings.
32     * Some implementations offer even stronger guarantees, for example that
33     * same guarantee holds between instances running on different JVMs (or
34     * with native code).
35     */
36    protected final UUIDTimer _timer;
37
38    /**
39     * Base values for the second long (last 8 bytes) of UUID to construct
40     */
41    protected final long _uuidL2;
42    
43    /*
44    /**********************************************************************
45    /* Construction
46    /**********************************************************************
47     */
48
49    /**
50     * @param ethAddr Hardware address (802.1) to use for generating
51     *   spatially unique part of UUID. If system has more than one NIC,
52     */
53    
54    public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer)
55    {
56        byte[] uuidBytes = new byte[16];
57        if (ethAddr == null) {
58            ethAddr = EthernetAddress.constructMulticastAddress();
59        }
60        // initialize baseline with MAC address info
61        _ethernetAddress = ethAddr;
62        _ethernetAddress.toByteArray(uuidBytes, 10);
63        // and add clock sequence
64        int clockSeq = timer.getClockSequence();
65        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq >> 8);
66        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) clockSeq;
67        long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
68        _uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
69        _timer = timer;
70    }
71    
72    /*
73    /**********************************************************************
74    /* Access to config
75    /**********************************************************************
76     */
77
78    @Override
79    public UUIDType getType() { return UUIDType.TIME_BASED; }
80
81    public EthernetAddress getEthernetAddress() { return _ethernetAddress; }
82    
83    /*
84    /**********************************************************************
85    /* UUID generation
86    /**********************************************************************
87     */
88    
89    /* As timer is not synchronized (nor _uuidBytes), need to sync; but most
90     * importantly, synchronize on timer which may also be shared between
91     * multiple instances
92     */
93    @Override
94    public UUID generate()
95    {
96        final long rawTimestamp = _timer.getTimestamp();
97        // Time field components are kind of shuffled, need to slice:
98        int clockHi = (int) (rawTimestamp >>> 32);
99        int clockLo = (int) rawTimestamp;
100        // and dice
101        int midhi = (clockHi << 16) | (clockHi >>> 16);
102        // need to squeeze in type (4 MSBs in byte 6, clock hi)
103        midhi &= ~0xF000; // remove high nibble of 6th byte
104        midhi |= 0x1000; // type 1
105        long midhiL = (long) midhi;
106        midhiL = ((midhiL << 32) >>> 32); // to get rid of sign extension
107        // and reconstruct
108        long l1 = (((long) clockLo) << 32) | midhiL;
109        // last detail: must force 2 MSB to be '10'
110        return new UUID(l1, _uuidL2);
111    }
112}
113final long now = 1644575806478L;
114
115final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(),
116  new UUIDTimer(new Random(now), null));
117import java.math.BigInteger;
118import java.util.function.Function;
119
120public class OldUUIDConverter implements Function<String, BigInteger> {
121    @Override
122    public BigInteger apply(final String uuid) {
123        final String uuidWithoutDashes = uuid.replaceAll("-", "");
124        return new BigInteger(uuidWithoutDashes, 16);
125    }
126}
127340282366920938463463374607431768211455
128^         ^         ^         ^         ^
129import com.fasterxml.uuid.EthernetAddress;
130import com.fasterxml.uuid.UUIDTimer;
131import com.fasterxml.uuid.impl.TimeBasedGenerator;
132import org.junit.Test;
133
134import java.io.IOException;
135import java.util.HashSet;
136import java.util.Random;
137import java.util.Set;
138
139public class UUIDShortenerTest {
140    @Test
141    public void test() throws IOException {
142        final Set<String> first8DigitsAsLong = new HashSet<>(73000000);
143
144        final long now = 1644575806478L;
145
146        final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(), new UUIDTimer(new Random(now), null));
147
148        for (int i=0; i < Integer.MAX_VALUE; i++) {
149            final String curUuid = sut.generate().toString();
150            final String first8Digits = curUuid.substring(0, 8);
151            if ((i % 1000000L) == 0) {
152                System.out.println(String.format("Counter: %d", i));
153            }
154            if (!first8DigitsAsLong.add(first8Digits)) {
155                System.out.println("Duplicate!");
156                System.out.println(i);
157                break;
158            }
159        }
160    }
161}
162new BigInteger( 
163    "ffffffff-ffff-ffff-ffff-ffffffffffff" ,
164    16 
165)               // Parse the input as hexadecimal numbers. Returns a `BigInteger` object.
166.toString()     // Generate text containing the digits of a decimal integer representation of this number.
167.codePoints()   // Generate a stream of the Unicode code point number assigned to each of the characters in this string.
168.toArray()      // Collect the streamed code point numbers into an array.
169.length         // Get size of array.
170

39

340282366920938463463374607431768211455 is indeed under 40 digits

Your statement:

But criterion a) -- the length of the converted number -- is not.

… is incorrect.

The resulting integer number has 39 digits. Thirty-nine meets your threshold of being under forty digits: 39 < 40.

Here is code to count the digits.

1package com.fasterxml.uuid.impl;
2
3import java.util.UUID;
4
5import com.fasterxml.uuid.*;
6
7/**
8 * Implementation of UUID generator that uses time/location based generation
9 * method (variant 1).
10 *&lt;p&gt;
11 * As all JUG provided implementations, this generator is fully thread-safe.
12 * Additionally it can also be made externally synchronized with other
13 * instances (even ones running on other JVMs); to do this,
14 * use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}
15 * (or equivalent).
16 *
17 * @since 3.0
18 */
19public class TimeBasedGenerator extends NoArgGenerator
20{
21    /*
22    /**********************************************************************
23    /* Configuration
24    /**********************************************************************
25     */
26
27    protected final EthernetAddress _ethernetAddress;
28
29    /**
30     * Object used for synchronizing access to timestamps, to guarantee
31     * that timestamps produced by this generator are unique and monotonically increasings.
32     * Some implementations offer even stronger guarantees, for example that
33     * same guarantee holds between instances running on different JVMs (or
34     * with native code).
35     */
36    protected final UUIDTimer _timer;
37
38    /**
39     * Base values for the second long (last 8 bytes) of UUID to construct
40     */
41    protected final long _uuidL2;
42    
43    /*
44    /**********************************************************************
45    /* Construction
46    /**********************************************************************
47     */
48
49    /**
50     * @param ethAddr Hardware address (802.1) to use for generating
51     *   spatially unique part of UUID. If system has more than one NIC,
52     */
53    
54    public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer)
55    {
56        byte[] uuidBytes = new byte[16];
57        if (ethAddr == null) {
58            ethAddr = EthernetAddress.constructMulticastAddress();
59        }
60        // initialize baseline with MAC address info
61        _ethernetAddress = ethAddr;
62        _ethernetAddress.toByteArray(uuidBytes, 10);
63        // and add clock sequence
64        int clockSeq = timer.getClockSequence();
65        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq &gt;&gt; 8);
66        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) clockSeq;
67        long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
68        _uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
69        _timer = timer;
70    }
71    
72    /*
73    /**********************************************************************
74    /* Access to config
75    /**********************************************************************
76     */
77
78    @Override
79    public UUIDType getType() { return UUIDType.TIME_BASED; }
80
81    public EthernetAddress getEthernetAddress() { return _ethernetAddress; }
82    
83    /*
84    /**********************************************************************
85    /* UUID generation
86    /**********************************************************************
87     */
88    
89    /* As timer is not synchronized (nor _uuidBytes), need to sync; but most
90     * importantly, synchronize on timer which may also be shared between
91     * multiple instances
92     */
93    @Override
94    public UUID generate()
95    {
96        final long rawTimestamp = _timer.getTimestamp();
97        // Time field components are kind of shuffled, need to slice:
98        int clockHi = (int) (rawTimestamp &gt;&gt;&gt; 32);
99        int clockLo = (int) rawTimestamp;
100        // and dice
101        int midhi = (clockHi &lt;&lt; 16) | (clockHi &gt;&gt;&gt; 16);
102        // need to squeeze in type (4 MSBs in byte 6, clock hi)
103        midhi &amp;= ~0xF000; // remove high nibble of 6th byte
104        midhi |= 0x1000; // type 1
105        long midhiL = (long) midhi;
106        midhiL = ((midhiL &lt;&lt; 32) &gt;&gt;&gt; 32); // to get rid of sign extension
107        // and reconstruct
108        long l1 = (((long) clockLo) &lt;&lt; 32) | midhiL;
109        // last detail: must force 2 MSB to be '10'
110        return new UUID(l1, _uuidL2);
111    }
112}
113final long now = 1644575806478L;
114
115final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(),
116  new UUIDTimer(new Random(now), null));
117import java.math.BigInteger;
118import java.util.function.Function;
119
120public class OldUUIDConverter implements Function&lt;String, BigInteger&gt; {
121    @Override
122    public BigInteger apply(final String uuid) {
123        final String uuidWithoutDashes = uuid.replaceAll(&quot;-&quot;, &quot;&quot;);
124        return new BigInteger(uuidWithoutDashes, 16);
125    }
126}
127340282366920938463463374607431768211455
128^         ^         ^         ^         ^
129import com.fasterxml.uuid.EthernetAddress;
130import com.fasterxml.uuid.UUIDTimer;
131import com.fasterxml.uuid.impl.TimeBasedGenerator;
132import org.junit.Test;
133
134import java.io.IOException;
135import java.util.HashSet;
136import java.util.Random;
137import java.util.Set;
138
139public class UUIDShortenerTest {
140    @Test
141    public void test() throws IOException {
142        final Set&lt;String&gt; first8DigitsAsLong = new HashSet&lt;&gt;(73000000);
143
144        final long now = 1644575806478L;
145
146        final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(), new UUIDTimer(new Random(now), null));
147
148        for (int i=0; i &lt; Integer.MAX_VALUE; i++) {
149            final String curUuid = sut.generate().toString();
150            final String first8Digits = curUuid.substring(0, 8);
151            if ((i % 1000000L) == 0) {
152                System.out.println(String.format(&quot;Counter: %d&quot;, i));
153            }
154            if (!first8DigitsAsLong.add(first8Digits)) {
155                System.out.println(&quot;Duplicate!&quot;);
156                System.out.println(i);
157                break;
158            }
159        }
160    }
161}
162new BigInteger( 
163    &quot;ffffffff-ffff-ffff-ffff-ffffffffffff&quot; ,
164    16 
165)               // Parse the input as hexadecimal numbers. Returns a `BigInteger` object.
166.toString()     // Generate text containing the digits of a decimal integer representation of this number.
167.codePoints()   // Generate a stream of the Unicode code point number assigned to each of the characters in this string.
168.toArray()      // Collect the streamed code point numbers into an array.
169.length         // Get size of array.
170String input = &quot;ffffffff-ffff-ffff-ffff-ffffffffffff&quot; ;
171String uuidWithoutDashes = input.replaceAll( &quot;-&quot; , &quot;&quot; );
172BigInteger bi = new BigInteger( uuidWithoutDashes , 16 );
173String output = bi.toString() ;
174int digitCount = output.codePoints().toArray().length ;
175
176System.out.println( bi ) ;
177System.out.println( digitCount ) ;
178

See this code run live at IdeOne.com.

340282366920938463463374607431768211455

39

Or, manually count the digits. To facilitate that count, I added caret characters to mark 1, 11, 21, 31, 41.

1package com.fasterxml.uuid.impl;
2
3import java.util.UUID;
4
5import com.fasterxml.uuid.*;
6
7/**
8 * Implementation of UUID generator that uses time/location based generation
9 * method (variant 1).
10 *&lt;p&gt;
11 * As all JUG provided implementations, this generator is fully thread-safe.
12 * Additionally it can also be made externally synchronized with other
13 * instances (even ones running on other JVMs); to do this,
14 * use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}
15 * (or equivalent).
16 *
17 * @since 3.0
18 */
19public class TimeBasedGenerator extends NoArgGenerator
20{
21    /*
22    /**********************************************************************
23    /* Configuration
24    /**********************************************************************
25     */
26
27    protected final EthernetAddress _ethernetAddress;
28
29    /**
30     * Object used for synchronizing access to timestamps, to guarantee
31     * that timestamps produced by this generator are unique and monotonically increasings.
32     * Some implementations offer even stronger guarantees, for example that
33     * same guarantee holds between instances running on different JVMs (or
34     * with native code).
35     */
36    protected final UUIDTimer _timer;
37
38    /**
39     * Base values for the second long (last 8 bytes) of UUID to construct
40     */
41    protected final long _uuidL2;
42    
43    /*
44    /**********************************************************************
45    /* Construction
46    /**********************************************************************
47     */
48
49    /**
50     * @param ethAddr Hardware address (802.1) to use for generating
51     *   spatially unique part of UUID. If system has more than one NIC,
52     */
53    
54    public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer)
55    {
56        byte[] uuidBytes = new byte[16];
57        if (ethAddr == null) {
58            ethAddr = EthernetAddress.constructMulticastAddress();
59        }
60        // initialize baseline with MAC address info
61        _ethernetAddress = ethAddr;
62        _ethernetAddress.toByteArray(uuidBytes, 10);
63        // and add clock sequence
64        int clockSeq = timer.getClockSequence();
65        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq &gt;&gt; 8);
66        uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) clockSeq;
67        long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
68        _uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
69        _timer = timer;
70    }
71    
72    /*
73    /**********************************************************************
74    /* Access to config
75    /**********************************************************************
76     */
77
78    @Override
79    public UUIDType getType() { return UUIDType.TIME_BASED; }
80
81    public EthernetAddress getEthernetAddress() { return _ethernetAddress; }
82    
83    /*
84    /**********************************************************************
85    /* UUID generation
86    /**********************************************************************
87     */
88    
89    /* As timer is not synchronized (nor _uuidBytes), need to sync; but most
90     * importantly, synchronize on timer which may also be shared between
91     * multiple instances
92     */
93    @Override
94    public UUID generate()
95    {
96        final long rawTimestamp = _timer.getTimestamp();
97        // Time field components are kind of shuffled, need to slice:
98        int clockHi = (int) (rawTimestamp &gt;&gt;&gt; 32);
99        int clockLo = (int) rawTimestamp;
100        // and dice
101        int midhi = (clockHi &lt;&lt; 16) | (clockHi &gt;&gt;&gt; 16);
102        // need to squeeze in type (4 MSBs in byte 6, clock hi)
103        midhi &amp;= ~0xF000; // remove high nibble of 6th byte
104        midhi |= 0x1000; // type 1
105        long midhiL = (long) midhi;
106        midhiL = ((midhiL &lt;&lt; 32) &gt;&gt;&gt; 32); // to get rid of sign extension
107        // and reconstruct
108        long l1 = (((long) clockLo) &lt;&lt; 32) | midhiL;
109        // last detail: must force 2 MSB to be '10'
110        return new UUID(l1, _uuidL2);
111    }
112}
113final long now = 1644575806478L;
114
115final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(),
116  new UUIDTimer(new Random(now), null));
117import java.math.BigInteger;
118import java.util.function.Function;
119
120public class OldUUIDConverter implements Function&lt;String, BigInteger&gt; {
121    @Override
122    public BigInteger apply(final String uuid) {
123        final String uuidWithoutDashes = uuid.replaceAll(&quot;-&quot;, &quot;&quot;);
124        return new BigInteger(uuidWithoutDashes, 16);
125    }
126}
127340282366920938463463374607431768211455
128^         ^         ^         ^         ^
129import com.fasterxml.uuid.EthernetAddress;
130import com.fasterxml.uuid.UUIDTimer;
131import com.fasterxml.uuid.impl.TimeBasedGenerator;
132import org.junit.Test;
133
134import java.io.IOException;
135import java.util.HashSet;
136import java.util.Random;
137import java.util.Set;
138
139public class UUIDShortenerTest {
140    @Test
141    public void test() throws IOException {
142        final Set&lt;String&gt; first8DigitsAsLong = new HashSet&lt;&gt;(73000000);
143
144        final long now = 1644575806478L;
145
146        final TimeBasedGenerator sut = new TimeBasedGenerator(EthernetAddress.fromInterface(), new UUIDTimer(new Random(now), null));
147
148        for (int i=0; i &lt; Integer.MAX_VALUE; i++) {
149            final String curUuid = sut.generate().toString();
150            final String first8Digits = curUuid.substring(0, 8);
151            if ((i % 1000000L) == 0) {
152                System.out.println(String.format(&quot;Counter: %d&quot;, i));
153            }
154            if (!first8DigitsAsLong.add(first8Digits)) {
155                System.out.println(&quot;Duplicate!&quot;);
156                System.out.println(i);
157                break;
158            }
159        }
160    }
161}
162new BigInteger( 
163    &quot;ffffffff-ffff-ffff-ffff-ffffffffffff&quot; ,
164    16 
165)               // Parse the input as hexadecimal numbers. Returns a `BigInteger` object.
166.toString()     // Generate text containing the digits of a decimal integer representation of this number.
167.codePoints()   // Generate a stream of the Unicode code point number assigned to each of the characters in this string.
168.toArray()      // Collect the streamed code point numbers into an array.
169.length         // Get size of array.
170String input = &quot;ffffffff-ffff-ffff-ffff-ffffffffffff&quot; ;
171String uuidWithoutDashes = input.replaceAll( &quot;-&quot; , &quot;&quot; );
172BigInteger bi = new BigInteger( uuidWithoutDashes , 16 );
173String output = bi.toString() ;
174int digitCount = output.codePoints().toArray().length ;
175
176System.out.println( bi ) ;
177System.out.println( digitCount ) ;
178340282366920938463463374607431768211455
179^         ^         ^         ^         ^
180

As for the bigger picture, I cannot imagine a worthy purpose to storing 39 digits extracted from a decimal representation of a UUID. Study the Comments suggesting you stick with a 128-bit binary representation.

I also wonder why you supply a fixed number as the seed to your Random. Doing so produces identical numbers as outputs.

Source https://stackoverflow.com/questions/71141180

QUESTION

Save Variable from a Pre-request script to use in a new Request

Asked 2021-Oct-26 at 21:13

I'd like to run a Pre-request script in POSTMAN that sends a request to a UUID generator API and saves the UUIDs as variables. Which I can call in the body of the request since they are required there.

Originally, I have two separate requests (1) a request to the UUID Generator API (2) and another to my private API. I'm able to set the 3 UUIDs as variables and call them to the body following request to my private API no problem and it works. Like so:

1GET https://www.uuidgenerator.net/api/version1/3
2    
3pm.collectionVariables.set(&quot;UUID_1&quot;, pm.response.text().split(&quot; &quot;)[1])
4pm.collectionVariables.set(&quot;UUID_2&quot;, pm.response.text().split(&quot; &quot;)[2])
5pm.collectionVariables.set(&quot;UUID_3&quot;, pm.response.text().split(&quot; &quot;)[3])
6
7**Response:**
8
91. f3600940-3684-11ec-8d3d-0242ac130003
102. f3600b70-3684-11ec-8d3d-0242ac130003
113. f3600c6a-3684-11ec-8d3d-0242ac130003
12
13
14**Variables in body of next Request:**
15
16  &quot;data&quot;: {
17        &quot;uuid&quot;: &quot;{{UUID_1}}&quot;,
18        &quot;uuid2&quot;: &quot;{{UUID_2}}&quot;,
19        &quot;uuid3&quot;: &quot;{{UUID_3}}&quot;,
20

Side note: The only way I figured out how to get individualized raw text data from a response is by using .split and the line the data is one, pm.response.text().split(" ")[1])

HOWEVER, I'd like to simplify things and insert the UUID Generator Request in the Pre-Request section so I don't need two separate Requests to make this work. But when inserting the same information that works in the prior request above to set these variables, it doesn't work.

The Pre-request script I have so far gives an error (below):

1GET https://www.uuidgenerator.net/api/version1/3
2    
3pm.collectionVariables.set(&quot;UUID_1&quot;, pm.response.text().split(&quot; &quot;)[1])
4pm.collectionVariables.set(&quot;UUID_2&quot;, pm.response.text().split(&quot; &quot;)[2])
5pm.collectionVariables.set(&quot;UUID_3&quot;, pm.response.text().split(&quot; &quot;)[3])
6
7**Response:**
8
91. f3600940-3684-11ec-8d3d-0242ac130003
102. f3600b70-3684-11ec-8d3d-0242ac130003
113. f3600c6a-3684-11ec-8d3d-0242ac130003
12
13
14**Variables in body of next Request:**
15
16  &quot;data&quot;: {
17        &quot;uuid&quot;: &quot;{{UUID_1}}&quot;,
18        &quot;uuid2&quot;: &quot;{{UUID_2}}&quot;,
19        &quot;uuid3&quot;: &quot;{{UUID_3}}&quot;,
20    pm.sendRequest({
21    url: &quot;https://www.uuidgenerator.net/api/version1/3&quot;,
22    method: 'GET'
23}, function (err, res) {
24pm.collectionVariables.set(&quot;UUID_1&quot;, pm.response.text().split(&quot; &quot;)[1])
25pm.collectionVariables.set(&quot;UUID_2&quot;, pm.response.text().split(&quot; &quot;)[2])
26pm.collectionVariables.set(&quot;UUID_3&quot;, pm.response.text().split(&quot; &quot;)[3])
27});
28
29POSTMAN Error:
30
31    There was an error in evaluating the Pre-request Script:Error: Cannot read property 'text' of undefined
32

Basically whichever different variations I try in collectionVariables.set in the Pre-request script....

1GET https://www.uuidgenerator.net/api/version1/3
2    
3pm.collectionVariables.set(&quot;UUID_1&quot;, pm.response.text().split(&quot; &quot;)[1])
4pm.collectionVariables.set(&quot;UUID_2&quot;, pm.response.text().split(&quot; &quot;)[2])
5pm.collectionVariables.set(&quot;UUID_3&quot;, pm.response.text().split(&quot; &quot;)[3])
6
7**Response:**
8
91. f3600940-3684-11ec-8d3d-0242ac130003
102. f3600b70-3684-11ec-8d3d-0242ac130003
113. f3600c6a-3684-11ec-8d3d-0242ac130003
12
13
14**Variables in body of next Request:**
15
16  &quot;data&quot;: {
17        &quot;uuid&quot;: &quot;{{UUID_1}}&quot;,
18        &quot;uuid2&quot;: &quot;{{UUID_2}}&quot;,
19        &quot;uuid3&quot;: &quot;{{UUID_3}}&quot;,
20    pm.sendRequest({
21    url: &quot;https://www.uuidgenerator.net/api/version1/3&quot;,
22    method: 'GET'
23}, function (err, res) {
24pm.collectionVariables.set(&quot;UUID_1&quot;, pm.response.text().split(&quot; &quot;)[1])
25pm.collectionVariables.set(&quot;UUID_2&quot;, pm.response.text().split(&quot; &quot;)[2])
26pm.collectionVariables.set(&quot;UUID_3&quot;, pm.response.text().split(&quot; &quot;)[3])
27});
28
29POSTMAN Error:
30
31    There was an error in evaluating the Pre-request Script:Error: Cannot read property 'text' of undefined
32pm.collectionVariables.set(&quot;UUID_1&quot;, pm.response.text().split(&quot; &quot;)[1])
33OR
34pm.collectionVariables.set(&quot;UUID_2&quot;, pm.response.split(&quot; &quot;)[2])
35OR
36pm.collectionVariables.set(&quot;UUID_3&quot;, pm.response.[3])
37

I receive errors that otherwise I wouldn't get if it was it's own Request (which works)

This leads me to believe it may be the inner workings of the Pre-Request Script I have.

ANSWER

Answered 2021-Oct-26 at 21:13

You were nearly there. Array starts with [0] and you need to declare the response as res, as placed in the function:

1GET https://www.uuidgenerator.net/api/version1/3
2    
3pm.collectionVariables.set(&quot;UUID_1&quot;, pm.response.text().split(&quot; &quot;)[1])
4pm.collectionVariables.set(&quot;UUID_2&quot;, pm.response.text().split(&quot; &quot;)[2])
5pm.collectionVariables.set(&quot;UUID_3&quot;, pm.response.text().split(&quot; &quot;)[3])
6
7**Response:**
8
91. f3600940-3684-11ec-8d3d-0242ac130003
102. f3600b70-3684-11ec-8d3d-0242ac130003
113. f3600c6a-3684-11ec-8d3d-0242ac130003
12
13
14**Variables in body of next Request:**
15
16  &quot;data&quot;: {
17        &quot;uuid&quot;: &quot;{{UUID_1}}&quot;,
18        &quot;uuid2&quot;: &quot;{{UUID_2}}&quot;,
19        &quot;uuid3&quot;: &quot;{{UUID_3}}&quot;,
20    pm.sendRequest({
21    url: &quot;https://www.uuidgenerator.net/api/version1/3&quot;,
22    method: 'GET'
23}, function (err, res) {
24pm.collectionVariables.set(&quot;UUID_1&quot;, pm.response.text().split(&quot; &quot;)[1])
25pm.collectionVariables.set(&quot;UUID_2&quot;, pm.response.text().split(&quot; &quot;)[2])
26pm.collectionVariables.set(&quot;UUID_3&quot;, pm.response.text().split(&quot; &quot;)[3])
27});
28
29POSTMAN Error:
30
31    There was an error in evaluating the Pre-request Script:Error: Cannot read property 'text' of undefined
32pm.collectionVariables.set(&quot;UUID_1&quot;, pm.response.text().split(&quot; &quot;)[1])
33OR
34pm.collectionVariables.set(&quot;UUID_2&quot;, pm.response.split(&quot; &quot;)[2])
35OR
36pm.collectionVariables.set(&quot;UUID_3&quot;, pm.response.[3])
37pm.sendRequest({
38    url: &quot;https://www.uuidgenerator.net/api/version1/3&quot;,
39    method: 'GET'
40    }, function(err, res){
41pm.collectionVariables.set(&quot;UUID_1&quot;, res.text().split(&quot;\r\n&quot;)[0])
42pm.collectionVariables.set(&quot;UUID_2&quot;, res.text().split(&quot;\r\n&quot;)[1])
43pm.collectionVariables.set(&quot;UUID_3&quot;, res.text().split(&quot;\r\n&quot;)[2])
44});
45console.log(pm.response);
46

Source https://stackoverflow.com/questions/69728155

QUESTION

YAML/YQ - remove sections that have sub-sections containing a particular attribute match

Asked 2021-Oct-07 at 18:16

I'm trying to use mikefarah's yq to remote sections of a yaml file that have a sub-section with a particular attribute match.

More specifically, let's say that we have the following OpenAPI file:

1openapi: 3.0.0
2protocol: https
3tags:
4  - description: Sample API
5    name: Sample Echo API
6info:
7  title: UUID generator based on httpbin.org
8  version: 1.0.3
9paths:
10  /uuid:
11    get:
12      responses:
13        &quot;200&quot;:
14          description: A UUID4.
15      summary: Return a UUID4.
16      tags:
17        - UUID Ops
18  /uuid/{uuid}:
19    delete:
20      parameters:
21        - in: path
22          name: uuid
23          required: true
24          schema:
25            type: string
26      responses:
27        &quot;200&quot;:
28          description: Deleted okay.
29      summary: This endpoint makes no sense.
30      tags:
31        - UUID Ops
32        - Experimental
33  /delay/{delay}:
34    get:
35      parameters:
36        - in: path
37          name: delay
38          required: true
39          schema:
40            type: integer
41      responses:
42        &quot;200&quot;:
43          description: Returns a delayed response
44      summary: Returns a delayed response
45      tags:
46        - Delayed Response  
47        - Experimental
48servers:
49  - url: https://httpbin.org/
50

I want to remove all API endpoints with a tag of "Experimental", so basically the resulting file would be:

1openapi: 3.0.0
2protocol: https
3tags:
4  - description: Sample API
5    name: Sample Echo API
6info:
7  title: UUID generator based on httpbin.org
8  version: 1.0.3
9paths:
10  /uuid:
11    get:
12      responses:
13        &quot;200&quot;:
14          description: A UUID4.
15      summary: Return a UUID4.
16      tags:
17        - UUID Ops
18  /uuid/{uuid}:
19    delete:
20      parameters:
21        - in: path
22          name: uuid
23          required: true
24          schema:
25            type: string
26      responses:
27        &quot;200&quot;:
28          description: Deleted okay.
29      summary: This endpoint makes no sense.
30      tags:
31        - UUID Ops
32        - Experimental
33  /delay/{delay}:
34    get:
35      parameters:
36        - in: path
37          name: delay
38          required: true
39          schema:
40            type: integer
41      responses:
42        &quot;200&quot;:
43          description: Returns a delayed response
44      summary: Returns a delayed response
45      tags:
46        - Delayed Response  
47        - Experimental
48servers:
49  - url: https://httpbin.org/
50openapi: 3.0.0
51protocol: https
52tags:
53  - description: Sample API
54    name: Sample Echo API
55info:
56  title: UUID generator based on httpbin.org
57  version: 1.0.3
58paths:
59  /uuid:
60    get:
61      responses:
62        &quot;200&quot;:
63          description: A UUID4.
64      summary: Return a UUID4.
65      tags:
66        - UUID Ops
67servers:
68  - url: https://httpbin.org/
69

Where I'm struggling is to find the right 'level' for the yq command to work in this way.

As in, I know that I can show all tags in a few different ways:

yq eval '.paths[]?[]?.tags?' openapi.yaml

or

yq eval '.. | select(. == "Experimental")' openapi.yaml

But when I try something like the following to delete the parent section (i.e. the actual API block) based on the tags:

yq eval '.paths | del(.. | select(. == "Experimental"))' openapi.yaml

or

yq eval '.paths |= with_entries(del(select(.. | select(. == "Experimental"))) )' openapi.yaml

All it does it delete the specific Experimental tag, not the actual API block.

Any ideas what I'm doing wrong please?

ANSWER

Answered 2021-Oct-07 at 18:16

With mikefarah/yq, this was a bit tricky, but you can use with_entries and contains methods to achieve your desired result

1openapi: 3.0.0
2protocol: https
3tags:
4  - description: Sample API
5    name: Sample Echo API
6info:
7  title: UUID generator based on httpbin.org
8  version: 1.0.3
9paths:
10  /uuid:
11    get:
12      responses:
13        &quot;200&quot;:
14          description: A UUID4.
15      summary: Return a UUID4.
16      tags:
17        - UUID Ops
18  /uuid/{uuid}:
19    delete:
20      parameters:
21        - in: path
22          name: uuid
23          required: true
24          schema:
25            type: string
26      responses:
27        &quot;200&quot;:
28          description: Deleted okay.
29      summary: This endpoint makes no sense.
30      tags:
31        - UUID Ops
32        - Experimental
33  /delay/{delay}:
34    get:
35      parameters:
36        - in: path
37          name: delay
38          required: true
39          schema:
40            type: integer
41      responses:
42        &quot;200&quot;:
43          description: Returns a delayed response
44      summary: Returns a delayed response
45      tags:
46        - Delayed Response  
47        - Experimental
48servers:
49  - url: https://httpbin.org/
50openapi: 3.0.0
51protocol: https
52tags:
53  - description: Sample API
54    name: Sample Echo API
55info:
56  title: UUID generator based on httpbin.org
57  version: 1.0.3
58paths:
59  /uuid:
60    get:
61      responses:
62        &quot;200&quot;:
63          description: A UUID4.
64      summary: Return a UUID4.
65      tags:
66        - UUID Ops
67servers:
68  - url: https://httpbin.org/
69yq e '
70  .paths |= 
71     with_entries( select( .value[].tags | contains([&quot;Experimental&quot;] ) | not ) )' yaml
72

Using with_entries, each of your map elements are converted to key/value pairs and by using a special notation as .value[], you bypass the top level keys - /uuid, /uuid/{uuid} and get to apply your filter directly on the tags

Using contains, we were able to filter only on the necessary object containing only "Experimental" and negate that condition using not to get your desired result.

Source https://stackoverflow.com/questions/69478916

QUESTION

How can I reference an array when I don't know the name of it?

Asked 2021-Aug-31 at 04:59

In my Cloud Firestore I have a database comprised of several users, and on their structure there's an array called contacts that has several nested arrays. The id (or name, if you will) from every single of one of those arrays is the id from another user. Like so

1&quot;contacts&quot;: [
2   &quot;UserAid&quot;: [
3      &quot;value1&quot;,
4      &quot;value2&quot;,
5      &quot;value3&quot;
6   ],
7   &quot;UserBid&quot;: [
8      &quot;value4&quot;,
9      &quot;value5&quot;
10   ]
11]
12

The thing is, I want to delete value2 from contacts. However, the UserAid is actually a value generated at random by an UUID generator. I know that deleting a value from an array is as simple as:

1&quot;contacts&quot;: [
2   &quot;UserAid&quot;: [
3      &quot;value1&quot;,
4      &quot;value2&quot;,
5      &quot;value3&quot;
6   ],
7   &quot;UserBid&quot;: [
8      &quot;value4&quot;,
9      &quot;value5&quot;
10   ]
11]
12firebase.firestore().collection('Users')
13        .doc(user.id)
14        .update({
15           array: firebase.firestore.FieldValue.arrayRemove(`${valueName}`)
16        })
17

However, because in this case "array" on the update function is a dynamic value (aka the uuid of another user), how can I reference "UserAid" on my function to delete de value?

ANSWER

Answered 2021-Aug-31 at 04:59

You can use [] notation to use the value of a variable as the property name. So:

1&quot;contacts&quot;: [
2   &quot;UserAid&quot;: [
3      &quot;value1&quot;,
4      &quot;value2&quot;,
5      &quot;value3&quot;
6   ],
7   &quot;UserBid&quot;: [
8      &quot;value4&quot;,
9      &quot;value5&quot;
10   ]
11]
12firebase.firestore().collection('Users')
13        .doc(user.id)
14        .update({
15           array: firebase.firestore.FieldValue.arrayRemove(`${valueName}`)
16        })
17const fieldName = &quot;theFieldNameThatYouWantToUpdate&quot;
18firebase.firestore().collection('Users')
19        .doc(user.id)
20        .update({
21           [fieldName]: firebase.firestore.FieldValue.arrayRemove(`${valueName}`)
22        })
23

If you don't have the name of the field to update, you'll have to first load the document to determine that.

Source https://stackoverflow.com/questions/68992388

QUESTION

React Context API context API issues , when adding and removing an items from UI

Asked 2021-Aug-30 at 02:54

I have this working code link, that have some issues with the following.

Adding items

I have multi components called row.. I need to add a single item to each of them, problems is the items is getting added to every one of the rows, instead of the selected one? is the context API the issue or should I use redux, or some other solution for that ? react mind set is really different when it comes to state, any idea how to achieve adding an item to every single row separately?

Removing a single element..

to say the truth I have no access to the id I tried to uses UUID generator, and pass the id down using props, which was a very stupid idea since it regenerate a different id each time, any idea how can I target the id of the parent element,

in the icon component so I can use the filter method on that state and remove the selected item from the items array ??

hiding an icon after click outside of the item …

if you have noticed once you click on an item it shows an icon, what if I decided on not doing any thing and remove the icon ? I tried removing it from the item it self element by using onBlur event but it resulted in the icon (losing the a passed down functionality) so I wont be able to remove the item later on.. currently the icon will disappear but then icon functionality (remove the current element has gone down)

Edit react-context-api-context-api-issues-when-adding-and-removing-an-items-from-ui

1// Context Module
2import React, { useReducer } from 'react'
3import appContext from './appContext'
4import AppReducer from './appReducer'
5import Item from '../../components/Item';
6// the action to chanhe the state !!! 
7import {
8    ICONS, 
9    ITEMS, 
10    ADD_ITEM,
11    REMOVE_ITEM
12    
13}  from '../types'
14// Creating the state  MUST BE A CAPITAL OTHER WISE IT WILL B^&amp;% !! AND REFUSE TO COMPILE
15const AppState = (props) =&gt; {
16const initialState = {
17    Icons : false,
18    Items : [&lt;Item/&gt;],
19}
20
21const [state, dispatch] = useReducer(AppReducer, initialState)
22const Iconsshow = () =&gt; {
23    // show the icon 
24    dispatch({
25        type: ICONS,
26        stabelIcons : true
27    })
28}
29
30const Iconshide = () =&gt; {
31    // show the icon 
32    dispatch({
33        type: ICONS,
34        stabelIcons : false
35    })
36}
37
38const AddItem = ()=&gt; {
39    dispatch({
40    type: ADD_ITEM,
41    Items : [...state.Items, initialState.Items]
42})
43}
44
45const RemoveItem = (e)=&gt; {
46    dispatch({
47    type: REMOVE_ITEM,
48    Items : [[&lt;Item/&gt;]]
49})
50}
51
52return &lt;appContext.Provider
53value={{ 
54    Icons : state.Icons,
55    Items : state.Items,
56    AddItem,
57    RemoveItem
58    }}&gt;
59{props.children}
60&lt;/appContext.Provider&gt;
61}
62
63export default AppState;
64

1// Context Module
2import React, { useReducer } from 'react'
3import appContext from './appContext'
4import AppReducer from './appReducer'
5import Item from '../../components/Item';
6// the action to chanhe the state !!! 
7import {
8    ICONS, 
9    ITEMS, 
10    ADD_ITEM,
11    REMOVE_ITEM
12    
13}  from '../types'
14// Creating the state  MUST BE A CAPITAL OTHER WISE IT WILL B^&amp;% !! AND REFUSE TO COMPILE
15const AppState = (props) =&gt; {
16const initialState = {
17    Icons : false,
18    Items : [&lt;Item/&gt;],
19}
20
21const [state, dispatch] = useReducer(AppReducer, initialState)
22const Iconsshow = () =&gt; {
23    // show the icon 
24    dispatch({
25        type: ICONS,
26        stabelIcons : true
27    })
28}
29
30const Iconshide = () =&gt; {
31    // show the icon 
32    dispatch({
33        type: ICONS,
34        stabelIcons : false
35    })
36}
37
38const AddItem = ()=&gt; {
39    dispatch({
40    type: ADD_ITEM,
41    Items : [...state.Items, initialState.Items]
42})
43}
44
45const RemoveItem = (e)=&gt; {
46    dispatch({
47    type: REMOVE_ITEM,
48    Items : [[&lt;Item/&gt;]]
49})
50}
51
52return &lt;appContext.Provider
53value={{ 
54    Icons : state.Icons,
55    Items : state.Items,
56    AddItem,
57    RemoveItem
58    }}&gt;
59{props.children}
60&lt;/appContext.Provider&gt;
61}
62
63export default AppState;
64// Reducer Module
65
66import {
67    ICONS_SHOW,
68    ICONS_HIDE,
69    ITEMS,
70    ADD_ITEM,
71    REMOVE_ITEM
72} from "../types"
73
74export default (state, action ) =&gt; {
75
76switch(action.type) {
77    case ICONS_SHOW:
78    return {
79        ...state,
80        Icons: true
81    } 
82    case ICONS_HIDE:
83    return {
84        ...state,
85        Icons: false
86    }
87    case ITEMS:
88    return {
89        ...state,
90        Items: action.Items
91    } 
92    case ADD_ITEM:
93        return {
94        ...state,
95        Items: [...state.Items, action.payload]
96     
97    }
98    case REMOVE_ITEM:
99        return {
100        ...state,
101        Items: action.payload
102    }
103default: 
104return state
105}
106}

code box dependencies

1// Context Module
2import React, { useReducer } from 'react'
3import appContext from './appContext'
4import AppReducer from './appReducer'
5import Item from '../../components/Item';
6// the action to chanhe the state !!! 
7import {
8    ICONS, 
9    ITEMS, 
10    ADD_ITEM,
11    REMOVE_ITEM
12    
13}  from '../types'
14// Creating the state  MUST BE A CAPITAL OTHER WISE IT WILL B^&amp;% !! AND REFUSE TO COMPILE
15const AppState = (props) =&gt; {
16const initialState = {
17    Icons : false,
18    Items : [&lt;Item/&gt;],
19}
20
21const [state, dispatch] = useReducer(AppReducer, initialState)
22const Iconsshow = () =&gt; {
23    // show the icon 
24    dispatch({
25        type: ICONS,
26        stabelIcons : true
27    })
28}
29
30const Iconshide = () =&gt; {
31    // show the icon 
32    dispatch({
33        type: ICONS,
34        stabelIcons : false
35    })
36}
37
38const AddItem = ()=&gt; {
39    dispatch({
40    type: ADD_ITEM,
41    Items : [...state.Items, initialState.Items]
42})
43}
44
45const RemoveItem = (e)=&gt; {
46    dispatch({
47    type: REMOVE_ITEM,
48    Items : [[&lt;Item/&gt;]]
49})
50}
51
52return &lt;appContext.Provider
53value={{ 
54    Icons : state.Icons,
55    Items : state.Items,
56    AddItem,
57    RemoveItem
58    }}&gt;
59{props.children}
60&lt;/appContext.Provider&gt;
61}
62
63export default AppState;
64// Reducer Module
65
66import {
67    ICONS_SHOW,
68    ICONS_HIDE,
69    ITEMS,
70    ADD_ITEM,
71    REMOVE_ITEM
72} from "../types"
73
74export default (state, action ) =&gt; {
75
76switch(action.type) {
77    case ICONS_SHOW:
78    return {
79        ...state,
80        Icons: true
81    } 
82    case ICONS_HIDE:
83    return {
84        ...state,
85        Icons: false
86    }
87    case ITEMS:
88    return {
89        ...state,
90        Items: action.Items
91    } 
92    case ADD_ITEM:
93        return {
94        ...state,
95        Items: [...state.Items, action.payload]
96     
97    }
98    case REMOVE_ITEM:
99        return {
100        ...state,
101        Items: action.payload
102    }
103default: 
104return state
105}
106}&quot;dependencies&quot;: {
107      &quot;@fortawesome/fontawesome-svg-core&quot;: &quot;^1.2.36&quot;,
108      &quot;@fortawesome/free-brands-svg-icons&quot;: &quot;^5.15.4&quot;,
109      &quot;@fortawesome/free-regular-svg-icons&quot;: &quot;^5.15.4&quot;,
110      &quot;@fortawesome/free-solid-svg-icons&quot;: &quot;^5.15.4&quot;,
111      &quot;@fortawesome/react-fontawesome&quot;: &quot;^0.1.15&quot;,
112      &quot;@testing-library/jest-dom&quot;: &quot;^5.14.1&quot;,
113      &quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
114      &quot;@testing-library/user-event&quot;: &quot;^12.8.3&quot;,
115      &quot;moment-timezone&quot;: &quot;^0.5.33&quot;,
116      &quot;node-sass&quot;: &quot;^6.0.1&quot;,
117      &quot;react&quot;: &quot;^17.0.2&quot;,
118      &quot;react-dom&quot;: &quot;^17.0.2&quot;,
119      &quot;react-live-clock&quot;: &quot;^5.2.0&quot;,
120      &quot;react-modal&quot;: &quot;^3.14.3&quot;,
121      &quot;react-moment&quot;: &quot;^1.1.1&quot;,
122      &quot;react-scripts&quot;: &quot;4.0.3&quot;,
123      &quot;uuid&quot;: &quot;^8.3.2&quot;,
124      &quot;web-vitals&quot;: &quot;^1.1.2&quot;
125  },
126

ANSWER

Answered 2021-Aug-26 at 06:43

After a day or so tinkering around with your sandbox I decided it had enough going against it that it needed more of a rewrite. The biggest issue was the storing of <Item /> component JSX into the component state. Storing JSX into component state is anti-pattern in React.

Solution

Give each row component an id that can be used to identify it in state. Pass the row id with each dispatched action to add/remove items from that row's data.

Adding items

appContext - Convert the items array to a rows object

1// Context Module
2import React, { useReducer } from 'react'
3import appContext from './appContext'
4import AppReducer from './appReducer'
5import Item from '../../components/Item';
6// the action to chanhe the state !!! 
7import {
8    ICONS, 
9    ITEMS, 
10    ADD_ITEM,
11    REMOVE_ITEM
12    
13}  from '../types'
14// Creating the state  MUST BE A CAPITAL OTHER WISE IT WILL B^&amp;% !! AND REFUSE TO COMPILE
15const AppState = (props) =&gt; {
16const initialState = {
17    Icons : false,
18    Items : [&lt;Item/&gt;],
19}
20
21const [state, dispatch] = useReducer(AppReducer, initialState)
22const Iconsshow = () =&gt; {
23    // show the icon 
24    dispatch({
25        type: ICONS,
26        stabelIcons : true
27    })
28}
29
30const Iconshide = () =&gt; {
31    // show the icon 
32    dispatch({
33        type: ICONS,
34        stabelIcons : false
35    })
36}
37
38const AddItem = ()=&gt; {
39    dispatch({
40    type: ADD_ITEM,
41    Items : [...state.Items, initialState.Items]
42})
43}
44
45const RemoveItem = (e)=&gt; {
46    dispatch({
47    type: REMOVE_ITEM,
48    Items : [[&lt;Item/&gt;]]
49})
50}
51
52return &lt;appContext.Provider
53value={{ 
54    Icons : state.Icons,
55    Items : state.Items,
56    AddItem,
57    RemoveItem
58    }}&gt;
59{props.children}
60&lt;/appContext.Provider&gt;
61}
62
63export default AppState;
64// Reducer Module
65
66import {
67    ICONS_SHOW,
68    ICONS_HIDE,
69    ITEMS,
70    ADD_ITEM,
71    REMOVE_ITEM
72} from "../types"
73
74export default (state, action ) =&gt; {
75
76switch(action.type) {
77    case ICONS_SHOW:
78    return {
79        ...state,
80        Icons: true
81    } 
82    case ICONS_HIDE:
83    return {
84        ...state,
85        Icons: false
86    }
87    case ITEMS:
88    return {
89        ...state,
90        Items: action.Items
91    } 
92    case ADD_ITEM:
93        return {
94        ...state,
95        Items: [...state.Items, action.payload]
96     
97    }
98    case REMOVE_ITEM:
99        return {
100        ...state,
101        Items: action.payload
102    }
103default: 
104return state
105}
106}&quot;dependencies&quot;: {
107      &quot;@fortawesome/fontawesome-svg-core&quot;: &quot;^1.2.36&quot;,
108      &quot;@fortawesome/free-brands-svg-icons&quot;: &quot;^5.15.4&quot;,
109      &quot;@fortawesome/free-regular-svg-icons&quot;: &quot;^5.15.4&quot;,
110      &quot;@fortawesome/free-solid-svg-icons&quot;: &quot;^5.15.4&quot;,
111      &quot;@fortawesome/react-fontawesome&quot;: &quot;^0.1.15&quot;,
112      &quot;@testing-library/jest-dom&quot;: &quot;^5.14.1&quot;,
113      &quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
114      &quot;@testing-library/user-event&quot;: &quot;^12.8.3&quot;,
115      &quot;moment-timezone&quot;: &quot;^0.5.33&quot;,
116      &quot;node-sass&quot;: &quot;^6.0.1&quot;,
117      &quot;react&quot;: &quot;^17.0.2&quot;,
118      &quot;react-dom&quot;: &quot;^17.0.2&quot;,
119      &quot;react-live-clock&quot;: &quot;^5.2.0&quot;,
120      &quot;react-modal&quot;: &quot;^3.14.3&quot;,
121      &quot;react-moment&quot;: &quot;^1.1.1&quot;,
122      &quot;react-scripts&quot;: &quot;4.0.3&quot;,
123      &quot;uuid&quot;: &quot;^8.3.2&quot;,
124      &quot;web-vitals&quot;: &quot;^1.1.2&quot;
125  },
126const CentContext = createContext({
127  Icons: null,
128  rows: {},
129  addItem: () =&gt; {},
130  removeItem: () =&gt; {}
131});
132

appReducer - When adding items store only a new element id. When removing items used the passed element id to filter the row's data.

1// Context Module
2import React, { useReducer } from 'react'
3import appContext from './appContext'
4import AppReducer from './appReducer'
5import Item from '../../components/Item';
6// the action to chanhe the state !!! 
7import {
8    ICONS, 
9    ITEMS, 
10    ADD_ITEM,
11    REMOVE_ITEM
12    
13}  from '../types'
14// Creating the state  MUST BE A CAPITAL OTHER WISE IT WILL B^&amp;% !! AND REFUSE TO COMPILE
15const AppState = (props) =&gt; {
16const initialState = {
17    Icons : false,
18    Items : [&lt;Item/&gt;],
19}
20
21const [state, dispatch] = useReducer(AppReducer, initialState)
22const Iconsshow = () =&gt; {
23    // show the icon 
24    dispatch({
25        type: ICONS,
26        stabelIcons : true
27    })
28}
29
30const Iconshide = () =&gt; {
31    // show the icon 
32    dispatch({
33        type: ICONS,
34        stabelIcons : false
35    })
36}
37
38const AddItem = ()=&gt; {
39    dispatch({
40    type: ADD_ITEM,
41    Items : [...state.Items, initialState.Items]
42})
43}
44
45const RemoveItem = (e)=&gt; {
46    dispatch({
47    type: REMOVE_ITEM,
48    Items : [[&lt;Item/&gt;]]
49})
50}
51
52return &lt;appContext.Provider
53value={{ 
54    Icons : state.Icons,
55    Items : state.Items,
56    AddItem,
57    RemoveItem
58    }}&gt;
59{props.children}
60&lt;/appContext.Provider&gt;
61}
62
63export default AppState;
64// Reducer Module
65
66import {
67    ICONS_SHOW,
68    ICONS_HIDE,
69    ITEMS,
70    ADD_ITEM,
71    REMOVE_ITEM
72} from "../types"
73
74export default (state, action ) =&gt; {
75
76switch(action.type) {
77    case ICONS_SHOW:
78    return {
79        ...state,
80        Icons: true
81    } 
82    case ICONS_HIDE:
83    return {
84        ...state,
85        Icons: false
86    }
87    case ITEMS:
88    return {
89        ...state,
90        Items: action.Items
91    } 
92    case ADD_ITEM:
93        return {
94        ...state,
95        Items: [...state.Items, action.payload]
96     
97    }
98    case REMOVE_ITEM:
99        return {
100        ...state,
101        Items: action.payload
102    }
103default: 
104return state
105}
106}&quot;dependencies&quot;: {
107      &quot;@fortawesome/fontawesome-svg-core&quot;: &quot;^1.2.36&quot;,
108      &quot;@fortawesome/free-brands-svg-icons&quot;: &quot;^5.15.4&quot;,
109      &quot;@fortawesome/free-regular-svg-icons&quot;: &quot;^5.15.4&quot;,
110      &quot;@fortawesome/free-solid-svg-icons&quot;: &quot;^5.15.4&quot;,
111      &quot;@fortawesome/react-fontawesome&quot;: &quot;^0.1.15&quot;,
112      &quot;@testing-library/jest-dom&quot;: &quot;^5.14.1&quot;,
113      &quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
114      &quot;@testing-library/user-event&quot;: &quot;^12.8.3&quot;,
115      &quot;moment-timezone&quot;: &quot;^0.5.33&quot;,
116      &quot;node-sass&quot;: &quot;^6.0.1&quot;,
117      &quot;react&quot;: &quot;^17.0.2&quot;,
118      &quot;react-dom&quot;: &quot;^17.0.2&quot;,
119      &quot;react-live-clock&quot;: &quot;^5.2.0&quot;,
120      &quot;react-modal&quot;: &quot;^3.14.3&quot;,
121      &quot;react-moment&quot;: &quot;^1.1.1&quot;,
122      &quot;react-scripts&quot;: &quot;4.0.3&quot;,
123      &quot;uuid&quot;: &quot;^8.3.2&quot;,
124      &quot;web-vitals&quot;: &quot;^1.1.2&quot;
125  },
126const CentContext = createContext({
127  Icons: null,
128  rows: {},
129  addItem: () =&gt; {},
130  removeItem: () =&gt; {}
131});
132import { v4 as uuidV4 } from &quot;uuid&quot;;
133
134...
135
136export default (state, action) =&gt; {
137  switch (action.type) {
138    ...
139
140    case ADD_ITEM:
141      console.log(&quot;add item&quot;);
142      return {
143        ...state,
144        rows: {
145          ...state.rows,
146          [action.rowId]: [
147            ...(state.rows[action.rowId] ?? []),
148            { id: uuidV4() }
149          ]
150        }
151      };
152
153    case REMOVE_ITEM:
154      return {
155        ...state,
156        rows: {
157          ...state.rows,
158          [action.rowId]: state.rows[action.rowId]?.filter(
159            (el) =&gt; el.id !== action.elementId
160          )
161        }
162      };
163      
164    default:
165      return state;
166  }
167};
168

appState - Swap the items state for a rows object state. Update the add/remove item action creators to consume the appropriate row and element ids. Pass the rows state to the context provider.

1// Context Module
2import React, { useReducer } from 'react'
3import appContext from './appContext'
4import AppReducer from './appReducer'
5import Item from '../../components/Item';
6// the action to chanhe the state !!! 
7import {
8    ICONS, 
9    ITEMS, 
10    ADD_ITEM,
11    REMOVE_ITEM
12    
13}  from '../types'
14// Creating the state  MUST BE A CAPITAL OTHER WISE IT WILL B^&amp;% !! AND REFUSE TO COMPILE
15const AppState = (props) =&gt; {
16const initialState = {
17    Icons : false,
18    Items : [&lt;Item/&gt;],
19}
20
21const [state, dispatch] = useReducer(AppReducer, initialState)
22const Iconsshow = () =&gt; {
23    // show the icon 
24    dispatch({
25        type: ICONS,
26        stabelIcons : true
27    })
28}
29
30const Iconshide = () =&gt; {
31    // show the icon 
32    dispatch({
33        type: ICONS,
34        stabelIcons : false
35    })
36}
37
38const AddItem = ()=&gt; {
39    dispatch({
40    type: ADD_ITEM,
41    Items : [...state.Items, initialState.Items]
42})
43}
44
45const RemoveItem = (e)=&gt; {
46    dispatch({
47    type: REMOVE_ITEM,
48    Items : [[&lt;Item/&gt;]]
49})
50}
51
52return &lt;appContext.Provider
53value={{ 
54    Icons : state.Icons,
55    Items : state.Items,
56    AddItem,
57    RemoveItem
58    }}&gt;
59{props.children}
60&lt;/appContext.Provider&gt;
61}
62
63export default AppState;
64// Reducer Module
65
66import {
67    ICONS_SHOW,
68    ICONS_HIDE,
69    ITEMS,
70    ADD_ITEM,
71    REMOVE_ITEM
72} from "../types"
73
74export default (state, action ) =&gt; {
75
76switch(action.type) {
77    case ICONS_SHOW:
78    return {
79        ...state,
80        Icons: true
81    } 
82    case ICONS_HIDE:
83    return {
84        ...state,
85        Icons: false
86    }
87    case ITEMS:
88    return {
89        ...state,
90        Items: action.Items
91    } 
92    case ADD_ITEM:
93        return {
94        ...state,
95        Items: [...state.Items, action.payload]
96     
97    }
98    case REMOVE_ITEM:
99        return {
100        ...state,
101        Items: action.payload
102    }
103default: 
104return state
105}
106}&quot;dependencies&quot;: {
107      &quot;@fortawesome/fontawesome-svg-core&quot;: &quot;^1.2.36&quot;,
108      &quot;@fortawesome/free-brands-svg-icons&quot;: &quot;^5.15.4&quot;,
109      &quot;@fortawesome/free-regular-svg-icons&quot;: &quot;^5.15.4&quot;,
110      &quot;@fortawesome/free-solid-svg-icons&quot;: &quot;^5.15.4&quot;,
111      &quot;@fortawesome/react-fontawesome&quot;: &quot;^0.1.15&quot;,
112      &quot;@testing-library/jest-dom&quot;: &quot;^5.14.1&quot;,
113      &quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
114      &quot;@testing-library/user-event&quot;: &quot;^12.8.3&quot;,
115      &quot;moment-timezone&quot;: &quot;^0.5.33&quot;,
116      &quot;node-sass&quot;: &quot;^6.0.1&quot;,
117      &quot;react&quot;: &quot;^17.0.2&quot;,
118      &quot;react-dom&quot;: &quot;^17.0.2&quot;,
119      &quot;react-live-clock&quot;: &quot;^5.2.0&quot;,
120      &quot;react-modal&quot;: &quot;^3.14.3&quot;,
121      &quot;react-moment&quot;: &quot;^1.1.1&quot;,
122      &quot;react-scripts&quot;: &quot;4.0.3&quot;,
123      &quot;uuid&quot;: &quot;^8.3.2&quot;,
124      &quot;web-vitals&quot;: &quot;^1.1.2&quot;
125  },
126const CentContext = createContext({
127  Icons: null,
128  rows: {},
129  addItem: () =&gt; {},
130  removeItem: () =&gt; {}
131});
132import { v4 as uuidV4 } from &quot;uuid&quot;;
133
134...
135
136export default (state, action) =&gt; {
137  switch (action.type) {
138    ...
139
140    case ADD_ITEM:
141      console.log(&quot;add item&quot;);
142      return {
143        ...state,
144        rows: {
145          ...state.rows,
146          [action.rowId]: [
147            ...(state.rows[action.rowId] ?? []),
148            { id: uuidV4() }
149          ]
150        }
151      };
152
153    case REMOVE_ITEM:
154      return {
155        ...state,
156        rows: {
157          ...state.rows,
158          [action.rowId]: state.rows[action.rowId]?.filter(
159            (el) =&gt; el.id !== action.elementId
160          )
161        }
162      };
163      
164    default:
165      return state;
166  }
167};
168const AppState = (props) =&gt; {
169  const initialState = {
170    Icons: false,
171    rows: {}
172  };
173
174  const [state, dispatch] = useReducer(AppReducer, initialState);
175
176  ...
177
178  const addItem = (rowId) =&gt; {
179    dispatch({
180      type: ADD_ITEM,
181      rowId,
182    });
183  };
184
185  const removeItem = (rowId, elementId) =&gt; {
186    dispatch({
187      type: REMOVE_ITEM,
188      rowId,
189      elementId,
190    });
191  };
192
193  return (
194    &lt;appContext.Provider
195      value={{
196        Icons: state.Icons,
197        Items: state.Items,
198        rows: state.rows,
199        addItem,
200        removeItem
201      }}
202    &gt;
203      {props.children}
204    &lt;/appContext.Provider&gt;
205  );
206};
207

App - Give each Row component an id prop to uniquely identify it.

1// Context Module
2import React, { useReducer } from 'react'
3import appContext from './appContext'
4import AppReducer from './appReducer'
5import Item from '../../components/Item';
6// the action to chanhe the state !!! 
7import {
8    ICONS, 
9    ITEMS, 
10    ADD_ITEM,
11    REMOVE_ITEM
12    
13}  from '../types'
14// Creating the state  MUST BE A CAPITAL OTHER WISE IT WILL B^&amp;% !! AND REFUSE TO COMPILE
15const AppState = (props) =&gt; {
16const initialState = {
17    Icons : false,
18    Items : [&lt;Item/&gt;],
19}
20
21const [state, dispatch] = useReducer(AppReducer, initialState)
22const Iconsshow = () =&gt; {
23    // show the icon 
24    dispatch({
25        type: ICONS,
26        stabelIcons : true
27    })
28}
29
30const Iconshide = () =&gt; {
31    // show the icon 
32    dispatch({
33        type: ICONS,
34        stabelIcons : false
35    })
36}
37
38const AddItem = ()=&gt; {
39    dispatch({
40    type: ADD_ITEM,
41    Items : [...state.Items, initialState.Items]
42})
43}
44
45const RemoveItem = (e)=&gt; {
46    dispatch({
47    type: REMOVE_ITEM,
48    Items : [[&lt;Item/&gt;]]
49})
50}
51
52return &lt;appContext.Provider
53value={{ 
54    Icons : state.Icons,
55    Items : state.Items,
56    AddItem,
57    RemoveItem
58    }}&gt;
59{props.children}
60&lt;/appContext.Provider&gt;
61}
62
63export default AppState;
64// Reducer Module
65
66import {
67    ICONS_SHOW,
68    ICONS_HIDE,
69    ITEMS,
70    ADD_ITEM,
71    REMOVE_ITEM
72} from "../types"
73
74export default (state, action ) =&gt; {
75
76switch(action.type) {
77    case ICONS_SHOW:
78    return {
79        ...state,
80        Icons: true
81    } 
82    case ICONS_HIDE:
83    return {
84        ...state,
85        Icons: false
86    }
87    case ITEMS:
88    return {
89        ...state,
90        Items: action.Items
91    } 
92    case ADD_ITEM:
93        return {
94        ...state,
95        Items: [...state.Items, action.payload]
96     
97    }
98    case REMOVE_ITEM:
99        return {
100        ...state,
101        Items: action.payload
102    }
103default: 
104return state
105}
106}&quot;dependencies&quot;: {
107      &quot;@fortawesome/fontawesome-svg-core&quot;: &quot;^1.2.36&quot;,
108      &quot;@fortawesome/free-brands-svg-icons&quot;: &quot;^5.15.4&quot;,
109      &quot;@fortawesome/free-regular-svg-icons&quot;: &quot;^5.15.4&quot;,
110      &quot;@fortawesome/free-solid-svg-icons&quot;: &quot;^5.15.4&quot;,
111      &quot;@fortawesome/react-fontawesome&quot;: &quot;^0.1.15&quot;,
112      &quot;@testing-library/jest-dom&quot;: &quot;^5.14.1&quot;,
113      &quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
114      &quot;@testing-library/user-event&quot;: &quot;^12.8.3&quot;,
115      &quot;moment-timezone&quot;: &quot;^0.5.33&quot;,
116      &quot;node-sass&quot;: &quot;^6.0.1&quot;,
117      &quot;react&quot;: &quot;^17.0.2&quot;,
118      &quot;react-dom&quot;: &quot;^17.0.2&quot;,
119      &quot;react-live-clock&quot;: &quot;^5.2.0&quot;,
120      &quot;react-modal&quot;: &quot;^3.14.3&quot;,
121      &quot;react-moment&quot;: &quot;^1.1.1&quot;,
122      &quot;react-scripts&quot;: &quot;4.0.3&quot;,
123      &quot;uuid&quot;: &quot;^8.3.2&quot;,
124      &quot;web-vitals&quot;: &quot;^1.1.2&quot;
125  },
126const CentContext = createContext({
127  Icons: null,
128  rows: {},
129  addItem: () =&gt; {},
130  removeItem: () =&gt; {}
131});
132import { v4 as uuidV4 } from &quot;uuid&quot;;
133
134...
135
136export default (state, action) =&gt; {
137  switch (action.type) {
138    ...
139
140    case ADD_ITEM:
141      console.log(&quot;add item&quot;);
142      return {
143        ...state,
144        rows: {
145          ...state.rows,
146          [action.rowId]: [
147            ...(state.rows[action.rowId] ?? []),
148            { id: uuidV4() }
149          ]
150        }
151      };
152
153    case REMOVE_ITEM:
154      return {
155        ...state,
156        rows: {
157          ...state.rows,
158          [action.rowId]: state.rows[action.rowId]?.filter(
159            (el) =&gt; el.id !== action.elementId
160          )
161        }
162      };
163      
164    default:
165      return state;
166  }
167};
168const AppState = (props) =&gt; {
169  const initialState = {
170    Icons: false,
171    rows: {}
172  };
173
174  const [state, dispatch] = useReducer(AppReducer, initialState);
175
176  ...
177
178  const addItem = (rowId) =&gt; {
179    dispatch({
180      type: ADD_ITEM,
181      rowId,
182    });
183  };
184
185  const removeItem = (rowId, elementId) =&gt; {
186    dispatch({
187      type: REMOVE_ITEM,
188      rowId,
189      elementId,
190    });
191  };
192
193  return (
194    &lt;appContext.Provider
195      value={{
196        Icons: state.Icons,
197        Items: state.Items,
198        rows: state.rows,
199        addItem,
200        removeItem
201      }}
202    &gt;
203      {props.children}
204    &lt;/appContext.Provider&gt;
205  );
206};
207&lt;AppState&gt;
208  &lt;Row id={1} /&gt;
209  &lt;Row id={2} /&gt;
210  &lt;Row id={3} /&gt;
211&lt;/AppState&gt;
212

Row - Pass the rows id prop to the addItem handler. Map the rows state to the Item component.

1// Context Module
2import React, { useReducer } from 'react'
3import appContext from './appContext'
4import AppReducer from './appReducer'
5import Item from '../../components/Item';
6// the action to chanhe the state !!! 
7import {
8    ICONS, 
9    ITEMS, 
10    ADD_ITEM,
11    REMOVE_ITEM
12    
13}  from '../types'
14// Creating the state  MUST BE A CAPITAL OTHER WISE IT WILL B^&amp;% !! AND REFUSE TO COMPILE
15const AppState = (props) =&gt; {
16const initialState = {
17    Icons : false,
18    Items : [&lt;Item/&gt;],
19}
20
21const [state, dispatch] = useReducer(AppReducer, initialState)
22const Iconsshow = () =&gt; {
23    // show the icon 
24    dispatch({
25        type: ICONS,
26        stabelIcons : true
27    })
28}
29
30const Iconshide = () =&gt; {
31    // show the icon 
32    dispatch({
33        type: ICONS,
34        stabelIcons : false
35    })
36}
37
38const AddItem = ()=&gt; {
39    dispatch({
40    type: ADD_ITEM,
41    Items : [...state.Items, initialState.Items]
42})
43}
44
45const RemoveItem = (e)=&gt; {
46    dispatch({
47    type: REMOVE_ITEM,
48    Items : [[&lt;Item/&gt;]]
49})
50}
51
52return &lt;appContext.Provider
53value={{ 
54    Icons : state.Icons,
55    Items : state.Items,
56    AddItem,
57    RemoveItem
58    }}&gt;
59{props.children}
60&lt;/appContext.Provider&gt;
61}
62
63export default AppState;
64// Reducer Module
65
66import {
67    ICONS_SHOW,
68    ICONS_HIDE,
69    ITEMS,
70    ADD_ITEM,
71    REMOVE_ITEM
72} from "../types"
73
74export default (state, action ) =&gt; {
75
76switch(action.type) {
77    case ICONS_SHOW:
78    return {
79        ...state,
80        Icons: true
81    } 
82    case ICONS_HIDE:
83    return {
84        ...state,
85        Icons: false
86    }
87    case ITEMS:
88    return {
89        ...state,
90        Items: action.Items
91    } 
92    case ADD_ITEM:
93        return {
94        ...state,
95        Items: [...state.Items, action.payload]
96     
97    }
98    case REMOVE_ITEM:
99        return {
100        ...state,
101        Items: action.payload
102    }
103default: 
104return state
105}
106}&quot;dependencies&quot;: {
107      &quot;@fortawesome/fontawesome-svg-core&quot;: &quot;^1.2.36&quot;,
108      &quot;@fortawesome/free-brands-svg-icons&quot;: &quot;^5.15.4&quot;,
109      &quot;@fortawesome/free-regular-svg-icons&quot;: &quot;^5.15.4&quot;,
110      &quot;@fortawesome/free-solid-svg-icons&quot;: &quot;^5.15.4&quot;,
111      &quot;@fortawesome/react-fontawesome&quot;: &quot;^0.1.15&quot;,
112      &quot;@testing-library/jest-dom&quot;: &quot;^5.14.1&quot;,
113      &quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
114      &quot;@testing-library/user-event&quot;: &quot;^12.8.3&quot;,
115      &quot;moment-timezone&quot;: &quot;^0.5.33&quot;,
116      &quot;node-sass&quot;: &quot;^6.0.1&quot;,
117      &quot;react&quot;: &quot;^17.0.2&quot;,
118      &quot;react-dom&quot;: &quot;^17.0.2&quot;,
119      &quot;react-live-clock&quot;: &quot;^5.2.0&quot;,
120      &quot;react-modal&quot;: &quot;^3.14.3&quot;,
121      &quot;react-moment&quot;: &quot;^1.1.1&quot;,
122      &quot;react-scripts&quot;: &quot;4.0.3&quot;,
123      &quot;uuid&quot;: &quot;^8.3.2&quot;,
124      &quot;web-vitals&quot;: &quot;^1.1.2&quot;
125  },
126const CentContext = createContext({
127  Icons: null,
128  rows: {},
129  addItem: () =&gt; {},
130  removeItem: () =&gt; {}
131});
132import { v4 as uuidV4 } from &quot;uuid&quot;;
133
134...
135
136export default (state, action) =&gt; {
137  switch (action.type) {
138    ...
139
140    case ADD_ITEM:
141      console.log(&quot;add item&quot;);
142      return {
143        ...state,
144        rows: {
145          ...state.rows,
146          [action.rowId]: [
147            ...(state.rows[action.rowId] ?? []),
148            { id: uuidV4() }
149          ]
150        }
151      };
152
153    case REMOVE_ITEM:
154      return {
155        ...state,
156        rows: {
157          ...state.rows,
158          [action.rowId]: state.rows[action.rowId]?.filter(
159            (el) =&gt; el.id !== action.elementId
160          )
161        }
162      };
163      
164    default:
165      return state;
166  }
167};
168const AppState = (props) =&gt; {
169  const initialState = {
170    Icons: false,
171    rows: {}
172  };
173
174  const [state, dispatch] = useReducer(AppReducer, initialState);
175
176  ...
177
178  const addItem = (rowId) =&gt; {
179    dispatch({
180      type: ADD_ITEM,
181      rowId,
182    });
183  };
184
185  const removeItem = (rowId, elementId) =&gt; {
186    dispatch({
187      type: REMOVE_ITEM,
188      rowId,
189      elementId,
190    });
191  };
192
193  return (
194    &lt;appContext.Provider
195      value={{
196        Icons: state.Icons,
197        Items: state.Items,
198        rows: state.rows,
199        addItem,
200        removeItem
201      }}
202    &gt;
203      {props.children}
204    &lt;/appContext.Provider&gt;
205  );
206};
207&lt;AppState&gt;
208  &lt;Row id={1} /&gt;
209  &lt;Row id={2} /&gt;
210  &lt;Row id={3} /&gt;
211&lt;/AppState&gt;
212function Row(props) {
213  // getting the context needed
214  const context = useContext(appContext);
215  return (
216    &lt;li className=&quot;day-row check faderin&quot;&gt;
217      &lt;div className=&quot;income-outcome&quot;&gt;
218        &lt;div className=&quot;vl-changable&quot;&gt;&lt;/div&gt;
219        &lt;ul className=&quot;global income dayIncome&quot;&gt;
220          {context.rows[props.id]?.map((el) =&gt; (
221            &lt;Item key={el.id} rowId={props.id} id={el.id} /&gt;
222          ))}
223          &lt;FontAwesomeIcon
224            className=&quot;changable margin-left&quot;
225            onClick={() =&gt; context.addItem(props.id)}
226            icon={[&quot;fas&quot;, &quot;plus-circle&quot;]}
227            size=&quot;lg&quot;
228          /&gt;
229        &lt;/ul&gt;
230      &lt;/div&gt;
231    &lt;/li&gt;
232  );
233}
234
Removing a single element

Removing a single element from state was covered above, but you need to pass the correct row and element ids to the removeItem handler.

1// Context Module
2import React, { useReducer } from 'react'
3import appContext from './appContext'
4import AppReducer from './appReducer'
5import Item from '../../components/Item';
6// the action to chanhe the state !!! 
7import {
8    ICONS, 
9    ITEMS, 
10    ADD_ITEM,
11    REMOVE_ITEM
12    
13}  from '../types'
14// Creating the state  MUST BE A CAPITAL OTHER WISE IT WILL B^&amp;% !! AND REFUSE TO COMPILE
15const AppState = (props) =&gt; {
16const initialState = {
17    Icons : false,
18    Items : [&lt;Item/&gt;],
19}
20
21const [state, dispatch] = useReducer(AppReducer, initialState)
22const Iconsshow = () =&gt; {
23    // show the icon 
24    dispatch({
25        type: ICONS,
26        stabelIcons : true
27    })
28}
29
30const Iconshide = () =&gt; {
31    // show the icon 
32    dispatch({
33        type: ICONS,
34        stabelIcons : false
35    })
36}
37
38const AddItem = ()=&gt; {
39    dispatch({
40    type: ADD_ITEM,
41    Items : [...state.Items, initialState.Items]
42})
43}
44
45const RemoveItem = (e)=&gt; {
46    dispatch({
47    type: REMOVE_ITEM,
48    Items : [[&lt;Item/&gt;]]
49})
50}
51
52return &lt;appContext.Provider
53value={{ 
54    Icons : state.Icons,
55    Items : state.Items,
56    AddItem,
57    RemoveItem
58    }}&gt;
59{props.children}
60&lt;/appContext.Provider&gt;
61}
62
63export default AppState;
64// Reducer Module
65
66import {
67    ICONS_SHOW,
68    ICONS_HIDE,
69    ITEMS,
70    ADD_ITEM,
71    REMOVE_ITEM
72} from "../types"
73
74export default (state, action ) =&gt; {
75
76switch(action.type) {
77    case ICONS_SHOW:
78    return {
79        ...state,
80        Icons: true
81    } 
82    case ICONS_HIDE:
83    return {
84        ...state,
85        Icons: false
86    }
87    case ITEMS:
88    return {
89        ...state,
90        Items: action.Items
91    } 
92    case ADD_ITEM:
93        return {
94        ...state,
95        Items: [...state.Items, action.payload]
96     
97    }
98    case REMOVE_ITEM:
99        return {
100        ...state,
101        Items: action.payload
102    }
103default: 
104return state
105}
106}&quot;dependencies&quot;: {
107      &quot;@fortawesome/fontawesome-svg-core&quot;: &quot;^1.2.36&quot;,
108      &quot;@fortawesome/free-brands-svg-icons&quot;: &quot;^5.15.4&quot;,
109      &quot;@fortawesome/free-regular-svg-icons&quot;: &quot;^5.15.4&quot;,
110      &quot;@fortawesome/free-solid-svg-icons&quot;: &quot;^5.15.4&quot;,
111      &quot;@fortawesome/react-fontawesome&quot;: &quot;^0.1.15&quot;,
112      &quot;@testing-library/jest-dom&quot;: &quot;^5.14.1&quot;,
113      &quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
114      &quot;@testing-library/user-event&quot;: &quot;^12.8.3&quot;,
115      &quot;moment-timezone&quot;: &quot;^0.5.33&quot;,
116      &quot;node-sass&quot;: &quot;^6.0.1&quot;,
117      &quot;react&quot;: &quot;^17.0.2&quot;,
118      &quot;react-dom&quot;: &quot;^17.0.2&quot;,
119      &quot;react-live-clock&quot;: &quot;^5.2.0&quot;,
120      &quot;react-modal&quot;: &quot;^3.14.3&quot;,
121      &quot;react-moment&quot;: &quot;^1.1.1&quot;,
122      &quot;react-scripts&quot;: &quot;4.0.3&quot;,
123      &quot;uuid&quot;: &quot;^8.3.2&quot;,
124      &quot;web-vitals&quot;: &quot;^1.1.2&quot;
125  },
126const CentContext = createContext({
127  Icons: null,
128  rows: {},
129  addItem: () =&gt; {},
130  removeItem: () =&gt; {}
131});
132import { v4 as uuidV4 } from &quot;uuid&quot;;
133
134...
135
136export default (state, action) =&gt; {
137  switch (action.type) {
138    ...
139
140    case ADD_ITEM:
141      console.log(&quot;add item&quot;);
142      return {
143        ...state,
144        rows: {
145          ...state.rows,
146          [action.rowId]: [
147            ...(state.rows[action.rowId] ?? []),
148            { id: uuidV4() }
149          ]
150        }
151      };
152
153    case REMOVE_ITEM:
154      return {
155        ...state,
156        rows: {
157          ...state.rows,
158          [action.rowId]: state.rows[action.rowId]?.filter(
159            (el) =&gt; el.id !== action.elementId
160          )
161        }
162      };
163      
164    default:
165      return state;
166  }
167};
168const AppState = (props) =&gt; {
169  const initialState = {
170    Icons: false,
171    rows: {}
172  };
173
174  const [state, dispatch] = useReducer(AppReducer, initialState);
175
176  ...
177
178  const addItem = (rowId) =&gt; {
179    dispatch({
180      type: ADD_ITEM,
181      rowId,
182    });
183  };
184
185  const removeItem = (rowId, elementId) =&gt; {
186    dispatch({
187      type: REMOVE_ITEM,
188      rowId,
189      elementId,
190    });
191  };
192
193  return (
194    &lt;appContext.Provider
195      value={{
196        Icons: state.Icons,
197        Items: state.Items,
198        rows: state.rows,
199        addItem,
200        removeItem
201      }}
202    &gt;
203      {props.children}
204    &lt;/appContext.Provider&gt;
205  );
206};
207&lt;AppState&gt;
208  &lt;Row id={1} /&gt;
209  &lt;Row id={2} /&gt;
210  &lt;Row id={3} /&gt;
211&lt;/AppState&gt;
212function Row(props) {
213  // getting the context needed
214  const context = useContext(appContext);
215  return (
216    &lt;li className=&quot;day-row check faderin&quot;&gt;
217      &lt;div className=&quot;income-outcome&quot;&gt;
218        &lt;div className=&quot;vl-changable&quot;&gt;&lt;/div&gt;
219        &lt;ul className=&quot;global income dayIncome&quot;&gt;
220          {context.rows[props.id]?.map((el) =&gt; (
221            &lt;Item key={el.id} rowId={props.id} id={el.id} /&gt;
222          ))}
223          &lt;FontAwesomeIcon
224            className=&quot;changable margin-left&quot;
225            onClick={() =&gt; context.addItem(props.id)}
226            icon={[&quot;fas&quot;, &quot;plus-circle&quot;]}
227            size=&quot;lg&quot;
228          /&gt;
229        &lt;/ul&gt;
230      &lt;/div&gt;
231    &lt;/li&gt;
232  );
233}
234function ChangeablelItem(props) {
235  const { rowId, id } = props;
236  const context = useContext(appContext);
237  ...
238  return (
239    &lt;li className=&quot;day-item&quot;&gt;
240      ... editable div ...
241      &lt;div className=&quot;icons&quot;&gt;
242        {iconsVisble &amp;&amp; (
243          &lt;RemoveIcon
244            removeItem={() =&gt; context.removeItem(rowId, id)}
245          /&gt;
246        )}
247      &lt;/div&gt;
248    &lt;/li&gt;
249  );
250}
251
Hiding an icon after click outside of the item

This was actually the easiest issue to resolve. Use onFocus and onBlur handlers to set the iconVisible state to show the delete button. I used a setTimeout on the blur handler to keep it the delete button mounted long enough when clicked to call the removeItem handler.

1// Context Module
2import React, { useReducer } from 'react'
3import appContext from './appContext'
4import AppReducer from './appReducer'
5import Item from '../../components/Item';
6// the action to chanhe the state !!! 
7import {
8    ICONS, 
9    ITEMS, 
10    ADD_ITEM,
11    REMOVE_ITEM
12    
13}  from '../types'
14// Creating the state  MUST BE A CAPITAL OTHER WISE IT WILL B^&amp;% !! AND REFUSE TO COMPILE
15const AppState = (props) =&gt; {
16const initialState = {
17    Icons : false,
18    Items : [&lt;Item/&gt;],
19}
20
21const [state, dispatch] = useReducer(AppReducer, initialState)
22const Iconsshow = () =&gt; {
23    // show the icon 
24    dispatch({
25        type: ICONS,
26        stabelIcons : true
27    })
28}
29
30const Iconshide = () =&gt; {
31    // show the icon 
32    dispatch({
33        type: ICONS,
34        stabelIcons : false
35    })
36}
37
38const AddItem = ()=&gt; {
39    dispatch({
40    type: ADD_ITEM,
41    Items : [...state.Items, initialState.Items]
42})
43}
44
45const RemoveItem = (e)=&gt; {
46    dispatch({
47    type: REMOVE_ITEM,
48    Items : [[&lt;Item/&gt;]]
49})
50}
51
52return &lt;appContext.Provider
53value={{ 
54    Icons : state.Icons,
55    Items : state.Items,
56    AddItem,
57    RemoveItem
58    }}&gt;
59{props.children}
60&lt;/appContext.Provider&gt;
61}
62
63export default AppState;
64// Reducer Module
65
66import {
67    ICONS_SHOW,
68    ICONS_HIDE,
69    ITEMS,
70    ADD_ITEM,
71    REMOVE_ITEM
72} from "../types"
73
74export default (state, action ) =&gt; {
75
76switch(action.type) {
77    case ICONS_SHOW:
78    return {
79        ...state,
80        Icons: true
81    } 
82    case ICONS_HIDE:
83    return {
84        ...state,
85        Icons: false
86    }
87    case ITEMS:
88    return {
89        ...state,
90        Items: action.Items
91    } 
92    case ADD_ITEM:
93        return {
94        ...state,
95        Items: [...state.Items, action.payload]
96     
97    }
98    case REMOVE_ITEM:
99        return {
100        ...state,
101        Items: action.payload
102    }
103default: 
104return state
105}
106}&quot;dependencies&quot;: {
107      &quot;@fortawesome/fontawesome-svg-core&quot;: &quot;^1.2.36&quot;,
108      &quot;@fortawesome/free-brands-svg-icons&quot;: &quot;^5.15.4&quot;,
109      &quot;@fortawesome/free-regular-svg-icons&quot;: &quot;^5.15.4&quot;,
110      &quot;@fortawesome/free-solid-svg-icons&quot;: &quot;^5.15.4&quot;,
111      &quot;@fortawesome/react-fontawesome&quot;: &quot;^0.1.15&quot;,
112      &quot;@testing-library/jest-dom&quot;: &quot;^5.14.1&quot;,
113      &quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
114      &quot;@testing-library/user-event&quot;: &quot;^12.8.3&quot;,
115      &quot;moment-timezone&quot;: &quot;^0.5.33&quot;,
116      &quot;node-sass&quot;: &quot;^6.0.1&quot;,
117      &quot;react&quot;: &quot;^17.0.2&quot;,
118      &quot;react-dom&quot;: &quot;^17.0.2&quot;,
119      &quot;react-live-clock&quot;: &quot;^5.2.0&quot;,
120      &quot;react-modal&quot;: &quot;^3.14.3&quot;,
121      &quot;react-moment&quot;: &quot;^1.1.1&quot;,
122      &quot;react-scripts&quot;: &quot;4.0.3&quot;,
123      &quot;uuid&quot;: &quot;^8.3.2&quot;,
124      &quot;web-vitals&quot;: &quot;^1.1.2&quot;
125  },
126const CentContext = createContext({
127  Icons: null,
128  rows: {},
129  addItem: () =&gt; {},
130  removeItem: () =&gt; {}
131});
132import { v4 as uuidV4 } from &quot;uuid&quot;;
133
134...
135
136export default (state, action) =&gt; {
137  switch (action.type) {
138    ...
139
140    case ADD_ITEM:
141      console.log(&quot;add item&quot;);
142      return {
143        ...state,
144        rows: {
145          ...state.rows,
146          [action.rowId]: [
147            ...(state.rows[action.rowId] ?? []),
148            { id: uuidV4() }
149          ]
150        }
151      };
152
153    case REMOVE_ITEM:
154      return {
155        ...state,
156        rows: {
157          ...state.rows,
158          [action.rowId]: state.rows[action.rowId]?.filter(
159            (el) =&gt; el.id !== action.elementId
160          )
161        }
162      };
163      
164    default:
165      return state;
166  }
167};
168const AppState = (props) =&gt; {
169  const initialState = {
170    Icons: false,
171    rows: {}
172  };
173
174  const [state, dispatch] = useReducer(AppReducer, initialState);
175
176  ...
177
178  const addItem = (rowId) =&gt; {
179    dispatch({
180      type: ADD_ITEM,
181      rowId,
182    });
183  };
184
185  const removeItem = (rowId, elementId) =&gt; {
186    dispatch({
187      type: REMOVE_ITEM,
188      rowId,
189      elementId,
190    });
191  };
192
193  return (
194    &lt;appContext.Provider
195      value={{
196        Icons: state.Icons,
197        Items: state.Items,
198        rows: state.rows,
199        addItem,
200        removeItem
201      }}
202    &gt;
203      {props.children}
204    &lt;/appContext.Provider&gt;
205  );
206};
207&lt;AppState&gt;
208  &lt;Row id={1} /&gt;
209  &lt;Row id={2} /&gt;
210  &lt;Row id={3} /&gt;
211&lt;/AppState&gt;
212function Row(props) {
213  // getting the context needed
214  const context = useContext(appContext);
215  return (
216    &lt;li className=&quot;day-row check faderin&quot;&gt;
217      &lt;div className=&quot;income-outcome&quot;&gt;
218        &lt;div className=&quot;vl-changable&quot;&gt;&lt;/div&gt;
219        &lt;ul className=&quot;global income dayIncome&quot;&gt;
220          {context.rows[props.id]?.map((el) =&gt; (
221            &lt;Item key={el.id} rowId={props.id} id={el.id} /&gt;
222          ))}
223          &lt;FontAwesomeIcon
224            className=&quot;changable margin-left&quot;
225            onClick={() =&gt; context.addItem(props.id)}
226            icon={[&quot;fas&quot;, &quot;plus-circle&quot;]}
227            size=&quot;lg&quot;
228          /&gt;
229        &lt;/ul&gt;
230      &lt;/div&gt;
231    &lt;/li&gt;
232  );
233}
234function ChangeablelItem(props) {
235  const { rowId, id } = props;
236  const context = useContext(appContext);
237  ...
238  return (
239    &lt;li className=&quot;day-item&quot;&gt;
240      ... editable div ...
241      &lt;div className=&quot;icons&quot;&gt;
242        {iconsVisble &amp;&amp; (
243          &lt;RemoveIcon
244            removeItem={() =&gt; context.removeItem(rowId, id)}
245          /&gt;
246        )}
247      &lt;/div&gt;
248    &lt;/li&gt;
249  );
250}
251// Icon State
252const [iconsVisble, setIconVisble] = useState(false);
253
254...
255
256&lt;div
257  className=&quot;number amount&quot;
258  onFocus={() =&gt; setIconVisble(true)}
259  onBlur={() =&gt; setTimeout(() =&gt; setIconVisble(false), 200)}
260  contentEditable=&quot;true&quot;
261/&gt;
262

Edit react-context-api-context-api-issues-when-adding-and-removing-an-items-from-ui

Source https://stackoverflow.com/questions/68914785

QUESTION

BLE: How to get correct service UUID and characteristic UUID?

Asked 2021-Jan-08 at 06:18

I am a new in Bluetooth connection and I want to add second device in my iOS project. I already have one device, and the new device is very similar with first one, but little bit deferent. I have one process for the two devices, and I did not change a lot of code, just created all value for the new device. My all devices have different name and identifier, first device is working fine.

For creating UUID values, I used UUID generator (https://www.guidgenerator.com/online-guid-generator.aspx).

1class BleConstants: NSObject {
2let deviceTwoServiceUUID = “59DE3994-6A63-4654-8FF0-F85C5163B2F5”
3let deviceTwoFirstCharacteristicUUID = “59DE3994-6A63-4654-8FF0-F85C5163B2F6”
4let deviceTwoSecondCharacteristicUUID = “59DE3994-6A63-4654-8FF0-F85C5163B2F7”
5let deviceOneServiceUUID = “A6AF4483-E210-457B-B9D6-B8A621513D1D”
6let deviceOneFirstCharacteristicUUID = “A6AF4483-E210-457B-B9D6-B8A621513D2D”
7let deviceOneSecondCharacteristicUUID = “A6AF4483-E210-457B-B9D6-B8A621513D2D”
8}
9
10class BleManager: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
11@objc private(set) static var sharedInstance = BleManager()
12var cbManager : CBCentralManager? = nil
13var currentPeripheral : CBPeripheral? = nil
14var secondService : CBService? = nil
15var firstService : CBService? = nil
16var secondFirstCharacteristic : CBCharacteristic!
17var secondSecondCharacteristic : CBCharacteristic!
18var firstFirstCharacteristic : CBCharacteristic!
19var firstSecondCharacteristic : CBCharacteristic!
20
21func initCentralManager() {
22    if cbManager == nil {
23        cbManager = CBCentralManager(delegate: self, queue: nil, options: [CBCentralManagerOptionRestoreIdentifierKey : “MyApp”, CBCentralManagerOptionShowPowerAlertKey: true])            
24    }
25
26func deinitCentralManager() {
27    cbManager = nil
28}
29
30func isBluetoothAvailable() -&gt; Bool {
31    return cbManager?.state == CBManagerState.poweredOn
32}
33
34func scan() {
35    if (cbManager != nil &amp;&amp; (cbManager?.isScanning)!) {
36        return
37    }
38    
39    discoveredPeripherals.removeAll()
40    
41    let serviceUUIDs = [CBUUID(string: BleConstants.deviceTwoServiceUUID), CBUUID(string: BleConstants.deviceOneServiceUUID)]
42    
43    cbManager?.scanForPeripherals(withServices: serviceUUIDs,
44                                  options: [CBCentralManagerScanOptionAllowDuplicatesKey : 1])
45}
46
47func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
48    if(!discoveredPeripherals.contains(peripheral)) {
49        discoveredPeripherals.append(peripheral)
50    }
51}
52
53func stopScan() {
54    if cbManager != nil &amp;&amp; (cbManager?.isScanning)! {
55        cbManager?.stopScan()
56    }
57}
58
59func connect(peripheral: CBPeripheral) {
60    if cbManager?.state == CBManagerState.poweredOn {
61        if currentPeripheral == nil || currentPeripheral?.state != CBPeripheralState.connected {
62            cbManager?.connect(peripheral, options: nil)
63        } else {
64            cbManager?.cancelPeripheralConnection(peripheral)
65        }
66    }
67}
68
69func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
70Device.savePeripheralString(peripheral: peripheral.identifier.uuidString)
71    AutoConnect.stop()
72DeviceUpdate.updateProgress = .None
73Device.isDongleConnected = true
74currentPeripheral = peripheral
75currentPeripheral?.delegate = self
76currentPeripheral?.discoverServices(nil)
77disableSleep()
78}
79
80func disableSleep() {
81    UIApplication.shared.isIdleTimerDisabled = true
82}
83
84func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
85 if error != nil {
86        return
87    }
88
89    if let services = peripheral.services {
90
91        for service in services {
92            if service.uuid.uuidString == BleConstants.deviceTwoServiceUUID {
93        Device.dongleType = port.second
94                    secondService = service
95                peripheral.discoverCharacteristics(nil, for: service)
96        }
97            if service.uuid.uuidString == BleConstants.deviceOneServiceUUID {
98        Device.dongleType = port.first
99                firstService = service
100                peripheral.discoverCharacteristics(nil, for: service)
101            } else {
102                Log.bt(&quot;didDiscoverServices for peripheral not found \(peripheral.identifier.uuidString)&quot;)
103            }
104        }
105    }
106}
107
108func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
109
110    for characteristic in service.characteristics! {
111        if characteristic.uuid.uuidString == BleConstants.deviceOneFirstCharacteristicUUID {
112     firstCharacteristic = characteristic
113        }  
114    else if characteristic.uuid.uuidString == BleConstants.deviceOneSecondCharacteristicUUID {
115           firstSecondCharacteristic = characteristic
116        else if characteristic.uuid.uuidString == BleConstants.deviceTwoFirstCharacteristicUUID {
117            secondFirstCharacteristic = characteristic
118        } else if characteristic.uuid.uuidString == BleConstants.deviceTwoSecondCharacteristicUUID {
119    secondSecondCharacteristic = characteristic
120        } else {
121            Log.bt(&quot;didDiscoverCharacteristics not found \(characteristic.uuid.uuidString)&quot;)
122        }
123    }
124    
125    if Device.dongleType == .deviceTwo {
126         openPortDeviceTwo()
127    } else {
128        openPortDeviceOne()
129    }
130}
131

}

Data from logs:

For first device:

  1. isBluetoothAvailable()
  2. scan()
  3. CentralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) (peripheral <CBPeripheral: 0x267hg5670, identifier = 98HG761CE-56C3-K767-26HJ-E51BA678Gh56, name = DeviceOne, state = disconnected)
  4. CentralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
  5. scan()
  6. CentralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) (peripheral <CBPeripheral: 0x267hg5670, identifier = FJ1478HJ-EH8J-6709-1FH0-1456HGJ0BC901, name = SecondDevice, state = disconnected>)
  7. stopScan()
  8. connect(peripheral: CBPeripheral) (currentPeripheral nil, currentPeripheral nil)
  9. CentralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral
  10. centralManager(_:didConnect:) - didConnectPeripheral FJ1478HJ-EH8J-6709-1FH0-1456HGJ0BC901 Second device
  11. savedPeripheralString FJ1478HJ-EH8J-6709-1FH0-1456HGJ0BC901 Second device
  12. Bluetooth stop() currentPeripheral Optional(<CBPeripheral: 0x2jk875fe0, identifier = FJ1478HJ-EH8J-6709-1FH0-1456HGJ0BC901, name = SecondDevice, state = connected>)
  13. disableSleep()
  14. peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)
  15. peripheral(_:didDiscoverServices:) - didDiscoverServices for peripheral FJ1478HJ-EH8J-6709-1FH0-1456HGJ0BC901
  16. peripheral(_:didDiscoverServices:) - didDiscoverServices for peripheral.services Optional([<CBService: 0x2jkki2dc0, isPrimary = YES, UUID = 59DE3994-6A63-4654-8FF0-F85C5163B2F5>, <CBService: 0xhj67c240, isPrimary = YES, UUID = Device Information>]) [<CBService: 0x5678f2dc0, isPrimary = YES, UUID = 59DE3994-6A63-4654-8FF0-F85C5163B2F5>, <CBService: 0x28186c240, isPrimary = YES, UUID = Device Information>], peripheral.services is Optional([<CBService: 0xhjy62dc0, isPrimary = YES, UUID = 59DE3994-6A63-4654-8FF0-F85C5163B2F5>, <CBService: 0x2hju7240, isPrimary = YES, UUID = Device Information>])) service.uuid.uuidString is 59DE3994-6A63-4654-8FF0-F85C5163B2F5 and services is [<CBService: 0xhj7892dc0, isPrimary = YES, UUID = 59DE3994-6A63-4654-8FF0-F85C5163B2F5>, <CBService: 0xhjk678340, isPrimary = YES, UUID = Device Information>]
  17. peripheral(_:didDiscoverServices:) - didDiscoverServices SecondDevice 59DE3994-6A63-4654-8FF0-F85C5163B2F5
  18. peripheral(_:didDiscoverServices:) - didDiscoverServices for peripheral not found FJ1478HJ-EH8J-6709-1FH0-1456HGJ0BC901

For second device:

  1. isBluetoothAvailable()
  2. scan()
  3. CentralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) (peripheral <CBPeripheral: 0xh6789a40, identifier = 98HG761CE-56C3-K767-26HJ-E51BA678Gh56, name = DeviceOne, state = disconnected)
  4. scan()
  5. CentralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) (peripheral <CBPeripheral: 0x678jhs0, identifier = H56KIL35-7835-7JKL-2B11-HJKLIYTAA400, name = ThirdDevice, state = disconnected)
  6. CentralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
  7. stopScan()
  8. connect(peripheral: CBPeripheral) currentPeripheral nil, currentPeripheral nil
  9. CentralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral
  10. centralManager(_:didConnect:) - didConnectPeripheral H56KIL35-7835-7JKL-2B11-HJKLIYTAA400
  11. savedPeripheralString H56KIL35-7835-7JKL-2B11-HJKLIYTAA400
  12. Bluetooth stop() - currentPeripheral Optional(<CBPeripheral: 0x78jkl680, identifier = H56KIL35-7835-7JKL-2B11-HJKLIYTAA400, name = ThirdDevice, state = connected>)
  13. disableSleep()
  14. peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)
  15. peripheral(_:didDiscoverServices:) - didDiscoverServices for peripheral H56KIL35-7835-7JKL-2B11-HJKLIYTAA400
  16. **peripheral(_:didDiscoverServices:) - didDiscoverServices for peripheral.services Optional([<CBService: 0xlki8901c0, isPrimary = YES, UUID = 59DE3994-6A63-4654-8FF0-F85C5163B2F5 - same like for secondDevice>, <CBService: 0x281111180, isPrimary = YES, UUID = Device Information>]) services is [<CBService: 0x2827444c0, isPrimary = YES, UUID = 59DE3994-6A63-4654-8FF0-F85C5163B2F5 - same like for secondDevice>, <CBService: 0x282744580, isPrimary = YES, UUID = Device Information>], peripheral.services is Optional([<CBService: 0xlki8901c0, isPrimary = YES, UUID = 59DE3994-6A63-4654-8FF0-F85C5163B2F5 - same like for secondDevice>, <CBService: 0x281111180, isPrimary = YES, UUID = Device Information>])) service.uuid.uuidString is 59DE3994-6A63-4654-8FF0-F85C5163B2F5 - same like for secondDeviceand services is [<CBService: 0x27893kdc0, isPrimary = YES, UUID = 59DE3994-6A63-4654-8FF0-F85C5163B2F5 - same like for secondDevice>, <CBService: 0x679kh8580, isPrimary = YES, UUID = Device Information>]
  17. peripheral(_:didDiscoverServices:) - didDiscoverServices ThirdDevice 59DE3994-6A63-4654-8FF0-F85C5163B2F5 - same like for secondDevice
  18. peripheral(_:didDiscoverServices:) - didDiscoverServices for peripheral not found H56KIL35-7835-7JKL-2B11-HJKLIYTAA400**

Based on logs information for second device in 16th step app connected to my first service UUID and first characteristic UUID, that is wrong!

Do you have idea, Did I create UUIDs correct?

P.S: Android app works fine with both devices.

Thanks a lot!

ANSWER

Answered 2021-Jan-08 at 06:18

Receiving the same service and characteristic UUID for multiple BLE devices is perfectly normal and only means that all the devices offer exactly the same service.

For example: If you have two devices which measure the heart rate of a person, e.g. a smartwatch, both devices might offer the heart rate service with the same UUID.

If you want to differentiate between the device you can use the identifier which you received in step 3 of your provided log.

Source https://stackoverflow.com/questions/65588346

QUESTION

Syntax to manually insert a UUID value in Postgres

Asked 2020-Nov-19 at 15:41

I have a table that was created as such:

1CREATE TABLE IF NOT EXISTS DIM_Jour (
2    jour_id uuid NOT NULL,
3    AAAA int,
4    MM int,
5    JJ int,
6    Jour_Semaine int,
7    Num_Semaine int,
8
9    PRIMARY KEY (jour_id)
10);
11

I'm trying to manually insert some value for testing purposes. I know that eventually I would need to use a UUID generator.

1CREATE TABLE IF NOT EXISTS DIM_Jour (
2    jour_id uuid NOT NULL,
3    AAAA int,
4    MM int,
5    JJ int,
6    Jour_Semaine int,
7    Num_Semaine int,
8
9    PRIMARY KEY (jour_id)
10);
11INSERT INTO DIM_Jour (jour_id, AAAA, MM, JJ, Jour_Semaine, Num_Semaine) VALUES (
12    292a485f-a56a-4938-8f1a-bbbbbbbbbbb1,
13    2020,
14    11,
15    19,
16    4,
17    47
18);
19

I get this error (or similar)

1CREATE TABLE IF NOT EXISTS DIM_Jour (
2    jour_id uuid NOT NULL,
3    AAAA int,
4    MM int,
5    JJ int,
6    Jour_Semaine int,
7    Num_Semaine int,
8
9    PRIMARY KEY (jour_id)
10);
11INSERT INTO DIM_Jour (jour_id, AAAA, MM, JJ, Jour_Semaine, Num_Semaine) VALUES (
12    292a485f-a56a-4938-8f1a-bbbbbbbbbbb1,
13    2020,
14    11,
15    19,
16    4,
17    47
18);
19ERROR:  syntax error at or near &quot;a485f&quot;
20 LINE 3:  292a485f-a56a-4938-8f1a-bbbbbbbbbbb1,
21             ^
22

I've tried the different formats mentioned in the Postgres documentation, but it seems like it doesn't except any format. Is it a stupid syntax issue or am I missing something here? What is the correct syntax?

ANSWER

Answered 2020-Nov-19 at 15:40

You could pass it as a string literal and have the database implicitly convert it to a UUID:

1CREATE TABLE IF NOT EXISTS DIM_Jour (
2    jour_id uuid NOT NULL,
3    AAAA int,
4    MM int,
5    JJ int,
6    Jour_Semaine int,
7    Num_Semaine int,
8
9    PRIMARY KEY (jour_id)
10);
11INSERT INTO DIM_Jour (jour_id, AAAA, MM, JJ, Jour_Semaine, Num_Semaine) VALUES (
12    292a485f-a56a-4938-8f1a-bbbbbbbbbbb1,
13    2020,
14    11,
15    19,
16    4,
17    47
18);
19ERROR:  syntax error at or near &quot;a485f&quot;
20 LINE 3:  292a485f-a56a-4938-8f1a-bbbbbbbbbbb1,
21             ^
22INSERT INTO DIM_Jour (jour_id, AAAA, MM, JJ, Jour_Semaine, Num_Semaine) VALUES (
23    '292a485f-a56a-4938-8f1a-bbbbbbbbbbb1',
24    2020,
25    11,
26    19,
27    4,
28    47
29);
30

But it's probably a good practice to be explicit about it and perform the cast yourself

1CREATE TABLE IF NOT EXISTS DIM_Jour (
2    jour_id uuid NOT NULL,
3    AAAA int,
4    MM int,
5    JJ int,
6    Jour_Semaine int,
7    Num_Semaine int,
8
9    PRIMARY KEY (jour_id)
10);
11INSERT INTO DIM_Jour (jour_id, AAAA, MM, JJ, Jour_Semaine, Num_Semaine) VALUES (
12    292a485f-a56a-4938-8f1a-bbbbbbbbbbb1,
13    2020,
14    11,
15    19,
16    4,
17    47
18);
19ERROR:  syntax error at or near &quot;a485f&quot;
20 LINE 3:  292a485f-a56a-4938-8f1a-bbbbbbbbbbb1,
21             ^
22INSERT INTO DIM_Jour (jour_id, AAAA, MM, JJ, Jour_Semaine, Num_Semaine) VALUES (
23    '292a485f-a56a-4938-8f1a-bbbbbbbbbbb1',
24    2020,
25    11,
26    19,
27    4,
28    47
29);
30INSERT INTO DIM_Jour (jour_id, AAAA, MM, JJ, Jour_Semaine, Num_Semaine) VALUES (
31    '292a485f-a56a-4938-8f1a-bbbbbbbbbbb1'::UUID,
32    2020,
33    11,
34    19,
35    4,
36    47
37);
38

Source https://stackoverflow.com/questions/64914884

Community Discussions contain sources that include Stack Exchange Network

Tutorials and Learning Resources in UUID Generator

Tutorials and Learning Resources are not available at this moment for UUID Generator

Share this Page

share link

Get latest updates on UUID Generator