Blame test/cases/api.sh

Packit Service 509fd4
#!/usr/bin/bash
Packit Service 509fd4
Packit Service 509fd4
#
Packit Service 509fd4
# Test osbuild-composer's main API endpoint by building a sample image and
Packit Service 509fd4
# uploading it to AWS.
Packit Service 509fd4
#
Packit Service 509fd4
# This script sets `-x` and is meant to always be run like that. This is
Packit Service 509fd4
# simpler than adding extensive error reporting, which would make this script
Packit Service 509fd4
# considerably more complex. Also, the full trace this produces is very useful
Packit Service 509fd4
# for the primary audience: developers of osbuild-composer looking at the log
Packit Service 509fd4
# from a run on a remote continuous integration system.
Packit Service 509fd4
#
Packit Service 509fd4
Packit Service 509fd4
set -euxo pipefail
Packit Service 509fd4
Packit Service 509fd4
Packit Service 509fd4
#
Packit Service 509fd4
# Provision the software under tet.
Packit Service 509fd4
#
Packit Service 509fd4
Packit Service 509fd4
/usr/libexec/osbuild-composer-test/provision.sh
Packit Service 509fd4
Packit Service 509fd4
Packit Service 509fd4
#
Packit Service 509fd4
# Verify that this script is running in the right environment. In particular,
Packit Service 509fd4
# it needs variables is set to access AWS.
Packit Service 509fd4
#
Packit Service 509fd4
Packit Service 509fd4
printenv AWS_REGION AWS_BUCKET AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_API_TEST_SHARE_ACCOUNT > /dev/null
Packit Service 509fd4
Packit Service 509fd4
Packit Service 509fd4
#
Packit Service 509fd4
# Create a temporary directory and ensure it gets deleted when this script
Packit Service 509fd4
# terminates in any way.
Packit Service 509fd4
#
Packit Service 509fd4
Packit Service 509fd4
WORKDIR=$(mktemp -d)
Packit Service bcdfb1
AMI_IMAGE_ID=
Packit Service bcdfb1
SNAPSHOT_ID=
Packit Service bcdfb1
INSTANCE_ID=
Packit Service bcdfb1
AWS_CMD=
Packit Service 509fd4
function cleanup() {
Packit Service bcdfb1
  if [ -n "$AWS_CMD" ]; then
Packit Service bcdfb1
    set +e
Packit Service bcdfb1
    $AWS_CMD ec2 terminate-instances --instance-ids "$INSTANCE_ID"
Packit Service bcdfb1
    $AWS_CMD ec2 deregister-image --image-id "$AMI_IMAGE_ID"
Packit Service bcdfb1
    $AWS_CMD ec2 delete-snapshot --snapshot-id "$SNAPSHOT_ID"
Packit Service bcdfb1
    $AWS_CMD ec2 delete-key-pair --key-name "key-for-$AMI_IMAGE_ID"
Packit Service bcdfb1
    set -e
Packit Service bcdfb1
  fi
Packit Service bcdfb1
Packit Service 509fd4
  rm -rf "$WORKDIR"
Packit Service 509fd4
}
Packit Service 509fd4
trap cleanup EXIT
Packit Service 509fd4
Packit Service 509fd4
#
Packit Service 509fd4
# Install the aws client from the upstream release, because it doesn't seem to
Packit Service 509fd4
# be available as a RHEL package.
Packit Service 509fd4
#
Packit Service 509fd4
Packit Service 509fd4
if ! hash aws; then
Packit Service 509fd4
    mkdir "$WORKDIR/aws"
Packit Service 509fd4
    pushd "$WORKDIR/aws"
Packit Service 509fd4
        curl -Ls --retry 5 --output awscliv2.zip \
Packit Service 509fd4
            https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip
Packit Service 509fd4
        unzip awscliv2.zip > /dev/null
Packit Service 509fd4
        sudo ./aws/install > /dev/null
Packit Service 509fd4
        aws --version
Packit Service 509fd4
    popd
Packit Service 509fd4
fi
Packit Service 509fd4
Packit Service 509fd4
AWS_CMD="aws --region $AWS_REGION --output json --color on"
Packit Service 509fd4
Packit Service bcdfb1
#
Packit Service bcdfb1
# Make sure /openapi.json and /version endpoints return success
Packit Service bcdfb1
#
Packit Service bcdfb1
Packit Service bcdfb1
curl \
Packit Service bcdfb1
    --silent \
Packit Service bcdfb1
    --show-error \
Packit Service bcdfb1
    --cacert /etc/osbuild-composer/ca-crt.pem \
Packit Service bcdfb1
    --key /etc/osbuild-composer/client-key.pem \
Packit Service bcdfb1
    --cert /etc/osbuild-composer/client-crt.pem \
Packit Service bcdfb1
    https://localhost/api/composer/v1/version | jq .
Packit Service bcdfb1
Packit Service bcdfb1
curl \
Packit Service bcdfb1
    --silent \
Packit Service bcdfb1
    --show-error \
Packit Service bcdfb1
    --cacert /etc/osbuild-composer/ca-crt.pem \
Packit Service bcdfb1
    --key /etc/osbuild-composer/client-key.pem \
Packit Service bcdfb1
    --cert /etc/osbuild-composer/client-crt.pem \
Packit Service bcdfb1
    https://localhost/api/composer/v1/openapi.json | jq .
Packit Service 509fd4
Packit Service 509fd4
#
Packit Service 509fd4
# Prepare a request to be sent to the composer API.
Packit Service 509fd4
#
Packit Service 509fd4
Packit Service 509fd4
REQUEST_FILE="${WORKDIR}/request.json"
Packit Service 509fd4
ARCH=$(uname -m)
Packit Service 509fd4
SNAPSHOT_NAME=$(uuidgen)
Packit Service bcdfb1
SSH_USER=
Packit Service 509fd4
Packit Service 509fd4
case $(set +x; . /etc/os-release; echo "$ID-$VERSION_ID") in
Packit Service 509fd4
  "rhel-8.4")
Packit Service 509fd4
    DISTRO="rhel-84"
Packit Service bcdfb1
    SSH_USER="cloud-user"
Packit Service 509fd4
  ;;
Packit Service 509fd4
  "rhel-8.2" | "rhel-8.3")
Packit Service 509fd4
    DISTRO="rhel-8"
Packit Service bcdfb1
    SSH_USER="cloud-user"
Packit Service 509fd4
  ;;
Packit Service 509fd4
  "fedora-32")
Packit Service 509fd4
    DISTRO="fedora-32"
Packit Service bcdfb1
    SSH_USER="fedora"
Packit Service 509fd4
  ;;
Packit Service 509fd4
  "fedora-33")
Packit Service 509fd4
    DISTRO="fedora-33"
Packit Service bcdfb1
    SSH_USER="fedora"
Packit Service bcdfb1
  ;;
Packit Service bcdfb1
  "centos-8")
Packit Service bcdfb1
    DISTRO="centos-8"
Packit Service bcdfb1
    SSH_USER="cloud-user"
Packit Service 509fd4
  ;;
Packit Service 509fd4
esac
Packit Service 509fd4
Packit Service 509fd4
cat > "$REQUEST_FILE" << EOF
Packit Service 509fd4
{
Packit Service 509fd4
  "distribution": "$DISTRO",
Packit Service bcdfb1
  "customizations": {
Packit Service bcdfb1
    "packages": [
Packit Service bcdfb1
      "postgresql"
Packit Service bcdfb1
    ]
Packit Service bcdfb1
  },
Packit Service 509fd4
  "image_requests": [
Packit Service 509fd4
    {
Packit Service 509fd4
      "architecture": "$ARCH",
Packit Service 509fd4
      "image_type": "ami",
Packit Service 509fd4
      "repositories": $(jq ".\"$ARCH\"" /usr/share/tests/osbuild-composer/repositories/"$DISTRO".json),
Packit Service 509fd4
      "upload_requests": [
Packit Service 509fd4
        {
Packit Service 509fd4
          "type": "aws",
Packit Service 509fd4
          "options": {
Packit Service 509fd4
            "region": "${AWS_REGION}",
Packit Service 509fd4
            "s3": {
Packit Service 509fd4
              "access_key_id": "${AWS_ACCESS_KEY_ID}",
Packit Service 509fd4
              "secret_access_key": "${AWS_SECRET_ACCESS_KEY}",
Packit Service 509fd4
              "bucket": "${AWS_BUCKET}"
Packit Service 509fd4
            },
Packit Service 509fd4
            "ec2": {
Packit Service 509fd4
              "access_key_id": "${AWS_ACCESS_KEY_ID}",
Packit Service 509fd4
              "secret_access_key": "${AWS_SECRET_ACCESS_KEY}",
Packit Service 509fd4
              "snapshot_name": "${SNAPSHOT_NAME}",
Packit Service 509fd4
              "share_with_accounts": ["${AWS_API_TEST_SHARE_ACCOUNT}"]
Packit Service 509fd4
            }
Packit Service 509fd4
          }
Packit Service 509fd4
        }
Packit Service 509fd4
      ]
Packit Service 509fd4
    }
Packit Service 509fd4
  ]
Packit Service 509fd4
}
Packit Service 509fd4
EOF
Packit Service 509fd4
Packit Service 509fd4
Packit Service 509fd4
#
Packit Service 509fd4
# Send the request and wait for the job to finish.
Packit Service 509fd4
#
Packit Service 509fd4
# Separate `curl` and `jq` commands here, because piping them together hides
Packit Service 509fd4
# the server's response in case of an error.
Packit Service 509fd4
#
Packit Service 509fd4
Packit Service 509fd4
OUTPUT=$(curl \
Packit Service 509fd4
  --silent \
Packit Service 509fd4
  --show-error \
Packit Service 509fd4
  --cacert /etc/osbuild-composer/ca-crt.pem \
Packit Service 509fd4
  --key /etc/osbuild-composer/client-key.pem \
Packit Service 509fd4
  --cert /etc/osbuild-composer/client-crt.pem \
Packit Service 509fd4
  --header 'Content-Type: application/json' \
Packit Service 509fd4
  --request POST \
Packit Service 509fd4
  --data @"$REQUEST_FILE" \
Packit Service 509fd4
  https://localhost/api/composer/v1/compose)
Packit Service 509fd4
Packit Service 509fd4
COMPOSE_ID=$(echo "$OUTPUT" | jq -r '.id')
Packit Service 509fd4
Packit Service 509fd4
while true
Packit Service 509fd4
do
Packit Service 509fd4
  OUTPUT=$(curl \
Packit Service 509fd4
    --silent \
Packit Service 509fd4
    --show-error \
Packit Service 509fd4
    --cacert /etc/osbuild-composer/ca-crt.pem \
Packit Service 509fd4
    --key /etc/osbuild-composer/client-key.pem \
Packit Service 509fd4
    --cert /etc/osbuild-composer/client-crt.pem \
Packit Service 509fd4
    https://localhost/api/composer/v1/compose/"$COMPOSE_ID")
Packit Service 509fd4
Packit Service bcdfb1
  COMPOSE_STATUS=$(echo "$OUTPUT" | jq -r '.image_status.status')
Packit Service bcdfb1
  UPLOAD_STATUS=$(echo "$OUTPUT" | jq -r '.image_status.upload_status.status')
Packit Service bcdfb1
  UPLOAD_TYPE=$(echo "$OUTPUT" | jq -r '.image_status.upload_status.type')
Packit Service 509fd4
Packit Service 509fd4
  if [[ "$COMPOSE_STATUS" != "pending" && "$COMPOSE_STATUS" != "running" ]]; then
Packit Service 509fd4
    test "$COMPOSE_STATUS" = "success"
Packit Service bcdfb1
    test "$UPLOAD_STATUS" = "success"
Packit Service bcdfb1
    test "$UPLOAD_TYPE" = "aws"
Packit Service 509fd4
    break
Packit Service 509fd4
  fi
Packit Service 509fd4
Packit Service 509fd4
  sleep 30
Packit Service 509fd4
done
Packit Service 509fd4
Packit Service 509fd4
Packit Service 509fd4
#
Packit Service 509fd4
# Verify the image landed in EC2, and delete it.
Packit Service 509fd4
#
Packit Service 509fd4
Packit Service 509fd4
$AWS_CMD ec2 describe-images \
Packit Service 509fd4
    --owners self \
Packit Service 509fd4
    --filters Name=name,Values="$SNAPSHOT_NAME" \
Packit Service 509fd4
    > "$WORKDIR/ami.json"
Packit Service 509fd4
Packit Service 509fd4
AMI_IMAGE_ID=$(jq -r '.Images[].ImageId' "$WORKDIR/ami.json")
Packit Service 509fd4
SNAPSHOT_ID=$(jq -r '.Images[].BlockDeviceMappings[].Ebs.SnapshotId' "$WORKDIR/ami.json")
Packit Service 509fd4
SHARE_OK=1
Packit Service 509fd4
Packit Service 509fd4
# Verify that the ec2 snapshot was shared
Packit Service 509fd4
$AWS_CMD ec2 describe-snapshot-attribute --snapshot-id "$SNAPSHOT_ID" --attribute createVolumePermission > "$WORKDIR/snapshot-attributes.json"
Packit Service 509fd4
Packit Service 509fd4
SHARED_ID=$(jq -r '.CreateVolumePermissions[0].UserId' "$WORKDIR/snapshot-attributes.json")
Packit Service 509fd4
if [ "$AWS_API_TEST_SHARE_ACCOUNT" != "$SHARED_ID" ]; then
Packit Service 509fd4
    SHARE_OK=0
Packit Service 509fd4
fi
Packit Service 509fd4
Packit Service 509fd4
# Verify that the ec2 ami was shared
Packit Service 509fd4
$AWS_CMD ec2 describe-image-attribute --image-id "$AMI_IMAGE_ID" --attribute launchPermission > "$WORKDIR/ami-attributes.json"
Packit Service 509fd4
Packit Service 509fd4
SHARED_ID=$(jq -r '.LaunchPermissions[0].UserId' "$WORKDIR/ami-attributes.json")
Packit Service 509fd4
if [ "$AWS_API_TEST_SHARE_ACCOUNT" != "$SHARED_ID" ]; then
Packit Service 509fd4
    SHARE_OK=0
Packit Service 509fd4
fi
Packit Service 509fd4
Packit Service bcdfb1
# Create key-pair
Packit Service bcdfb1
$AWS_CMD ec2 create-key-pair --key-name "key-for-$AMI_IMAGE_ID" --query 'KeyMaterial' --output text > keypair.pem
Packit Service bcdfb1
chmod 400 ./keypair.pem
Packit Service bcdfb1
Packit Service bcdfb1
# Create an instance based on the ami
Packit Service bcdfb1
$AWS_CMD ec2 run-instances --image-id "$AMI_IMAGE_ID" --count 1 --instance-type t2.micro --key-name "key-for-$AMI_IMAGE_ID" > "$WORKDIR/instances.json"
Packit Service bcdfb1
INSTANCE_ID=$(jq -r '.Instances[].InstanceId' "$WORKDIR/instances.json")
Packit Service bcdfb1
Packit Service bcdfb1
$AWS_CMD ec2 wait instance-running --instance-ids "$INSTANCE_ID"
Packit Service bcdfb1
Packit Service bcdfb1
$AWS_CMD ec2 describe-instances --instance-ids "$INSTANCE_ID" > "$WORKDIR/instances.json"
Packit Service bcdfb1
HOST=$(jq -r '.Reservations[].Instances[].PublicIpAddress' "$WORKDIR/instances.json")
Packit Service bcdfb1
Packit Service bcdfb1
echo "⏱ Waiting for AWS instance to respond to ssh"
Packit Service bcdfb1
for LOOP_COUNTER in {0..30}; do
Packit Service bcdfb1
    if ssh-keyscan "$HOST" > /dev/null 2>&1; then
Packit Service bcdfb1
        echo "SSH is up!"
Packit Service bcdfb1
        # ssh-keyscan "$PUBLIC_IP" | sudo tee -a /root/.ssh/known_hosts
Packit Service bcdfb1
        break
Packit Service bcdfb1
    fi
Packit Service bcdfb1
    echo "Retrying in 5 seconds... $LOOP_COUNTER"
Packit Service bcdfb1
    sleep 5
Packit Service bcdfb1
done
Packit Service bcdfb1
Packit Service bcdfb1
# Check if postgres is installed
Packit Service bcdfb1
ssh -oStrictHostKeyChecking=no -i ./keypair.pem "$SSH_USER"@"$HOST" rpm -q postgresql
Packit Service 509fd4
Packit Service 509fd4
if [ "$SHARE_OK" != 1 ]; then
Packit Service 509fd4
    echo "EC2 snapshot wasn't shared with the AWS_API_TEST_SHARE_ACCOUNT. 😢"
Packit Service 509fd4
    exit 1
Packit Service 509fd4
fi
Packit Service 509fd4
Packit Service 509fd4
exit 0