11#cloud-config
22bootcmd:
3+ - 'echo "bootcmd executed by service: $(ps -o comm= $PPID)" > /tmp/bootcmd_proof.txt'
34 # Resize the partition (4 = /dev/nvme0n1p4 typically)
45 - growpart /dev/nvme0n1 4
56runcmd:
7+ - 'echo "runcmd executed by service: $(ps -o comm= $PPID)" > /tmp/runcmd_proof.txt'
68 - systemctl enable --now kubelet
7- - export PS=$(podman run --rm docker.io/amazon/aws-cli ssm get-parameter --name "{{ .SSMPullSecretName }}" --with-decryption --query "Parameter.Value" --output text)
8- - echo ${PS} > /opt/crc/pull-secret
9- - chmod 0644 /opt/crc/pull-secret
10- - export KP=$(podman run --rm docker.io/amazon/aws-cli ssm get-parameter --name "{{ .SSMKubeAdminPasswordName }}" --with-decryption --query "Parameter.Value" --output text)
11- - echo ${KP} > /opt/crc/pass_kubeadmin
12- - chmod 0644 /opt/crc/pass_kubeadmin
13- - export DV=$(podman run --rm docker.io/amazon/aws-cli ssm get-parameter --name "{{ .SSMDeveloperPasswordName }}" --with-decryption --query "Parameter.Value" --output text)
14- - echo ${DV} > /opt/crc/pass_developer
15- - chmod 0644 /opt/crc/pass_developer
16- - echo "{{ .PublicIP }}" > /opt/crc/eip
17- - chmod 0644 /opt/crc/eip
9+ - /usr/local/bin/mapt-crc-aws-fetch-secrets-workaround.sh
1810write_files:
11+ - path: /opt/crc/eip
12+ content: "{{ .PublicIP }}"
13+ owner: root:root
14+ permissions: '0644'
1915- path: /home/core/.ssh/authorized_keys
2016 content: {{ .PubKey }}
2117 owner: {{ .Username }}
@@ -27,6 +23,152 @@ write_files:
2723- content: |
2824 CRC_SELF_SUFFICIENT=1
2925 CRC_NETWORK_MODE_USER=0
26+ CRC_SOURCE=mapt/snc
3027 owner: root:root
3128 path: /etc/sysconfig/crc-env
3229 permissions: '0644'
30+ - owner: root:root
31+ path: /usr/local/bin/mapt-crc-aws-fetch-secrets-workaround.sh
32+ permissions: '0755'
33+ content: |
34+ #!/bin/bash
35+ if [[ -f /usr/local/bin/crc-aws-fetch-secrets.sh ]]; then
36+ script=/usr/local/bin/crc-aws-fetch-secrets.sh
37+ else
38+ echo "crc-aws-fetch-secrets.sh not found, falling back to MAPT's copy"
39+ script=/usr/local/bin/mapt-crc-aws-fetch-secrets.sh
40+ fi
41+
42+ exec "$script" "{{ .SSMPullSecretName }}" "{{ .SSMKubeAdminPasswordName }}" "{{ .SSMDeveloperPasswordName }}"
43+ - owner: root:root
44+ path: /usr/local/bin/mapt-crc-aws-fetch-secrets.sh
45+ permissions: '0755'
46+ content: |
47+ #!/bin/bash
48+
49+ set -o pipefail
50+ set -o errexit
51+ set -o nounset
52+ set -o errtrace
53+ set -x
54+
55+ # set -x is safe, the secrets are passed via stdin
56+
57+ AWS_CLI_IMG=docker.io/amazon/aws-cli
58+ MIN_CHAR_COUNT=8 # minimum number of chars for the secret to be
59+ # assumed valid
60+
61+ umask 0077 # 0600 file permission for secrets
62+ install -d -m 0700 /opt/crc # ensure that the target directory exists
63+
64+ PULL_SECRETS_KEY=${1:-}
65+ KUBEADM_PASS_KEY=${2:-}
66+ DEVELOPER_PASS_KEY=${3:-}
67+
68+ if [[ -z "$PULL_SECRETS_KEY" || -z "$KUBEADM_PASS_KEY" || -z "$DEVELOPER_PASS_KEY" ]]; then
69+ echo "ERROR: expected to receive 3 parameters: PULL_SECRETS_KEY KUBEADM_PASS_KEY DEVELOPER_PASS_KEY"
70+ exit 1
71+ fi
72+
73+ DELAY=5
74+ TOTAL_PERIOD=$(( 3*60 ))
75+ ATTEMPTS=$(( TOTAL_PERIOD / DELAY))
76+ function retry_compact() {
77+ for i in $(seq 1 $ATTEMPTS); do
78+ # If the command succeeds (returns 0), exit the function with success.
79+ if "$@"; then
80+ echo "'$*' succeeded after $i attempts "
81+ return 0
82+ fi
83+ echo "'$*' still failing after $i/$ATTEMPTS attempts ..."
84+ sleep "$DELAY"
85+ done
86+ echo "'$*' didn't succeed after $i attempt ..."
87+ # If the loop finishes, the command never succeeded.
88+ return 1
89+ }
90+
91+ cleanup() {
92+ rm -f /tmp/aws-region /opt/crc/pull-secret.tmp /opt/crc/pass_kubeadmin.tmp /opt/crc/pass_developer.tmp
93+ echo "Temp files cleanup complete."
94+ }
95+
96+ # Cleanup happens automatically via trap on error or at script end
97+ trap cleanup ERR EXIT
98+
99+ SECONDS=0
100+ podman pull --quiet "$AWS_CLI_IMG"
101+ echo "Took $SECONDS seconds to pull the $AWS_CLI_IMG"
102+
103+ check_imds_available_and_get_region() {
104+ IMDS_TOKEN_COMMAND=(
105+ curl
106+ --connect-timeout 1
107+ -X PUT
108+ "http://169.254.169.254/latest/api/token"
109+ -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
110+ -Ssf
111+ )
112+
113+ if ! TOKEN=$("${IMDS_TOKEN_COMMAND[@]}"); then
114+ echo "Couldn't fetch the token..." >&2
115+ return 1
116+ fi
117+
118+ # Then, use the token to get the region
119+ echo "Fetching the AWS region ..."
120+ curl -Ssf -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/region > /tmp/aws-region
121+ echo >> /tmp/aws-region # add EOL at EOF, for consistency
122+ echo "AWS region: $(< /tmp/aws-region)"
123+ }
124+
125+ (
126+ set +x # disable the xtrace as the token would be leaked
127+ echo "Waiting for the AWS IMDS service to be available ..."
128+ SECONDS=0
129+ retry_compact check_imds_available_and_get_region
130+ echo "Took $SECONDS for the IMDS service to become available."
131+ )
132+
133+ save_secret() {
134+ name=$1
135+ key=$2
136+ dest=$3
137+
138+ # --log-driver=none avoids that the journal captures the stdout
139+ # logs of podman and leaks the passwords in the journal ...
140+ if ! podman run \
141+ --name "cloud-init-fetch-$name" \
142+ --env AWS_REGION="$(< /tmp/aws-region)" \
143+ --log-driver=none \
144+ --rm \
145+ "$AWS_CLI_IMG" \
146+ ssm get-parameter \
147+ --name "$key" \
148+ --with-decryption \
149+ --query "Parameter.Value" \
150+ --output text \
151+ > "${dest}.tmp"
152+ then
153+ rm -f "${dest}.tmp"
154+ echo "ERROR: failed to get the '$name' secret ... (fetched from $key)"
155+ return 1
156+ fi
157+ char_count=$(wc -c < "${dest}.tmp")
158+ if (( char_count < MIN_CHAR_COUNT )); then
159+ echo "ERROR: the content of the '$name' secret is too short ... (fetched from $key)"
160+ rm -f "${dest}.tmp"
161+ return 1
162+ fi
163+
164+ mv "${dest}.tmp" "${dest}" # atomic creation of the file
165+
166+ return 0
167+ }
168+
169+ # execution will abort if 'retry_compact' fails.
170+ retry_compact save_secret "pull-secrets" "$PULL_SECRETS_KEY" /opt/crc/pull-secret
171+ retry_compact save_secret "kubeadmin-pass" "$KUBEADM_PASS_KEY" /opt/crc/pass_kubeadmin
172+ retry_compact save_secret "developer-pass" "$DEVELOPER_PASS_KEY" /opt/crc/pass_developer
173+
174+ exit 0
0 commit comments