Skip to content

Commit 3088aeb

Browse files
Update the midstream scripts and Dockerfile
1 parent f817799 commit 3088aeb

File tree

6 files changed

+94
-138
lines changed

6 files changed

+94
-138
lines changed

.github/workflows/build_and_test_midstream_image.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,4 @@ jobs:
3434
- name: "Run unit tests"
3535
continue-on-error: false
3636
run: |
37-
podman run --entrypoint fix_etc_passwd_k8s.sh --user=3159:0 -e HOME=/var/tmp --workdir=/tmp/ -e IMAGE_TO_TEST=quay.io/cvpops/test-operator:v1.0-16 midstream_image:latest
38-
podman run -t --entrypoint /usr/bin/unit_tests.py midstream_image:latest
37+
podman run --rm -ti --user=3149:0 midstream_image:latest unit_tests.py -vvv

Dockerfiles/midstream/Dockerfile

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ ARG OPERATOR_SDK_VERSION=v1.9.0
33
ARG UMOCI_VERSION=v0.4.5
44
ENV ANSIBLE_CONFIG=/project/operator-test-playbooks/Dockerfiles/midstream/
55
ENV ANSIBLE_LOCAL_TEMP=/tmp/
6-
ENV PATH="/operator-test-playbooks/Dockerfiles/midstream/:${PATH}"
76
ADD extract-operator-bundle.yml validate-operator-bundle.yml /project/operator-test-playbooks/
87
RUN export ARCH=$(case $(arch) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; *) echo -n $(arch) ;; esac);\
98
export OS=$(uname | awk '{print tolower($0)}');\
@@ -13,12 +12,9 @@ RUN export ARCH=$(case $(arch) in x86_64) echo -n amd64 ;; aarch64) echo -n arm6
1312
curl -fL -o /usr/local/bin/umoci https://github.com/opencontainers/umoci/releases/download/${UMOCI_VERSION}/umoci.amd64 && \
1413
chmod a+x /usr/local/bin/umoci && \
1514
chmod g+w /etc/passwd && \
16-
chmod -R 777 /project/ && \
1715
dnf install --setopt=install_weak_deps=False -y git-core ansible skopeo && \
1816
dnf clean all
19-
ADD ./Dockerfiles/midstream/fix_etc_passwd_k8s.sh ./Dockerfiles/midstream/run_tests.py ./Dockerfiles/midstream/unit_tests.py ./Dockerfiles/midstream/fix_etc_passwd.sh /usr/bin/
17+
ADD ./Dockerfiles/midstream/run_tests.py ./Dockerfiles/midstream/unit_tests.py ./Dockerfiles/midstream/fix_etc_passwd.sh /usr/bin/
2018
ADD roles /project/operator-test-playbooks/roles/
21-
ADD extract-operator-bundle.yml validate-operator-bundle.yml /project/operator-test-playbooks/
2219
ADD ./Dockerfiles/midstream/ansible.cfg /project/operator-test-playbooks/
23-
WORKDIR /project/
24-
ENTRYPOINT ["/usr/bin/fix_etc_passwd.sh"]
20+
WORKDIR /var/tmp

Dockerfiles/midstream/fix_etc_passwd.sh

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,33 @@
11
#!/usr/bin/bash -e
2-
# WARNING: Please do not modify;
3-
# current behaviour of this script
4-
# Directly impacts Midstream effort.
52

63
main() {
74
local username="${SSH_AUTH_USER:-default}"
85
local home
96
home=$(mk_home "$username")
107
setup_passwd "$username" "$home"
11-
if [ "$#" -eq 0 ]; then
12-
echo "Running inside a openshift environment \n
13-
No arguments to script detected.\n
14-
sleeping indefintely."
15-
exec sleep inf
16-
fi
178
}
189

1910
mk_home() {
2011
local username="${1:?}"
21-
[[ -d /workDir ]] && [[ -w /workDir ]] && \
22-
mkdir -p "/workDir/home/$username" && \
23-
echo "/workDir/home/$username" && \
24-
return 0
12+
mkdir -p "/tmp/home/$username" && \
13+
echo "/tmp/home/$username" && \
14+
return 0
2515
mktemp --tmpdir -d "${username}.XXXXXX"
2616
}
2717

2818
setup_passwd() {
2919
local username="${1:?}"
3020
local home="${2:?}"
31-
local uid="$3"
32-
local gid="${4:-0}"
21+
local uid="$(id -u)"
22+
local gid="${3:-0}"
3323
local passwd=/etc/passwd
34-
! whoami 2>/dev/null || return 0
24+
25+
# do not change anything if user exists
26+
getent passwd $uid 2>/dev/null >/dev/null && return 0
3527
if ! [[ -w "$passwd" ]]; then
3628
echo "There is no permission to add user $username to $passwd"
37-
return 0
29+
return 1
3830
fi
39-
[[ "$uid" ]] || uid="$(id -u)"
4031
echo \
4132
"${username}:x:${uid}:${gid}:Default Application User:${home}:/sbin/nologin" \
4233
>> /etc/passwd

Dockerfiles/midstream/fix_etc_passwd_k8s.sh

Lines changed: 0 additions & 35 deletions
This file was deleted.

Dockerfiles/midstream/run_tests.py

Lines changed: 66 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
#!/usr/bin/env python3
22
import os
33
import sys
4-
import json
5-
import unittest
64
import subprocess
75
import logging
8-
from os import path
96

107

118
TEST_WORKING_DIR= os.getcwd()
@@ -15,93 +12,97 @@
1512
WORK_DIR=OUTPUT_DIRECTORY+"/output/"
1613
PLAYBOOKS_DIR="/project/operator-test-playbooks/"
1714
ERROR_MESSAGE_PATH=TEST_WORKING_DIR+"/.errormessage"
18-
logging.basicConfig(filename=ERROR_MESSAGE_PATH)
15+
16+
logging.basicConfig(handlers=[logging.StreamHandler()],
17+
level=logging.INFO)
18+
VALIDATION_LOGGER = logging.getLogger('.errormessage')
19+
# by default will be logged logs to stderr but also add the same messages
20+
# to the file which midstream expects
21+
VALIDATION_LOGGER.addHandler(logging.FileHandler(ERROR_MESSAGE_PATH))
22+
1923

2024
class RunMidstreamCVPTests():
2125

22-
def setUp(self):
26+
def __init__(self):
2327
# IMAGE_TO_TESTis an environment variable that takes
2428
# operator-bundle-image
2529
self.image_to_test = os.getenv('IMAGE_TO_TEST')
2630
# VERBOSITY is verbosity of output log range varying from 1 to 4
2731
self.verbosity = int(os.getenv('VERBOSITY', '1'))*"v"
2832

29-
def run_subprocess_command(self, exec_cmd):
30-
print("[INFO] Running the subprocess ansible command ")
31-
print(exec_cmd)
33+
@staticmethod
34+
def run_subprocess_command(exec_cmd):
35+
logging.info("Running the subprocess ansible command ")
36+
logging.info(exec_cmd)
3237
env = os.environ.copy()
33-
result = {}
3438
process = subprocess.run(exec_cmd,
35-
stdout=subprocess.PIPE,
36-
stderr=subprocess.PIPE,
37-
shell=True,
38-
universal_newlines=True,
39-
env=env)
40-
result["stdout"] = process.stdout
41-
result["stderr"] = process.stderr
42-
result["return_code"] = process.returncode
43-
return result
39+
stdout=subprocess.PIPE,
40+
stderr=subprocess.PIPE,
41+
shell=True,
42+
universal_newlines=True,
43+
env=env)
44+
return {
45+
"stdout": process.stdout,
46+
"stderr": process.stderr,
47+
"return_code": process.returncode,
48+
}
4449

4550
def run_extract_operator_bundle(self):
4651
exec_cmd = "/usr/bin/ansible-playbook -i localhost, -c local -{verbosity} {playbook_dir}/extract-operator-bundle.yml \
4752
-e 'bundle_image={bundle_image}' \
4853
-e 'operator_work_dir={operator_work_dir}' \
49-
-e 'work_dir={work_dir}'".format(
50-
operator_dir=OPERATOR_DIR,
51-
playbook_dir=PLAYBOOKS_DIR,
52-
operator_work_dir=OPERATOR_WORK_DIR,
53-
bundle_image=self.image_to_test,
54-
verbosity=self.verbosity,
55-
work_dir=WORK_DIR)
56-
result = self.run_subprocess_command(exec_cmd)
57-
return result
54+
-e 'work_dir={work_dir}'".format(verbosity=self.verbosity,
55+
playbook_dir=PLAYBOOKS_DIR,
56+
bundle_image=self.image_to_test,
57+
operator_work_dir=OPERATOR_WORK_DIR,
58+
work_dir=WORK_DIR)
59+
return RunMidstreamCVPTests.run_subprocess_command(exec_cmd)
5860

5961
def run_validate_operator_bundle(self):
60-
exec_cmd = "/usr/bin/ansible-playbook -{verbosity} -i localhost, --connection local \
61-
{playbook_dir}/validate-operator-bundle.yml \
62-
-e 'operator_dir={operator_dir}' \
63-
-e 'operator_work_dir={operator_work_dir}' \
64-
-e 'work_dir={work_dir}'".format(operator_dir=OPERATOR_DIR,
65-
operator_work_dir=OPERATOR_WORK_DIR,
66-
work_dir=WORK_DIR,
67-
playbook_dir=PLAYBOOKS_DIR,
68-
verbosity=self.verbosity)
69-
result = self.run_subprocess_command(exec_cmd)
70-
return result
62+
exec_cmd = "/usr/bin/ansible-playbook -i localhost, -c local -{verbosity} \
63+
{playbook_dir}/validate-operator-bundle.yml \
64+
-e 'operator_dir={operator_dir}' \
65+
-e 'operator_work_dir={operator_work_dir}' \
66+
-e 'work_dir={work_dir}'".format(verbosity=self.verbosity,
67+
playbook_dir=PLAYBOOKS_DIR,
68+
operator_work_dir=OPERATOR_WORK_DIR,
69+
operator_dir=OPERATOR_DIR,
70+
work_dir=WORK_DIR)
71+
return RunMidstreamCVPTests.run_subprocess_command(exec_cmd)
7172

7273
def test_for_extract_and_validate_bundle_image(self):
7374

74-
self.setUp()
75-
global exit_code
76-
exit_code = 0
7775
# check if IMAGE_TO_TEST is defined, return exit_code 102 in case it's not
78-
if (self.image_to_test is None):
79-
logging.error("Environment variable IMAGE_TO_TEST not set! Stopping the tests.")
80-
logging.error("Result code: 102 Error message: Environment variable IMAGE_TO_TEST not set!")
81-
exit_code = 102
82-
return exit_code
76+
if not self.image_to_test:
77+
VALIDATION_LOGGER.error("Environment variable IMAGE_TO_TEST not set! Stopping the tests.")
78+
VALIDATION_LOGGER.error("Result code: 102 Error message: Environment variable IMAGE_TO_TEST not set!")
79+
return 102
80+
8381
result = self.run_extract_operator_bundle()
84-
if (result["return_code"] != 0):
85-
logging.error("Ansible playbook extract-operator-bundle.yml failed with result code: %s , see the file .errormessage for more info." % result["return_code"])
86-
logging.error("Result code: " + str(result["return_code"]))
87-
logging.error("Error message: " + str(result["stderr"]))
88-
logging.error("Result stdout: " + str(result["stdout"]))
89-
exit_code = 50
90-
return exit_code
82+
if result["return_code"] != 0:
83+
VALIDATION_LOGGER.error("Ansible playbook extract-operator-bundle.yml failed with result code: %s , see the file .errormessage for more info.", result["return_code"])
84+
VALIDATION_LOGGER.error("Result code: %d", result["return_code"])
85+
VALIDATION_LOGGER.error("Error message: %s", result["stderr"])
86+
VALIDATION_LOGGER.error("Result stdout: %s", result["stdout"])
87+
return 50
9188
result = self.run_validate_operator_bundle()
92-
with open(WORK_DIR+"/validation-rc.txt", 'r') as reader:
93-
rc = reader.read()
94-
if (int(rc) != 0):
95-
logging.error("Image bundle validation failed with result code: %s , see /project/output/validation-output.txt file for more info." % int(rc))
96-
exit_code = 70
97-
return exit_code
98-
print("[INFO] {image_to_test} has passed operator bundle image validation test".format(image_to_test=self.image_to_test))
89+
with open(WORK_DIR + "/validation-rc.txt", 'r') as reader:
90+
validation_rc = reader.read()
91+
if int(validation_rc) != 0:
92+
with open(WORK_DIR + "/validation-output.txt", 'r') as validate_reader:
93+
validation_output = validate_reader.read()
94+
VALIDATION_LOGGER.error("Image bundle validation failed with result code: %s and error:\n%s", validation_rc, validation_output)
95+
return 70
96+
97+
logging.info("Image: %s has passed operator bundle image validation test", self.image_to_test)
9998
return 0
10099

101100
if __name__ == '__main__':
101+
subprocess.run(['fix_etc_passwd.sh'], check=True)
102102
resultcodes = [0, 50, 70, 102]
103-
runTest = RunMidstreamCVPTests()
104-
if (runTest.test_for_extract_and_validate_bundle_image() not in resultcodes):
105-
exit_code = 1
106-
print("Error occured during unit tests, please see .errormessage file for more info.")
107-
sys.exit(exit_code)
103+
test_runner = RunMidstreamCVPTests()
104+
return_code = test_runner.test_for_extract_and_validate_bundle_image()
105+
if return_code not in resultcodes:
106+
VALIDATION_LOGGER.error("Unexpected error (%d) occured during unit tests, please see .errormessage file for more info.", return_code)
107+
return_code = 1
108+
sys.exit(return_code)

Dockerfiles/midstream/unit_tests.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def setUp(self):
1414
self.env["ANSIBLE_LOCAL_TEMP"] = "/tmp/"
1515
self.exec_cmd = "run_tests.py"
1616

17-
def clean_up(self):
17+
def tearDown(self):
1818
os.remove(OUTPUT_DIR+".errormessage")
1919
# removes the output directory created by playbooks
2020
shutil.rmtree(OUTPUT_DIR+"/output/", ignore_errors=True)
@@ -23,6 +23,12 @@ def clean_up(self):
2323
# removes the operator-bundle directory created by playbooks
2424
shutil.rmtree(OUTPUT_DIR+"/operator-bundle/", ignore_errors=True)
2525

26+
@staticmethod
27+
def get_error_message_content(output_file=".errormessage"):
28+
with open(OUTPUT_DIR + output_file) as error_file:
29+
return error_file.read()
30+
31+
2632
# Running the container with correctly set environment variables, default channel missing, all tasks should pass
2733
def test_positive_missing_default_channel(self):
2834
self.env["IMAGE_TO_TEST"] = "quay.io/cvpops/test-operator:missing-default-channel-v1"
@@ -32,7 +38,6 @@ def test_positive_missing_default_channel(self):
3238
cwd=OUTPUT_DIR)
3339
self.assertEqual(0, result.returncode)
3440
self.assertTrue(os.path.exists(OUTPUT_DIR+".errormessage"))
35-
self.clean_up()
3641

3742
# Set env variable to custom made image that makes playbook extract-operator-bundle.yml fail
3843
# Due to parsing error
@@ -42,11 +47,11 @@ def test_negative_parsing(self):
4247
shell=True,
4348
env=self.env,
4449
cwd=OUTPUT_DIR)
45-
with open(OUTPUT_DIR+".errormessage") as error_file:
46-
self.assertIn("Result code:", error_file.read(), "Result code not found in %s" % error_file)
50+
51+
message = self.get_error_message_content()
52+
self.assertIn("Result code:", message, "Result code not found in .errormessage")
4753
self.assertEqual(50, result.returncode)
4854
self.assertTrue(os.path.exists(OUTPUT_DIR+".errormessage"))
49-
self.clean_up()
5055

5156
# Set env variable to custom made image that makes validation fails with following error:
5257
# ERRO[0003] error validating format in /tmp/bundle-688328851: Bundle validation errors: couldn't
@@ -57,11 +62,11 @@ def test_negative_image_bundle_validation(self):
5762
shell=True,
5863
env=self.env,
5964
cwd=OUTPUT_DIR)
60-
with open(OUTPUT_DIR+"/output/validation-output.txt") as error_file:
61-
self.assertIn("Bundle validation errors: couldn't parse dependency of type olm.crd", error_file.read(), "Result code not found in %s" % error_file)
65+
66+
message = self.get_error_message_content()
67+
self.assertIn("Bundle validation errors: couldn't parse dependency of type olm.crd", message, "Result code not found in .erroremessage")
6268
self.assertEqual(70, result.returncode)
6369
self.assertTrue(os.path.exists(OUTPUT_DIR+".errormessage"))
64-
self.clean_up()
6570

6671
# Don't set env variable IMAGE_TO_TEST case
6772
def test_negative_image_to_test_not_set(self):
@@ -70,11 +75,11 @@ def test_negative_image_to_test_not_set(self):
7075
shell=True,
7176
env=self.env,
7277
cwd=OUTPUT_DIR)
73-
with open(OUTPUT_DIR+".errormessage") as error_file:
74-
self.assertIn("Result code: 102 Error message: Environment variable IMAGE_TO_TEST not set!", error_file.read(), "Result code not found in %s" % error_file)
78+
message = self.get_error_message_content()
79+
self.assertIn("Result code: 102 Error message: Environment variable IMAGE_TO_TEST not set!", message,
80+
"Result code not found in %s" % message)
7581
self.assertEqual(102, result.returncode)
7682
self.assertTrue(os.path.exists(OUTPUT_DIR+".errormessage"))
77-
self.clean_up()
7883

7984
# Run with a test-operator which passes the bundle image validation job
8085
def test_default_positive(self):
@@ -88,7 +93,6 @@ def test_default_positive(self):
8893
self.assertTrue(os.stat("/tmp/.errormessage").st_size == 0)
8994
# check if the .errormessage exists since its a logger file
9095
self.assertTrue(os.path.exists(OUTPUT_DIR+".errormessage"))
91-
self.clean_up()
9296

9397

9498
if __name__ == '__main__':

0 commit comments

Comments
 (0)