Skip to content

Commit 20c34c9

Browse files
authored
Merge pull request #1286 from stackhpc/2023.1-zed-merge
2023.1: zed merge
2 parents e474210 + acc31e9 commit 20c34c9

File tree

10 files changed

+240
-7
lines changed

10 files changed

+240
-7
lines changed

.github/path-filters.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# This file is a list of path filters for the PR workflow in .github/workflows/stackhpc-pull-request.yml.
2-
aio:
2+
aio: &aio
33
- '.automation'
44
- '.automation.conf/config.sh'
55
- '.automation.conf/tempest/load-lists/default'
@@ -20,6 +20,11 @@ aio:
2020
- 'kayobe-env'
2121
- 'requirements.txt'
2222
- 'terraform/aio/**'
23-
check-tags:
23+
check-tags: &check-tags
2424
- '.github/workflows/stackhpc-check-tags.yml'
2525
- 'etc/kayobe/kolla-image-tags.yml'
26+
- 'etc/kayobe/pulp.yml'
27+
- 'tools/kolla-images.py'
28+
build-kayobe-image:
29+
- *aio
30+
- *check-tags

.github/workflows/stackhpc-check-tags.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ jobs:
4646
run: |
4747
docker image pull $KAYOBE_IMAGE
4848
49+
- name: Check kolla-images.py image map and tag hierarchy
50+
run: |
51+
docker run -t --rm \
52+
-v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \
53+
-e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \
54+
$KAYOBE_IMAGE \
55+
/stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/playbook-run.sh \
56+
'$KAYOBE_CONFIG_PATH/ansible/check-kolla-images-py.yml'
57+
4958
- name: Check container image tags
5059
run: |
5160
docker run -t --rm \

.github/workflows/stackhpc-pull-request.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ jobs:
2020
if: github.repository == 'stackhpc/stackhpc-kayobe-config'
2121
outputs:
2222
aio: ${{ steps.changes.outputs.aio }}
23+
build-kayobe-image: ${{ steps.changes.outputs.build-kayobe-image }}
2324
check-tags: ${{ steps.changes.outputs.check-tags }}
2425
steps:
2526
- name: GitHub Checkout
@@ -74,7 +75,7 @@ jobs:
7475
- check-changes
7576
uses: ./.github/workflows/stackhpc-build-kayobe-image.yml
7677
with:
77-
if: ${{ needs.check-changes.outputs.aio == 'true' }}
78+
if: ${{ needs.check-changes.outputs.build-kayobe-image == 'true' }}
7879
if: github.repository == 'stackhpc/stackhpc-kayobe-config'
7980

8081
check-tags:
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
- name: Check kolla-images.py image map and tag hierarchy
3+
hosts: localhost
4+
gather_facts: false
5+
tasks:
6+
- name: Create a temporary directory
7+
ansible.builtin.tempfile:
8+
state: directory
9+
suffix: kolla-ansible
10+
register: tempdir_result
11+
12+
- name: Clone Kolla Ansible repository
13+
ansible.builtin.git:
14+
repo: "{{ stackhpc_kolla_ansible_source_url }}"
15+
version: "{{ stackhpc_kolla_ansible_source_version }}"
16+
dest: "{{ tempdir_result.path }}"
17+
18+
- name: Check image mapping
19+
ansible.builtin.command:
20+
cmd: >-
21+
{{ kayobe_config_path }}/../../tools/kolla-images.py
22+
check-image-map
23+
--kolla-ansible-path {{ tempdir_result.path }}
24+
25+
- name: Check tag hierarchy
26+
ansible.builtin.command:
27+
cmd: >-
28+
{{ kayobe_config_path }}/../../tools/kolla-images.py
29+
check-hierarchy
30+
--kolla-ansible-path {{ tempdir_result.path }}
31+
32+
- name: Remove temporary directory
33+
ansible.builtin.file:
34+
path: "{{ tempdir_result.path }}"
35+
state: absent

etc/kayobe/ansible/check-tags.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- name: Check whether tags exist in Pulp container registry
66
hosts: localhost
7+
gather_facts: false
78
tasks:
89
- name: Query images and tags
910
command:

etc/kayobe/ansible/growroot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
vars:
7676
pv: "{{ pvs.stdout | from_json }}"
7777
disk_tmp: "{{ pv.report[0].pv[0].pv_name[:-1] }}"
78-
disk: "{{ disk_tmp[:-1] if disk_tmp[-1] == 'p' and disk_tmp[:9] == '/dev/nvme' else disk_tmp }}"
78+
disk: "{{ disk_tmp[:-1] if pv.report[0].pv[0].pv_name | regex_search('[a-z0-9]+[0-9]+p[0-9]+') else disk_tmp }}"
7979
part_num: "{{ pv.report[0].pv[0].pv_name[-1] }}"
8080
become: true
8181
failed_when: "growpart.rc != 0 and 'NOCHANGE' not in growpart.stdout"

etc/kayobe/kolla-image-tags.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ kolla_image_tags:
1717
ironic:
1818
rocky-9: 2023.1-rocky-9-20240906T144646
1919
ubuntu-jammy: 2023.1-ubuntu-jammy-20240906T144646
20+
ironic_dnsmasq:
21+
rocky-9: 2023.1-rocky-9-20240709T132012
22+
ubuntu-jammy: 2023.1-ubuntu-jammy-20240621T104542
2023
kolla_toolbox:
2124
rocky-9: 2023.1-rocky-9-20240809T102431
2225
letsencrypt:
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
fixes:
3+
- |
4+
Fixes a regression when using ``growroot.yml`` and software raid where the
5+
playbook would fail to identify the correct disk.

tools/kolla-images.py

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,20 @@
3939

4040
# Maps a Kolla image to a list of containers that use the image.
4141
IMAGE_TO_CONTAINERS_EXCEPTIONS: Dict[str, List[str]] = {
42+
"dnsmasq": [
43+
"ironic_dnsmasq",
44+
],
4245
"haproxy": [
4346
"glance_tls_proxy",
47+
"haproxy",
4448
"neutron_tls_proxy",
4549
],
4650
"mariadb-server": [
4751
"mariadb",
4852
"mariabackup",
4953
],
50-
"neutron-eswitchd": [
54+
"neutron-mlnx-agent": [
55+
"neutron_eswitchd",
5156
"neutron_mlnx_agent",
5257
],
5358
"neutron-metadata-agent": [
@@ -58,6 +63,15 @@
5863
"nova_super_conductor",
5964
"nova_conductor",
6065
],
66+
"openvswitch-db-server": [
67+
"openvswitch_db",
68+
],
69+
"ovn-nb-db-server": [
70+
"ovn_nb_db",
71+
],
72+
"ovn-sb-db-server": [
73+
"ovn_sb_db",
74+
],
6175
"prometheus-v2-server": [
6276
"prometheus_server",
6377
],
@@ -96,6 +110,9 @@ def parse_args() -> argparse.Namespace:
96110
parser.add_argument("--base-distros", default=",".join(SUPPORTED_BASE_DISTROS), choices=SUPPORTED_BASE_DISTROS)
97111
subparsers = parser.add_subparsers(dest="command", required=True)
98112

113+
subparser = subparsers.add_parser("check-image-map", help="Check image mapping against kolla-ansible")
114+
subparser.add_argument("--kolla-ansible-path", required=True, help="Path to kolla-ansible repostory checked out to correct branch")
115+
99116
subparser = subparsers.add_parser("check-hierarchy", help="Check tag variable hierarchy against kolla-ansible")
100117
subparser.add_argument("--kolla-ansible-path", required=True, help="Path to kolla-ansible repostory checked out to correct branch")
101118

@@ -114,7 +131,7 @@ def parse_args() -> argparse.Namespace:
114131
return parser.parse_args()
115132

116133

117-
def get_abs_path(relative_path: str) -> str:
134+
def get_abs_path(relative_path: str) -> pathlib.Path:
118135
"""Return the absolute path of a file in SKC."""
119136
script_path = pathlib.Path(inspect.getfile(inspect.currentframe()))
120137
return script_path.parent.parent / relative_path
@@ -277,6 +294,45 @@ def check_tags(base_distros: List[str], kolla_image_tags: KollaImageTags, regist
277294
sys.exit(1)
278295

279296

297+
def check_image_map(kolla_ansible_path: str):
298+
"""Check the image mapping against Kolla Ansible variables.
299+
300+
The *_image variables in Kolla Ansible define the mapping between
301+
containers and images. Ensure that the mapping defined in this script
302+
matches the one in Kolla Ansible.
303+
"""
304+
supported_images = read_images("etc/kayobe/pulp.yml")
305+
assert supported_images
306+
# Build a map from container to image name.
307+
cmd = """git grep -h '^[a-z0-9_]*_image:' ansible/roles/*/defaults/main.yml"""
308+
image_map_str = subprocess.check_output(cmd, shell=True, cwd=os.path.realpath(kolla_ansible_path))
309+
image_map = yaml.safe_load(image_map_str)
310+
image_var_re = re.compile(r"^([a-z0-9_]+)_image$")
311+
image_map = {
312+
image_var_re.match(image_var).group(1): image.split("/")[-1]
313+
for image_var, image in image_map.items()
314+
}
315+
# Filter out unsupported images.
316+
image_map = {
317+
container: image
318+
for container, image in image_map.items()
319+
if image in supported_images
320+
}
321+
assert image_map
322+
errors = []
323+
# Check that our mapping is correct.
324+
for container, image in image_map.items():
325+
containers = get_containers(image)
326+
if container not in containers:
327+
errors.append((container, image))
328+
if errors:
329+
print("Errors:")
330+
for tag_var, image in errors:
331+
print(f"Expected {tag_var} container to use {image} image")
332+
if errors:
333+
sys.exit(1)
334+
335+
280336
def check_hierarchy(kolla_ansible_path: str):
281337
"""Check the tag variable hierarchy against Kolla Ansible variables."""
282338
cmd = """git grep -h '^[a-z0-9_]*_tag:' ansible/roles/*/defaults/main.yml"""
@@ -352,7 +408,9 @@ def main():
352408

353409
validate(kolla_image_tags)
354410

355-
if args.command == "check-hierarchy":
411+
if args.command == "check-image-map":
412+
check_image_map(args.kolla_ansible_path)
413+
elif args.command == "check-hierarchy":
356414
check_hierarchy(args.kolla_ansible_path)
357415
elif args.command == "check-tags":
358416
check_tags(base_distros, kolla_image_tags, args.registry, args.namespace)

tools/merge.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/python3
2+
3+
DESCRIPTION = """
4+
This script merges one release branch of SKC into another.
5+
6+
Example 1: Merge stackhpc/yoga into stackhpc/zed:
7+
8+
merge.py yoga zed
9+
10+
Example 2: Merge the branch created in example 1 into stackhpc/2023.1:
11+
12+
merge.py zed 2023.1 zed-yoga-merge
13+
14+
Example 3: Continue after manually resolving merge conflicts seen in example 2:
15+
16+
merge.py zed 2023.1 zed-yoga-merge --continue
17+
18+
"""
19+
20+
import argparse
21+
import os
22+
from subprocess import check_call, check_output
23+
import sys
24+
25+
26+
def command(cmd):
27+
print("Running:", cmd)
28+
check_call(cmd)
29+
30+
31+
def parse_args():
32+
parser = argparse.ArgumentParser(description=DESCRIPTION, formatter_class=argparse.RawDescriptionHelpFormatter)
33+
#"Merge one branch of SKC into the next")
34+
parser.add_argument("previous", type=str, help="The previous version")
35+
parser.add_argument("current", type=str, help="The current version")
36+
parser.add_argument("previous_branch", type=str, nargs="?", default=None, help="Optional branch to use as the previous release. Allows merging multiple branches in parallel.")
37+
parser.add_argument("--continue", dest="cont", action="store_true", help="Continue after merge conflicts have been resolved.")
38+
parser.add_argument("--remote", type=str, default="origin", help="Git remote")
39+
return parser.parse_args()
40+
41+
42+
def fetch(args):
43+
command(["git", "fetch", args.remote])
44+
45+
46+
def checkout(args):
47+
merge_branch = f"{args.current}-{args.previous}-merge"
48+
current_branch = f"{args.remote}/stackhpc/{args.current}"
49+
command(["git", "checkout", "-B", merge_branch, current_branch])
50+
51+
52+
def update_submodules():
53+
command(["git", "submodule", "update"])
54+
55+
56+
def merge_in_progress():
57+
repo_root = check_output(["git", "rev-parse", "--show-toplevel"])
58+
repo_root = repo_root.decode().strip()
59+
return os.path.isfile(os.path.join(repo_root, ".git", "MERGE_HEAD"))
60+
61+
62+
def uncommitted_changes():
63+
unstaged = check_output(["git", "diff"])
64+
staged = check_output(["git", "diff", "--cached"])
65+
return unstaged or staged
66+
67+
68+
def continue_merge():
69+
if merge_in_progress():
70+
command(["git", "merge", "--continue"])
71+
else:
72+
print("No merge in progress")
73+
74+
75+
def merge(args):
76+
if args.previous_branch:
77+
previous_branch = args.previous_branch
78+
else:
79+
previous_branch = f"{args.remote}/stackhpc/{args.previous}"
80+
commit_message = f"Merge stackhpc/{args.previous} into stackhpc/{args.current}"
81+
command(["git", "merge", previous_branch, "-m", commit_message])
82+
83+
84+
def show_diff(args):
85+
print("Proposed changes:")
86+
current_branch = f"{args.remote}/stackhpc/{args.current}"
87+
command(["git", "diff", current_branch])
88+
89+
90+
def create_pr(args):
91+
current_branch = f"stackhpc/{args.current}"
92+
pr_title = f"{args.current}: {args.previous} merge"
93+
command(["gh", "pr", "create", "-f", "-a", "@me", "-B", current_branch, "-t", pr_title])
94+
95+
96+
def main():
97+
args = parse_args()
98+
if args.cont:
99+
continue_merge()
100+
else:
101+
if merge_in_progress():
102+
print("Merge in progress - did you miss the --continue argument?")
103+
sys.exit(1)
104+
if uncommitted_changes():
105+
print("You have uncommitted changes - aborting")
106+
sys.exit(1)
107+
fetch(args)
108+
checkout(args)
109+
update_submodules()
110+
merge(args)
111+
show_diff(args)
112+
create_pr(args)
113+
114+
115+
if __name__ == "__main__":
116+
main()

0 commit comments

Comments
 (0)