Skip to content

Commit edd0221

Browse files
authored
[jump-ci] Allow testing multiple presets (#646)
2 parents 468339e + 50fbc41 commit edd0221

File tree

9 files changed

+119
-69
lines changed

9 files changed

+119
-69
lines changed

projects/jump_ci/testing/config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,6 @@ exec_list:
3333
prepare_ci: null
3434
test_ci: null
3535
post_cleanup_ci: null
36+
multi_run:
37+
args: []
38+
stop_on_error: false

projects/jump_ci/testing/test.py

Lines changed: 86 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@ def rewrite_variables_overrides(variable_overrides_dict):
2424
new_args_str = new_variable_overrides[f"PR_POSITIONAL_ARGS"] = " ".join(new_args)
2525
new_variable_overrides["PR_POSITIONAL_ARGS"] = variable_overrides_dict["PR_POSITIONAL_ARG_0"]
2626
logging.info(f"New args to execute on the jump host: {new_args_str}")
27+
28+
idx = 0
2729
for idx, value in enumerate(new_args):
2830
new_variable_overrides[f"PR_POSITIONAL_ARG_{idx+1}"] = value
31+
next_pr_positional_arg_count = idx + 2
2932

3033
for k, v in variable_overrides_dict.items():
3134
if k.startswith("PR_POSITIONAL_ARG"): continue
@@ -44,7 +47,7 @@ def rewrite_variables_overrides(variable_overrides_dict):
4447
new_variable_overrides[k] = v
4548
logging.info(f"Passing '{k}: {v}' to the new variables overrides")
4649

47-
return new_variable_overrides
50+
return new_variable_overrides, next_pr_positional_arg_count
4851

4952

5053
def jump_ci(command):
@@ -67,26 +70,28 @@ def do_jump_ci(cluster=None, project=None, test_args=None):
6770

6871
secrets_path_env_key = config.project.get_config("secrets.dir.env_key")
6972

70-
env_fd_path, env_file = utils.get_tmp_fd()
7173
extra_env = dict(
7274
TOPSAIL_JUMP_CI="true",
7375
TOPSAIL_JUMP_CI_INSIDE_JUMP_HOST="true",
7476
)
75-
if step_dir := os.environ.get("TOPSAIL_OPENSHIFT_CI_STEP_DIR"):
76-
extra_env["TOPSAIL_OPENSHIFT_CI_STEP_DIR"] = f"{step_dir}/test-artifacts" # see "jump_ci retrieve_artifacts" below
7777

78-
env_pass_lists = config.project.get_config("env.pass_lists", print=False)
78+
def prepare_env_file(_extra_env):
79+
env_fd_path, env_file = utils.get_tmp_fd()
80+
81+
env_pass_lists = config.project.get_config("env.pass_lists", print=False)
7982

80-
env_pass_list = set()
81-
for _, pass_list in (env_pass_lists or {}).items():
82-
env_pass_list.update(pass_list)
83+
env_pass_list = set()
84+
for _, pass_list in (env_pass_lists or {}).items():
85+
env_pass_list.update(pass_list)
8386

84-
for k, v in (os.environ | extra_env).items():
85-
if k not in (env_pass_list | extra_env.keys()): continue
87+
for k, v in (os.environ | _extra_env).items():
88+
if k not in (env_pass_list | _extra_env.keys()): continue
8689

87-
print(f"{k}={shlex.quote(v)}", file=env_file)
90+
print(f"{k}={shlex.quote(v)}", file=env_file)
8891

89-
env_file.flush()
92+
env_file.flush()
93+
94+
return env_fd_path, env_file
9095

9196
variable_overrides_file = pathlib.Path(os.environ.get("ARTIFACT_DIR")) / "variable_overrides.yaml"
9297

@@ -100,6 +105,8 @@ def do_jump_ci(cluster=None, project=None, test_args=None):
100105

101106
run.run_toolbox("jump_ci", "ensure_lock", cluster=cluster, owner=utils.get_lock_owner())
102107

108+
cluster_lock_dir = f" /tmp/topsail_{cluster}"
109+
103110
if test_args is not None:
104111
variables_overrides_dict = dict(
105112
PR_POSITIONAL_ARGS=test_args,
@@ -110,55 +117,86 @@ def do_jump_ci(cluster=None, project=None, test_args=None):
110117
variables_overrides_dict[f"PR_POSITIONAL_ARG_{idx+1}"] = arg
111118

112119
config.project.set_config("overrides", variables_overrides_dict)
113-
120+
next_pr_positional_arg_count = idx + 2
114121
else:
115122
if not os.environ.get("OPENSHIFT_CI") == "true":
116123
logging.fatal("Not running in OpenShift CI. Don't know how to rewrite the variable_overrides_file. Aborting.")
117124
raise SystemExit(1)
118125

119126
project = config.project.get_config("overrides.PR_POSITIONAL_ARG_2")
120127

121-
variables_overrides_dict = rewrite_variables_overrides(
128+
variables_overrides_dict, next_pr_positional_arg_count = rewrite_variables_overrides(
122129
config.project.get_config("overrides")
123130
)
124131

125-
run.run_toolbox(
126-
"jump_ci", "prepare_step",
127-
cluster=cluster,
128-
lock_owner=utils.get_lock_owner(),
129-
project=project,
130-
step=command,
131-
env_file=env_fd_path,
132-
variables_overrides_dict=variables_overrides_dict,
133-
secrets_path_env_key=secrets_path_env_key,
134-
)
135-
136-
try:
137-
tunnelling.run_with_ansible_ssh_conf(f"bash /tmp/{cluster}/test/{command}/entrypoint.sh")
138-
logging.info(f"Test step '{command}' on cluster '{cluster}' succeeded.")
139-
failed = False
140-
except subprocess.CalledProcessError as e:
141-
logging.fatal(f"Test step '{command}' on cluster '{cluster}' FAILED.")
142-
failed = True
143-
except run.SignalError as e:
144-
logging.error(f"Caught signal {e.sig}. Aborting.")
145-
raise
146-
finally:
147-
# always run the cleanup to be sure that the container doesn't stay running
148-
tunnelling.run_with_ansible_ssh_conf(f"bash /tmp/{cluster}/test/{command}/entrypoint.sh cleanup")
149-
150-
run.run_toolbox(
151-
"jump_ci", "retrieve_artifacts",
152-
cluster=cluster,
153-
lock_owner=utils.get_lock_owner(),
154-
remote_dir=f"test/{command}/artifacts",
155-
local_dir=f"../test-artifacts", # copy to the main artifact directory
156-
mute_stdout=True,
157-
)
132+
for idx, multi_run_args in enumerate((config.project.get_config("multi_run.args") or [...])):
133+
multi_run_args_dict = {}
134+
multi_run_dirname = None
135+
test_artifacts_dirname = "test-artifacts"
136+
137+
if multi_run_args is not ...:
138+
139+
multi_run_args_lst = multi_run_args if isinstance(multi_run_args, list) else [multi_run_args]
140+
multi_run_dirname = f"multi_run__{'_'.join(multi_run_args_lst)}"
141+
142+
with open(env.ARTIFACT_DIR / "multi_run_args.list", "a+") as f:
143+
print(f"{multi_run_dirname}: {multi_run_args}")
144+
145+
for idx, multi_run_arg in enumerate(multi_run_args_lst):
146+
variables_overrides_dict[f"PR_POSITIONAL_ARG_{next_pr_positional_arg_count+idx}"] = multi_run_arg
147+
148+
with env.NextArtifactDir(multi_run_dirname) if multi_run_dirname else open("/dev/null"):
149+
150+
if multi_run_dirname:
151+
test_artifacts_dirname = f"{env.ARTIFACT_DIR.name}/{test_artifacts_dirname}"
152+
153+
if step_dir := os.environ.get("TOPSAIL_OPENSHIFT_CI_STEP_DIR"):
154+
# see "jump_ci retrieve_artifacts" below
155+
extra_env["TOPSAIL_OPENSHIFT_CI_STEP_DIR"] = f"{step_dir}/{test_artifacts_dirname}"
156+
157+
env_fd_path, env_file = prepare_env_file(extra_env)
158+
159+
run.run_toolbox(
160+
"jump_ci", "prepare_step",
161+
cluster=cluster,
162+
lock_owner=utils.get_lock_owner(),
163+
project=project,
164+
step=command,
165+
env_file=env_fd_path,
166+
variables_overrides_dict=(variables_overrides_dict | multi_run_args_dict),
167+
secrets_path_env_key=secrets_path_env_key,
168+
)
169+
env_file.close()
170+
171+
try:
172+
tunnelling.run_with_ansible_ssh_conf(f"bash {cluster_lock_dir}/test/{command}/entrypoint.sh")
173+
logging.info(f"Test step '{command}' on cluster '{cluster}' succeeded.")
174+
failed = False
175+
except subprocess.CalledProcessError as e:
176+
logging.fatal(f"Test step '{command}' on cluster '{cluster}' FAILED.")
177+
failed = True
178+
except run.SignalError as e:
179+
logging.error(f"Caught signal {e.sig}. Aborting.")
180+
raise
181+
finally:
182+
# always run the cleanup to be sure that the container doesn't stay running
183+
tunnelling.run_with_ansible_ssh_conf(f"bash {cluster_lock_dir}/test/{command}/entrypoint.sh cleanup")
184+
185+
run.run_toolbox(
186+
"jump_ci", "retrieve_artifacts",
187+
cluster=cluster,
188+
lock_owner=utils.get_lock_owner(),
189+
remote_dir=f"test/{command}/artifacts",
190+
local_dir=f"../{pathlib.Path(test_artifacts_dirname).name}", # copy to the main artifact directory
191+
mute_stdout=True,
192+
)
193+
194+
if failed and config.project.get_config("multi_run.stop_on_error"):
195+
break
158196

159197
jump_ci_artifacts = env.ARTIFACT_DIR / "jump-ci-artifacts"
160198
jump_ci_artifacts.mkdir(parents=True, exist_ok=True)
161-
run.run(f'mv {env.ARTIFACT_DIR}/0* {jump_ci_artifacts}/')
199+
run.run(f'mv {env.ARTIFACT_DIR}/*__jump_ci_* {jump_ci_artifacts}/')
162200

163201
if failed:
164202
raise SystemExit(1)

projects/jump_ci/toolbox/jump_ci_ensure_lock/tasks/main.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,22 @@
2323
fail: msg="The cluster KUBECONFIG ({{ cluster_kubeconfig }}) does not exists"
2424
when: not cluster_kubeconfig_stat.stat.exists
2525

26+
- name: Save the name of the cluster lock directory
27+
set_fact:
28+
cluster_lock_dir: "/tmp/topsail_{{ jump_ci_ensure_lock_cluster }}"
29+
2630
- name: "Get the stats of the lock directory: {{ jump_ci_ensure_lock_cluster }}"
2731
stat:
28-
path: "/tmp/{{ jump_ci_ensure_lock_cluster }}"
32+
path: "{{ cluster_lock_dir }}"
2933
register: lock_directory_stat
3034

3135
- name: Fail if the lock directory doesn't exist
32-
fail: msg="The lock directory '/tmp/{{ jump_ci_ensure_lock_cluster }}' does not exists"
36+
fail: msg="The lock directory '{{ cluster_lock_dir }}' does not exists"
3337
when: not lock_directory_stat.stat.exists
3438

3539
- name: Get the owner of the lock
3640
command:
37-
cat "/tmp/{{ jump_ci_ensure_lock_cluster }}/lock_owner"
41+
cat "{{ cluster_lock_dir }}/lock_owner"
3842
register: lock_owner_content_cmd
3943

4044
- name: Fail if the owner is different

projects/jump_ci/toolbox/jump_ci_prepare_step/tasks/main.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
- name: Fetch the name of the image to use
1111
shell:
12-
cat "/tmp/{{ jump_ci_prepare_step_cluster }}/pod.image"
12+
cat "{{ cluster_lock_dir }}/pod.image"
1313
register: pod_image_cmd
1414
failed_when: false
1515

@@ -19,13 +19,14 @@
1919

2020
- name: Generate the step artifacts dirname
2121
set_fact:
22-
step_artifact_dir: "/tmp/{{ jump_ci_prepare_step_cluster }}/test/{{ jump_ci_prepare_step_step }}"
22+
step_artifact_dir: "{{ cluster_lock_dir }}/test/{{ jump_ci_prepare_step_step }}"
2323

2424
- name: Ensure that the step artifacts dirname directory is empty
2525
ansible.builtin.file:
2626
state: absent
2727
path: "{{ step_artifact_dir }}"
2828
mode: '0755'
29+
no_log: true # can be too chatty when cleaning an existing artifacts directly
2930

3031
- name: Ensure that the step test dirname directory exists
3132
ansible.builtin.file:
@@ -68,22 +69,22 @@
6869
- name: Ensure that the secrets directory exists
6970
ansible.builtin.file:
7071
state: directory
71-
path: "/tmp/{{ jump_ci_prepare_step_cluster }}/secrets/{{ jump_ci_prepare_step_secrets_path_env_key }}"
72+
path: "{{ cluster_lock_dir }}/secrets/{{ jump_ci_prepare_step_secrets_path_env_key }}"
7273
mode: '0755'
7374

7475
- name: Copy the secrets to the jump host
7576
ansible.posix.synchronize:
7677
src: "{{ lookup('env', jump_ci_prepare_step_secrets_path_env_key) }}/"
77-
dest: "/tmp/{{ jump_ci_prepare_step_cluster }}/secrets/{{ jump_ci_prepare_step_secrets_path_env_key }}/"
78+
dest: "{{ cluster_lock_dir }}/secrets/{{ jump_ci_prepare_step_secrets_path_env_key }}/"
7879
mode: "push"
7980
no_log: true # not necessary, and leaks the hostnames and secret filenames (they aren't secret)
8081
when: jump_ci_prepare_step_secrets_path_env_key
8182

8283
- name: Ensure that the secret dirs have the right permission
83-
command: find "/tmp/{{ jump_ci_prepare_step_cluster }}/secrets" -type d -exec chmod 0755 {} \;
84+
command: find "{{ cluster_lock_dir }}/secrets" -type d -exec chmod 0755 {} \;
8485

8586
- name: Ensure that the secret files have the right permission
86-
command: find "/tmp/{{ jump_ci_prepare_step_cluster }}/secrets/" -type f -exec chmod 0644 {} \;
87+
command: find "{{ cluster_lock_dir }}/secrets/" -type f -exec chmod 0644 {} \;
8788

8889
- name: Prepare the entrypoint script
8990
template:

projects/jump_ci/toolbox/jump_ci_prepare_step/templates/entrypoint.sh.j2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ cleanup() {
1616

1717
# Not cleaning up the secrets for now. They are safe anyway
1818
# echo Cleaning up the secrets ..
19-
# rm -rf /tmp/{{ jump_ci_prepare_step_cluster }}/secrets
19+
# rm -rf {{ cluster_lock_dir }}/secrets
2020
}
2121

2222
# ---
@@ -49,7 +49,7 @@ podman run \
4949
--volume "{{ step_artifact_dir }}/artifacts:/logs/artifacts" \
5050
--env ARTIFACT_DIR="/logs/artifacts" \
5151
\
52-
--volume /tmp/{{ jump_ci_prepare_step_cluster }}/secrets/{{ jump_ci_prepare_step_secrets_path_env_key }}:/run/secrets/{{ jump_ci_prepare_step_secrets_path_env_key }}:ro \
52+
--volume {{ cluster_lock_dir }}/secrets/{{ jump_ci_prepare_step_secrets_path_env_key }}:/run/secrets/{{ jump_ci_prepare_step_secrets_path_env_key }}:ro \
5353
--env {{ jump_ci_prepare_step_secrets_path_env_key }}="/run/secrets/{{ jump_ci_prepare_step_secrets_path_env_key }}" \
5454
\
5555
--volume {{ cluster_kubeconfig }}:/run/secrets/kubeconfig:ro \

projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
- name: Generate the artifact dirname
1010
set_fact:
11-
artifact_dir: "/tmp/{{ jump_ci_prepare_topsail_cluster }}/jump_ci_artifacts"
11+
artifact_dir: "{{ cluster_lock_dir }}/jump_ci_artifacts"
1212

1313
- name: Ensure that the logs directory exists
1414
ansible.builtin.file:
@@ -49,7 +49,7 @@
4949

5050
- name: Set TOPSAIL's directory
5151
set_fact:
52-
topsail_home: "/tmp/{{ jump_ci_prepare_topsail_cluster }}/topsail"
52+
topsail_home: "{{ cluster_lock_dir }}/topsail"
5353

5454
- name: Set git command
5555
set_fact:
@@ -154,7 +154,7 @@
154154

155155
- name: "Build image as an update {{ image_full_name }}"
156156
shell: |
157-
cat > /tmp/overlay.containerfile <<EOF
157+
cat > {{ cluster_lock_dir }}/overlay.containerfile <<EOF
158158
FROM hell
159159
ENTRYPOINT []
160160
CMD []
@@ -167,7 +167,7 @@
167167
168168
time podman build \
169169
--tag "{{ image_full_name }}" \
170-
--file /tmp/overlay.containerfile \
170+
--file {{ cluster_lock_dir }}/overlay.containerfile \
171171
--from "{{ jump_ci_prepare_topsail_image_name }}:{{ jump_ci_prepare_topsail_update_from_imagetag }}"
172172
when:
173173
- has_image.rc != 0
@@ -186,4 +186,4 @@
186186

187187
- name: Save the name of the image to use
188188
shell:
189-
echo "{{ image_full_name }}" > "/tmp/{{ jump_ci_prepare_topsail_cluster }}/pod.image"
189+
echo "{{ image_full_name }}" > "{{ cluster_lock_dir }}/pod.image"

projects/jump_ci/toolbox/jump_ci_release_lock/tasks/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99

1010
- name: Release the lock directory
1111
command:
12-
rm -rf "/tmp/{{ jump_ci_release_lock_cluster }}"
12+
rm -rf "{{ cluster_lock_dir }}"

projects/jump_ci/toolbox/jump_ci_retrieve_artifacts/tasks/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
- name: Compute the path of the directory to retrieve
1111
set_fact:
12-
remote_dir_path: "/tmp/{{ jump_ci_retrieve_artifacts_cluster }}/{{ jump_ci_retrieve_artifacts_remote_dir }}"
12+
remote_dir_path: "{% if cluster_lock_dir is defined %}{{ cluster_lock_dir }}{% else %}{{ '/tmp/topsail_'+jump_ci_retrieve_artifacts_cluster}}{% endif %}/{{ jump_ci_retrieve_artifacts_remote_dir }}"
1313

1414
- name: Get the size of the directory to retrieve
1515
command:

projects/jump_ci/toolbox/jump_ci_take_lock/tasks/main.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
shell:
44
whoami
55

6+
- name: Save the name of the cluster lock directory
7+
set_fact:
8+
cluster_lock_dir: "/tmp/topsail_{{ jump_ci_take_lock_cluster }}"
9+
610
- name: Create the lock directory
711
shell: |
8-
if ! mkdir "/tmp/{{ jump_ci_take_lock_cluster }}" 2>/dev/null; then
12+
if ! mkdir "{{ cluster_lock_dir }}" 2>/dev/null; then
913
echo "$(date) Lock '{{ jump_ci_take_lock_cluster }}' already taken ..."
10-
cat "/tmp/{{ jump_ci_take_lock_cluster }}/lock_owner 2>/dev/null" || true
14+
cat "{{ cluster_lock_dir }}/lock_owner 2>/dev/null" || true
1115
exit 1
1216
else
1317
echo "$(date) Lock '{{ jump_ci_take_lock_cluster }}' acquired.";
@@ -19,7 +23,7 @@
1923

2024
- name: Log info about the lock owner
2125
shell:
22-
echo "{{ jump_ci_take_lock_owner }}" > "/tmp/{{ jump_ci_take_lock_cluster }}/lock_owner"
26+
echo "{{ jump_ci_take_lock_owner }}" > "{{ cluster_lock_dir }}/lock_owner"
2327

2428
- name: Ensure that the lock is owned
2529
include_role:

0 commit comments

Comments
 (0)