Skip to content

Commit 6f5904f

Browse files
obs-gh-nikhilduaobs-gh-alexlew
authored andcommitted
feat: add docker image tests (#51)
### Description Ticket: https://observe.atlassian.net/browse/OB-33428 - Adds docker image integration tests - Updates to support `cloud-init` for Ubuntu (debian) machine for docker purposes - Docker images are also now part of build step, for upload. They are packaged as `.tar` for each distribution to "install" on the debian machine (See https://docs.docker.com/reference/cli/docker/image/save/ & https://docs.docker.com/reference/cli/docker/image/load/) - Minor wrapper helper function for common work between windows, linux, docker ### Checklist - [x] Created tests which fail without the change (if possible) - [x] Extended the README / documentation, if necessary
1 parent bcedf51 commit 6f5904f

File tree

9 files changed

+250
-76
lines changed

9 files changed

+250
-76
lines changed

.github/workflows/tests-integration.yaml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,15 @@ jobs:
4545
args: release --prepare --clean --snapshot --verbose --parallelism 8
4646
env:
4747
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
48-
- run: ls -l && ls -l dist/
48+
- name: Save docker as .tar #Save docker images to tar
49+
run: |
50+
amd64_image=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep "amd64"| grep "observe-agent" | sort -r -k4 | head -n 1)
51+
arm64v8_image=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep "arm64v8"| grep "observe-agent" | sort -r -k4 | head -n 1)
52+
echo "amd64_image: ${amd64_image}"
53+
echo "arm64v8_image: ${arm64v8_image}"
54+
docker save -o dist/observe-agent_docker_arm64v8.tar ${arm64v8_image}
55+
docker save -o dist/observe-agent_docker_amd64.tar ${amd64_image}
56+
- run: ls -l && ls -l dist/
4957
- name: Upload build artifacts
5058
uses: actions/upload-artifact@v4
5159
with:
@@ -60,7 +68,7 @@ jobs:
6068
strategy:
6169
fail-fast: false
6270
matrix:
63-
AWS_MACHINE: ["AMAZON_LINUX_2023", "UBUNTU_22_04_LTS", "WINDOWS_SERVER_2016_BASE", "WINDOWS_SERVER_2019_BASE", "WINDOWS_SERVER_2022_BASE"]
71+
AWS_MACHINE: ["AMAZON_LINUX_2023", "UBUNTU_22_04_LTS", "WINDOWS_SERVER_2016_BASE", "WINDOWS_SERVER_2019_BASE", "WINDOWS_SERVER_2022_BASE", "DOCKER_AMD64_UBUNTU_22_04_LTS"]
6472
defaults:
6573
run:
6674
working-directory: integration #Terrafrom commands and tests are ran from integration directory

integration/modules/create_ec2/locals.tf

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ locals {
1515
architecture = "amd64"
1616
}
1717

18+
DOCKER_AMD64_UBUNTU_22_04_LTS = {
19+
# ami used in testing
20+
ami_instance_type = "t3.small"
21+
ami_id = "ami-036cafe742923b3d9"
22+
ami_description = "Used for Docker testing - Ubuntu Server 22.04 LTS (HVM)- EBS General Purpose (SSD) Volume Type. Support available from Canonical"
23+
default_user = "ubuntu"
24+
sleep = 120
25+
user_data = "user_data/aptbased_docker.sh"
26+
distribution = "docker"
27+
package_type = ".tar"
28+
architecture = "amd64"
29+
}
30+
1831
# UBUNTU_20_04_LTS = {
1932
# # ami used in testing
2033
# ami_instance_type = "t3.small"
@@ -54,7 +67,7 @@ locals {
5467
package_type = ".rpm"
5568
architecture = "x86_64"
5669
}
57-
70+
5871
# RHEL_8_4_0 = {
5972
# ami_instance_type = "t3.small"
6073
# ami_id = "ami-054965c6cd7c6e462"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
apt-get update -y
3+
apt-get install wget curl -y
4+
sudo apt-get install ca-certificates curl
5+
6+
sudo install -m 0755 -d /etc/apt/keyrings
7+
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
8+
sudo chmod a+r /etc/apt/keyrings/docker.asc
9+
10+
# Add the repository to Apt sources:
11+
echo \
12+
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
13+
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
14+
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
15+
sudo apt-get update -y
16+
17+
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
18+
sudo usermod -a -G docker $(whoami)

integration/scripts/test_configure.py

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import sys
44
import re
55
import time
6-
from utils import *
6+
import utils as u
77

8-
@print_test_decorator
9-
def run_test_windows(remote_host: Host, env_vars: dict) -> None:
8+
@u.print_test_decorator
9+
def run_test_windows(remote_host: u.Host, env_vars: dict) -> None:
1010

1111
"""
1212
Test to validate connection of observe-agent to Observe
@@ -39,8 +39,41 @@ def run_test_windows(remote_host: Host, env_vars: dict) -> None:
3939

4040
pass
4141

42-
@print_test_decorator
43-
def run_test_linux(remote_host: Host, env_vars: dict) -> None:
42+
@u.print_test_decorator
43+
def run_test_docker(remote_host: u.Host, env_vars: dict) -> None:
44+
docker_prefix='sudo docker run \
45+
--mount type=bind,source=/proc,target=/hostfs/proc,readonly \
46+
--mount type=bind,source=/snap,target=/hostfs/snap,readonly \
47+
--mount type=bind,source=/var/lib,target=/hostfs/var/lib,readonly \
48+
--mount type=bind,source=/var/log,target=/hostfs/var/log,readonly \
49+
--mount type=bind,source=/var/lib/docker/containers,target=/var/lib/docker/containers,readonly \
50+
--mount type=bind,source=$(pwd)/observe-agent.yaml,target=/etc/observe-agent/observe-agent.yaml \
51+
--pid host \
52+
$(sudo docker images --format "{{.Repository}}:{{.Tag}}" | grep SNAPSHOT)'
53+
54+
init_command='init-config --token {} --observe_url {}'.format(env_vars["observe_token"], env_vars["observe_url"])
55+
diagnose_command='diagnose'
56+
57+
#Set up correct config with observe url and token
58+
result = remote_host.run_command(docker_prefix + ' ' + init_command)
59+
60+
#Check diagnose command
61+
result = remote_host.run_command(docker_prefix + ' ' + diagnose_command)
62+
observe_val = False
63+
for line in result.stdout.splitlines():
64+
if "Request to test URL responded with response code 200" in line:
65+
print (" ✅ observe-agent -> observe validation passed! ")
66+
observe_val = True
67+
break
68+
if not observe_val:
69+
print(result)
70+
raise ValueError(f"❌ Failed: observe-agent -> observe validation")
71+
72+
73+
pass
74+
75+
@u.print_test_decorator
76+
def run_test_linux(remote_host: u.Host, env_vars: dict) -> None:
4477

4578
"""
4679
Test to validate connection of observe-agent to Observe
@@ -74,8 +107,8 @@ def run_test_linux(remote_host: Host, env_vars: dict) -> None:
74107

75108
if __name__ == '__main__':
76109

77-
env_vars = get_env_vars(need_observe=True)
78-
remote_host = Host(host_ip=env_vars["host"],
110+
env_vars = u.get_env_vars(need_observe=True)
111+
remote_host = u.Host(host_ip=env_vars["host"],
79112
username=env_vars["user"],
80113
key_file_path=env_vars["key_filename"],
81114
password=env_vars["password"])
@@ -87,6 +120,8 @@ def run_test_linux(remote_host: Host, env_vars: dict) -> None:
87120
run_test_linux(remote_host, env_vars)
88121
elif "windows" in env_vars["machine_config"]["distribution"]:
89122
run_test_windows(remote_host, env_vars)
123+
elif "docker" in env_vars["machine_config"]["distribution"]:
124+
run_test_docker(remote_host, env_vars)
90125

91126
pass
92127

integration/scripts/test_ec2_connection.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
import sys
66
import re
77
import time
8-
from utils import *
8+
import utils as u
99

10-
@print_test_decorator
11-
def run_test_windows(remote_host: Host, env_vars: dict) -> None:
10+
11+
@u.print_test_decorator
12+
def run_test_windows(remote_host: u.Host, env_vars: dict) -> None:
1213

1314
"""
1415
This test validates that the UserdataExecution.log finished successfully
@@ -58,10 +59,15 @@ def run_test_windows(remote_host: Host, env_vars: dict) -> None:
5859
time.sleep(1)
5960
raise RuntimeError("❌ The UserdataExecution file did not finish successfully in time")
6061

62+
@u.print_test_decorator
63+
def run_test_docker(remote_host: u.Host, env_vars: dict) -> None:
64+
#Since our test is being done on a linux EC2, we can just check it initializes and runs similar to linux test
65+
run_test_linux(remote_host, env_vars)
66+
pass
67+
6168

62-
63-
@print_test_decorator
64-
def run_test_linux(remote_host: Host, env_vars: dict) -> None:
69+
@u.print_test_decorator
70+
def run_test_linux(remote_host: u.Host, env_vars: dict) -> None:
6571
"""
6672
This test validates that the cloud-init file finished successfully
6773
and ec2 instance is in stable state prior to running other
@@ -94,8 +100,8 @@ def run_test_linux(remote_host: Host, env_vars: dict) -> None:
94100

95101
if __name__ == '__main__':
96102

97-
env_vars = get_env_vars()
98-
remote_host = Host(host_ip=env_vars["host"],
103+
env_vars = u.get_env_vars()
104+
remote_host = u.Host(host_ip=env_vars["host"],
99105
username=env_vars["user"],
100106
key_file_path=env_vars["key_filename"],
101107
password=env_vars["password"])
@@ -108,5 +114,5 @@ def run_test_linux(remote_host: Host, env_vars: dict) -> None:
108114
run_test_linux(remote_host, env_vars)
109115
elif "windows" in env_vars["machine_config"]["distribution"]:
110116
run_test_windows(remote_host, env_vars)
111-
112-
117+
elif "docker" in env_vars["machine_config"]["distribution"]:
118+
run_test_docker(remote_host, env_vars)

integration/scripts/test_install.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
import re
77
import time
88
import inspect
9-
from utils import *
9+
import utils as u
1010

1111

12-
13-
def get_installation_package(env_vars: dict) -> tuple:
12+
def _get_installation_package(env_vars: dict) -> tuple:
1413
"""Returns the full path and filename to the built distribution package
1514
1615
Args:
@@ -43,8 +42,8 @@ def get_installation_package(env_vars: dict) -> tuple:
4342
print(f"Found matching file {filename} at: {full_path}")
4443
return filename, full_path
4544

46-
@print_test_decorator
47-
def run_test_windows(remote_host: Host, env_vars: dict) -> None:
45+
@u.print_test_decorator
46+
def run_test_windows(remote_host: u.Host, env_vars: dict) -> None:
4847

4948
"""
5049
Test to install local observe-agent on a windows ec2 instance and validate command ran successfully
@@ -57,7 +56,7 @@ def run_test_windows(remote_host: Host, env_vars: dict) -> None:
5756
RuntimeError: Installation error in powershell script
5857
"""
5958
# Get built dist. installation package path for machine
60-
filename, full_path = get_installation_package(env_vars)
59+
filename, full_path = _get_installation_package(env_vars)
6160

6261
# Set windows home dir paths for consistency
6362
home_dir = r"/C:/Users/{}".format(env_vars["user"]) #for user in sftp
@@ -85,10 +84,24 @@ def run_test_windows(remote_host: Host, env_vars: dict) -> None:
8584
else:
8685
print("✅ Installation test passed")
8786

88-
8987

90-
@print_test_decorator
91-
def run_test_linux(remote_host: Host, env_vars: dict):
88+
@u.print_test_decorator
89+
def run_test_docker(remote_host: u.Host, env_vars: dict) -> None:
90+
91+
filename, full_path= _get_installation_package(env_vars)
92+
home_dir = "/home/{}".format(env_vars["user"])
93+
94+
remote_host.put_file(full_path, home_dir)
95+
result = remote_host.run_command('sudo docker load --input {}'.format(filename))
96+
if result.stderr:
97+
print(result)
98+
raise RuntimeError("❌ Installation error in docker load")
99+
else:
100+
print("✅ Installation test passed")
101+
102+
103+
@u.print_test_decorator
104+
def run_test_linux(remote_host: u.Host, env_vars: dict):
92105
"""
93106
Test to install local observe-agent on a linux ec2 instance and validate command ran successfully
94107
@@ -99,7 +112,7 @@ def run_test_linux(remote_host: Host, env_vars: dict):
99112
Raises:
100113
RuntimeError: Unknown distribution type passed
101114
"""
102-
filename, full_path= get_installation_package(env_vars)
115+
filename, full_path= _get_installation_package(env_vars)
103116
home_dir = "/home/{}".format(env_vars["user"])
104117

105118
remote_host.put_file(full_path, home_dir)
@@ -117,8 +130,8 @@ def run_test_linux(remote_host: Host, env_vars: dict):
117130

118131
if __name__ == '__main__':
119132

120-
env_vars = get_env_vars()
121-
remote_host = Host(host_ip=env_vars["host"],
133+
env_vars = u.get_env_vars()
134+
remote_host = u.Host(host_ip=env_vars["host"],
122135
username=env_vars["user"],
123136
key_file_path=env_vars["key_filename"],
124137
password=env_vars["password"])
@@ -130,6 +143,9 @@ def run_test_linux(remote_host: Host, env_vars: dict):
130143
run_test_linux(remote_host, env_vars)
131144
elif "windows" in env_vars["machine_config"]["distribution"]:
132145
run_test_windows(remote_host, env_vars)
146+
elif "docker" in env_vars["machine_config"]["distribution"]:
147+
run_test_docker(remote_host, env_vars)
148+
133149

134150

135151

0 commit comments

Comments
 (0)