Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CLIENT-3027] CI/CD: Use Dockerfile to build Docker image for Aerospike enterprise server with security enabled #645

Merged
merged 32 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
923c354
test using admin user
juliannguyen4 Jul 8, 2024
4cf803f
Merge remote-tracking branch 'origin/dev' into CLIENT-3027-cicd-build…
juliannguyen4 Jul 9, 2024
d4470cc
Use Dockerfile
juliannguyen4 Jul 9, 2024
52c309a
wip--broken
juliannguyen4 Jul 9, 2024
30caee1
build w/out cache
juliannguyen4 Jul 9, 2024
60bc9c4
add shell
juliannguyen4 Jul 9, 2024
cfe84e5
Right path to Dockerfile
juliannguyen4 Jul 9, 2024
b78bddb
Fix
juliannguyen4 Jul 9, 2024
7271895
Repo already cloned
juliannguyen4 Jul 9, 2024
fd1a5d4
Add print stmt
juliannguyen4 Jul 10, 2024
11c0245
add
juliannguyen4 Jul 10, 2024
432be27
check
juliannguyen4 Jul 10, 2024
1c681cb
whoops
juliannguyen4 Jul 10, 2024
5a345c9
Inspect docker container
juliannguyen4 Jul 11, 2024
bc7be56
Check cluster-stable state
juliannguyen4 Jul 12, 2024
7218d7a
Show state of cluster using asadm
juliannguyen4 Jul 12, 2024
30527b3
Also check cluster-stable
juliannguyen4 Jul 12, 2024
d3ca020
Change log msgs to make more sense
juliannguyen4 Jul 12, 2024
458a199
See if race condition happens with CE tests
juliannguyen4 Jul 12, 2024
22e1fdf
Assume we didn't wait for server to stabilize
juliannguyen4 Jul 12, 2024
ba2c995
Minimize time to prepare tests
juliannguyen4 Jul 12, 2024
b4a8061
Does the issue go away if we check for stability
juliannguyen4 Jul 12, 2024
142ddd9
Create user using security.smd
juliannguyen4 Jul 15, 2024
8eeb359
Fix
juliannguyen4 Jul 15, 2024
99e6950
Clarify why second check is needed
juliannguyen4 Jul 15, 2024
78f455c
cleanup
juliannguyen4 Jul 16, 2024
012aabe
Merge remote-tracking branch 'origin/dev' into CLIENT-3027-cicd-build…
juliannguyen4 Jul 16, 2024
b15d4c4
install buildx on macos
juliannguyen4 Jul 16, 2024
1bf8ff1
Fix syntax
juliannguyen4 Jul 16, 2024
f8f5a61
Add comments
juliannguyen4 Jul 16, 2024
5da791c
Fix comment
juliannguyen4 Jul 16, 2024
e2e6d39
Add warning
juliannguyen4 Jul 16, 2024
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
58 changes: 17 additions & 41 deletions .github/actions/run-ee-server/action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
name: 'Run EE Server'
description: 'Run EE server. Returns once server is ready. Only tested on Linux and macOS'
# NOTE: do not share this server container with others
# since it's using the default admin / admin credentials
inputs:
# All inputs in composite actions are strings
use-server-rc:
Expand Down Expand Up @@ -43,61 +45,35 @@ runs:
run: mkdir configs
shell: bash

- name: Use release server
if: ${{ inputs.use-server-rc == 'false' }}
run: echo "SERVER_IMAGE=aerospike/aerospike-server-enterprise" >> $GITHUB_ENV
shell: bash

- name: Use release candidate server
if: ${{ inputs.use-server-rc == 'true' }}
run: echo "SERVER_IMAGE=aerospike/aerospike-server-enterprise-rc" >> $GITHUB_ENV
shell: bash

- name: Log into Docker Hub to get server RC
if: ${{ inputs.use-server-rc == 'true' }}
run: docker login --username ${{ inputs.docker-hub-username }} --password ${{ inputs.docker-hub-password }}
shell: bash

- run: docker run -d --name aerospike -p 3000:3000 $SERVER_IMAGE:${{ inputs.server-tag }}
- run: echo IMAGE_NAME=aerospike/aerospike-server-enterprise${{ inputs.use-server-rc == 'true' && '-rc' || '' }}:${{ inputs.server-tag }} >> $GITHUB_ENV
shell: bash

- uses: ./.github/actions/wait-for-as-server-to-start
id: wait-for-server1
with:
container-name: aerospike
is-security-enabled: false

- name: Get default aerospike.conf from Docker server EE container
run: |
docker cp aerospike:/etc/aerospike/aerospike.conf ./configs/aerospike.conf
docker container stop aerospike
docker container rm aerospike
- run: echo SECURITY_IMAGE_NAME=${{ env.IMAGE_NAME }}-security >> $GITHUB_ENV
shell: bash

- name: Enable security features using aerospike.conf
# Security stanza
run: echo -e "security {\n\tenable-quotas true\n}\n" >> ./aerospike.conf
working-directory: ./configs
# macOS Github runners don't have Docker by default
- if: ${{ runner.os == 'macOS' }}
run: brew install docker-buildx
shell: bash

- name: Run enterprise edition server
run: docker run -tid -v $(pwd)/configs:/opt/aerospike/etc -p 3000:3000 --name aerospike $SERVER_IMAGE:${{ inputs.server-tag }} asd --config-file /opt/aerospike/etc/aerospike.conf
- name: Build and push
uses: docker/build-push-action@v6
with:
# Don't want to use default Git context or else it will clone the whole Python client repo again
context: .github/workflows
build-args: |
image=${{ env.IMAGE_NAME }}
tags: ${{ env.SECURITY_IMAGE_NAME }}

- run: docker run -d --name aerospike -p 3000:3000 ${{ env.SECURITY_IMAGE_NAME }}
shell: bash

- uses: ./.github/actions/wait-for-as-server-to-start
id: wait-for-server2
with:
container-name: aerospike
is-security-enabled: true

# Enabling debug logging for workflow runs doesn't show container logs
# So we need this step for now
- if: ${{ !cancelled() && (steps.wait-for-server1.outcome == 'failure' || steps.wait-for-server2.outcome == 'failure') }}
name: Print logs to help debug why the server failed to start up
run: docker container logs aerospike
shell: bash

- name: Create user in database for tests
# Use default admin user to create another user for testing
run: docker exec aerospike asadm --user admin --password admin --enable -e "manage acl create user superuser password superuser roles read-write-udf sys-admin user-admin data-admin"
shell: bash
2 changes: 1 addition & 1 deletion .github/actions/wait-for-as-server-to-start/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ runs:
# Also, we don't want to fail if we timeout in case the server *did* finish starting up but the script couldn't detect it due to a bug
# Effectively, this composite action is like calling "sleep" that is optimized to exit early when it detects an ok from the server
- name: Wait for EE server to start
run: timeout 5 bash ./.github/workflows/wait-for-as-server-to-start.bash ${{ inputs.container-name }} ${{ inputs.is-security-enabled }} || true
run: timeout 30 bash ./.github/workflows/wait-for-as-server-to-start.bash ${{ inputs.container-name }} ${{ inputs.is-security-enabled }} || true
shell: bash
10 changes: 10 additions & 0 deletions .github/workflows/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ARG image
FROM $image
RUN echo -e "security {\n\tenable-quotas true\n}\n" >> /etc/aerospike/aerospike.template.conf
# security.smd was generated manually by
# 1. Starting a new Aerospike EE server using Docker
# 2. Creating the superuser user
# 3. Copying /opt/aerospike/smd/security.smd from the container and committing it to this repo
# This file should always work
# TODO: generate this automatically, somehow
COPY security.smd /opt/aerospike/smd/
48 changes: 48 additions & 0 deletions .github/workflows/security.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[
[
162276881999406,
14
],
{
"key": "admin|P",
"value": "$2a$10$7EqJtq98hPqEX7fNZaFWoO1mVO/4MLpGzsqojz6E9Gef6iXDjXdDa",
"generation": 1,
"timestamp": 0
},
{
"key": "admin|R|user-admin",
"value": "",
"generation": 1,
"timestamp": 0
},
{
"key": "superuser|P",
"value": "$2a$10$7EqJtq98hPqEX7fNZaFWoOZX0o4mZCBUwvzt/iecIcG4JaDOC41zK",
"generation": 3,
"timestamp": 458774922440
},
{
"key": "superuser|R|read-write-udf",
"value": "",
"generation": 3,
"timestamp": 458774922441
},
{
"key": "superuser|R|sys-admin",
"value": "",
"generation": 3,
"timestamp": 458774922442
},
{
"key": "superuser|R|user-admin",
"value": "",
"generation": 3,
"timestamp": 458774922442
},
{
"key": "superuser|R|data-admin",
"value": null,
"generation": 2,
"timestamp": 458774718056
}
]
30 changes: 24 additions & 6 deletions .github/workflows/wait-for-as-server-to-start.bash
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ set -o pipefail
container_name=$1
is_security_enabled=$2

while true; do
if [[ $is_security_enabled == true ]]; then
# We need to pass credentials to asinfo if server requires it
# TODO: passing in hardcoded credentials since I can't figure out how to use --instance with global astools.conf
user_credentials="--user=admin --password=admin"
fi
if [[ $is_security_enabled == true ]]; then
# We need to pass credentials to asinfo if server requires it
# TODO: passing in credentials via command line flags since I can't figure out how to use --instance with global astools.conf
user_credentials="--user=admin --password=admin"
Copy link
Contributor

Choose a reason for hiding this comment

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

store the user and password credentials in a github secret

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the default credentials for the Aerospike EE server with security enabled. I don't think using secrets here is necessary unless we change those credentials

fi

while true; do
# An unset variable will have a default empty value
# Intermediate step is to print docker exec command's output in case it fails
# Sometimes, errors only appear in stdout and not stderr, like if asinfo throws an error because of no credentials
Expand All @@ -22,8 +22,26 @@ while true; do
# grep doesn't have a way to print all lines passed as input.
# ack does have an option but it doesn't come installed by default
# shellcheck disable=SC2086 # The flags in user credentials should be separate anyways. Not one string
echo "Checking if we can reach the server via the service port..."
if docker exec "$container_name" asinfo $user_credentials -v status | tee >(cat) | grep -qE "^ok"; then
# Server is ready when asinfo returns ok
echo "Can reach server now."
# docker container inspect "$container_name"
break
fi

echo "Server didn't return ok via the service port. Polling again..."
done

# Although the server may be reachable via the service port, the cluster may not be fully initialized yet.
# If we try to connect too soon (e.g right after "status" returns ok), the client may throw error code -1
while true; do
echo "Waiting for server to stabilize (i.e return a cluster key)..."
# We assume that when an ERROR is returned, the cluster is not stable yet (i.e not fully initialized)
if docker exec "$container_name" asinfo $user_credentials -v cluster-stable 2>&1 | (! grep -qE "^ERROR"); then
echo "Server is in a stable state."
break
fi

echo "Server did not return a cluster key. Polling again..."
done
Loading