Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 151 additions & 13 deletions pkg/provider/aws/action/openshift-snc/cloud-config
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
#cloud-config
bootcmd:
- 'echo "bootcmd executed by service: $(ps -o comm= $PPID)" > /tmp/bootcmd_proof.txt'
# Resize the partition (4 = /dev/nvme0n1p4 typically)
- growpart /dev/nvme0n1 4
# Resize the XFS filesystem on /sysroot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it was resized some how... AFAIK the disk was over the original 32 / 42 snc image disk size no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this part (the disk resize), we'll have to rethink it, this part was broken, and another script was broken
I think we'll try to let cloud-init handle it all

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok that is pretty important...as with 34G and not resize to requested disk size... users can not use it..actually we already hit that issue and this is why we introduced this here

- xfs_growfs /sysroot
runcmd:
- 'echo "runcmd executed by service: $(ps -o comm= $PPID)" > /tmp/runcmd_proof.txt'
- systemctl enable --now kubelet
- export PS=$(podman run --rm docker.io/amazon/aws-cli ssm get-parameter --name "{{ .SSMPullSecretName }}" --with-decryption --query "Parameter.Value" --output text)
- echo ${PS} > /opt/crc/pull-secret
- chmod 0644 /opt/crc/pull-secret
- export KP=$(podman run --rm docker.io/amazon/aws-cli ssm get-parameter --name "{{ .SSMKubeAdminPasswordName }}" --with-decryption --query "Parameter.Value" --output text)
- echo ${KP} > /opt/crc/pass_kubeadmin
- chmod 0644 /opt/crc/pass_kubeadmin
- export DV=$(podman run --rm docker.io/amazon/aws-cli ssm get-parameter --name "{{ .SSMDeveloperPasswordName }}" --with-decryption --query "Parameter.Value" --output text)
- echo ${DV} > /opt/crc/pass_developer
- chmod 0644 /opt/crc/pass_developer
- echo "{{ .PublicIP }}" > /opt/crc/eip
- chmod 0644 /opt/crc/eip
- /usr/local/bin/mapt-crc-aws-fetch-secrets-workaround.sh
write_files:
- path: /opt/crc/eip
content: "{{ .PublicIP }}"
owner: root:root
permissions: '0644'
- path: /home/core/.ssh/authorized_keys
content: {{ .PubKey }}
owner: {{ .Username }}
Expand All @@ -29,6 +23,150 @@ write_files:
- content: |
CRC_SELF_SUFFICIENT=1
CRC_NETWORK_MODE_USER=0
CRC_SOURCE=mapt/snc
owner: root:root
path: /etc/sysconfig/crc-env
permissions: '0644'
- owner: root:root
path: /usr/local/bin/mapt-crc-aws-fetch-secrets-workaround.sh
permissions: '0755'
content: |
#!/bin/bash
if [[ -f /usr/local/bin/crc-aws-fetch-secrets.sh ]]; then
script=/usr/local/bin/crc-aws-fetch-secrets.sh
else
echo "crc-aws-fetch-secrets.sh not found, falling back to MAPT's copy"
script=/usr/local/bin/mapt-crc-aws-fetch-secrets.sh
fi

exec "$script" "{{ .SSMPullSecretName }}" "{{ .SSMKubeAdminPasswordName }}" "{{ .SSMDeveloperPasswordName }}"
- owner: root:root
path: /usr/local/bin/mapt-crc-aws-fetch-secrets.sh
permissions: '0755'
content: |
#!/bin/bash

set -o pipefail
set -o errexit
set -o nounset
set -o errtrace
set -x

# set -x is safe, the secrets are passed via stdin

AWS_CLI_IMG=docker.io/amazon/aws-cli
MIN_CHAR_COUNT=8 # minimum number of chars for the secret to be
# assumed valid

umask 0077 # 0600 file permission for secrets

PULL_SECRETS_KEY=${1:-}
KUBEADM_PASS_KEY=${2:-}
DEVELOPER_PASS_KEY=${3:-}

if [[ -z "$PULL_SECRETS_KEY" || -z "$KUBEADM_PASS_KEY" || -z "$DEVELOPER_PASS_KEY" ]]; then
echo "ERROR: expected to receive 3 parameters: PULL_SECRETS_KEY KUBEADM_PASS_KEY DEVELOPER_PASS_KEY"
exit 1
fi

SECONDS=0
podman pull --quiet "$AWS_CLI_IMG"
echo "Took $SECONDS seconds to pull the $AWS_CLI_IMG"

wait_imds_available_and_get_region() {
total_timeout_minutes=5
retry_interval_seconds=5

IMDS_TOKEN_COMMAND=(
curl
--connect-timeout 1
-X PUT
"http://169.254.169.254/latest/api/token"
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
-Ssf
)
success=false
deadline=$(( $(date +%s) + (total_timeout_minutes * 60) ))
while [[ $(date +%s) -lt $deadline ]]; do
# By placing the command in an 'if' condition, we can test its exit code
# without triggering 'set -e'. The output is still captured.
if TOKEN=$("${IMDS_TOKEN_COMMAND[@]}"); then
# This block only runs if the curl command succeeds (exit code 0)
success=true
echo "Successfully fetched token." >&2
break # Exit the loop on success
fi

# This block runs if the curl command fails
echo "Failed to connect. Retrying in $retry_interval_seconds seconds..." >&2
sleep "$retry_interval_seconds"
done

if [[ "$success" != "true" ]]; then
echo "ERROR: Could not fetch token after $total_timeout_minutes minutes." >&2
return 1
fi

# Then, use the token to get the region
echo "Fetching the AWS region ..."
curl -Ssf -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/region > /tmp/aws-region
echo >> /tmp/aws-region # add EOL at EOF, for consistency
echo "AWS region: $(< /tmp/aws-region)"
}

(
set +x # disable the xtrace as the token would be leaked
echo "Waiting for the AWS IMDS service to be available ..."
SECONDS=0
wait_imds_available_and_get_region
echo "Took $SECONDS for the IMDS service to become available."
)

missing_secrets=0

save_secret() {
name=$1
key=$2
dest=$3

# --log-driver=none avoids that the journal captures the stdout
# logs of podman and leaks the passwords in the journal ...
if ! podman run \
--name "cloud-init-fetch-$name" \
--env AWS_REGION="$(< /tmp/aws-region)" \
--log-driver=none \
--rm \
"$AWS_CLI_IMG" \
ssm get-parameter \
--name "$key" \
--with-decryption \
--query "Parameter.Value" \
--output text \
> "${dest}.tmp"
then
rm -f "${dest}.tmp"
echo "ERROR: failed to get the '$name' secret ... (fetched from $key)"
((missing_secrets += 1))
return
fi
char_count=$(wc -c < "${dest}.tmp")
if (( char_count < MIN_CHAR_COUNT )); then
echo "ERROR: the content of the '$name' secret is too short ... (fetched from $key)"
rm -f "${dest}.tmp"
((missing_secrets += 1))
return
fi

mv "${dest}.tmp" "${dest}" # atomic creation of the file
}

save_secret "pull-secrets" "$PULL_SECRETS_KEY" /opt/crc/pull-secret
save_secret "kubeadmin-pass" "$KUBEADM_PASS_KEY" /opt/crc/pass_kubeadmin
save_secret "developer-pass" "$DEVELOPER_PASS_KEY" /opt/crc/pass_developer

if (( missing_secrets != 0 )); then
echo "ERROR: failed to fetch $missing_secrets secrets ..."
exit 1
fi

exit 0
126 changes: 126 additions & 0 deletions pkg/provider/aws/action/openshift-snc/mapt-crc-aws-fetch-secrets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/bin/bash

set -o pipefail
set -o errexit
set -o nounset
set -o errtrace
set -x

# set -x is safe, the secrets are passed via stdin

AWS_CLI_IMG=docker.io/amazon/aws-cli
MIN_CHAR_COUNT=8 # minimum number of chars for the secret to be
# assumed valid

umask 0077 # 0600 file permission for secrets

PULL_SECRETS_KEY=${1:-}
KUBEADM_PASS_KEY=${2:-}
DEVELOPER_PASS_KEY=${3:-}

if [[ -z "$PULL_SECRETS_KEY" || -z "$KUBEADM_PASS_KEY" || -z "$DEVELOPER_PASS_KEY" ]]; then
echo "ERROR: expected to receive 3 parameters: PULL_SECRETS_KEY KUBEADM_PASS_KEY DEVELOPER_PASS_KEY"
exit 1
fi

SECONDS=0
podman pull --quiet "$AWS_CLI_IMG"
echo "Took $SECONDS seconds to pull the $AWS_CLI_IMG"

wait_imds_available_and_get_region() {
total_timeout_minutes=5
retry_interval_seconds=5

IMDS_TOKEN_COMMAND=(
curl
--connect-timeout 1
-X PUT
"http://169.254.169.254/latest/api/token"
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
-Ssf
)
success=false
deadline=$(( $(date +%s) + (total_timeout_minutes * 60) ))
while [[ $(date +%s) -lt $deadline ]]; do
# By placing the command in an 'if' condition, we can test its exit code
# without triggering 'set -e'. The output is still captured.
if TOKEN=$("${IMDS_TOKEN_COMMAND[@]}"); then
# This block only runs if the curl command succeeds (exit code 0)
success=true
echo "Successfully fetched token." >&2
break # Exit the loop on success
fi

# This block runs if the curl command fails
echo "Failed to connect. Retrying in $retry_interval_seconds seconds..." >&2
sleep "$retry_interval_seconds"
done

if [[ "$success" != "true" ]]; then
echo "ERROR: Could not fetch token after $total_timeout_minutes minutes." >&2
return 1
fi

# Then, use the token to get the region
echo "Fetching the AWS region ..."
curl -Ssf -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/region > /tmp/aws-region
echo >> /tmp/aws-region # add EOL at EOF, for consistency
echo "AWS region: $(< /tmp/aws-region)"
}

(
set +x # disable the xtrace as the token would be leaked
echo "Waiting for the AWS IMDS service to be available ..."
SECONDS=0
wait_imds_available_and_get_region
echo "Took $SECONDS for the IMDS service to become available."
)

missing_secrets=0

save_secret() {
name=$1
key=$2
dest=$3

# --log-driver=none avoids that the journal captures the stdout
# logs of podman and leaks the passwords in the journal ...
if ! podman run \
--name "cloud-init-fetch-$name" \
--env AWS_REGION="$(< /tmp/aws-region)" \
--log-driver=none \
--rm \
"$AWS_CLI_IMG" \
ssm get-parameter \
--name "$key" \
--with-decryption \
--query "Parameter.Value" \
--output text \
> "${dest}.tmp"
then
rm -f "${dest}.tmp"
echo "ERROR: failed to get the '$name' secret ... (fetched from $key)"
((missing_secrets += 1))
return
fi
char_count=$(wc -c < "${dest}.tmp")
if (( char_count < MIN_CHAR_COUNT )); then
echo "ERROR: the content of the '$name' secret is too short ... (fetched from $key)"
rm -f "${dest}.tmp"
((missing_secrets += 1))
return
fi

mv "${dest}.tmp" "${dest}" # atomic creation of the file
}

save_secret "pull-secrets" "$PULL_SECRETS_KEY" /opt/crc/pull-secret
save_secret "kubeadmin-pass" "$KUBEADM_PASS_KEY" /opt/crc/pass_kubeadmin
save_secret "developer-pass" "$DEVELOPER_PASS_KEY" /opt/crc/pass_developer

if (( missing_secrets != 0 )); then
echo "ERROR: failed to fetch $missing_secrets secrets ..."
exit 1
fi

exit 0