Extract buildinfo from yaml file and create content_manifest.json#2603
Extract buildinfo from yaml file and create content_manifest.json#2603gursewak1997 merged 1 commit intocoreos:mainfrom gursewak1997:addBuildInfo
Conversation
miabbott
left a comment
There was a problem hiding this comment.
Looks like a good start, but I think there are some more changes needed
| fi | ||
| extra_compose_args+=("$parent_arg") | ||
|
|
||
| # Convert the yaml file of content_sets to json format |
There was a problem hiding this comment.
I would keep this code behind a conditional that checks for the presence of the --content-sets argument. We don't need to run this for FCOS at this time.
There was a problem hiding this comment.
Further, maybe it'd be cleaner to make this part of a function in cmdlib.sh and call out to it from prepare_compose_overlays when we detect the YAML file is present.
| extra_compose_args+=("$parent_arg") | ||
|
|
||
| # Convert the yaml file of content_sets to json format | ||
| mkdir -p /srv/buildinfo/ |
There was a problem hiding this comment.
Let's use "${workdir}"/tmp/buildinfo for this location
| mkdir -p ${tmp_overridesdir}/contentsetrootfs/usr/share/buildinfo/ | ||
| echo `jq . /srv/buildinfo/content_manifest.json` > ${tmp_overridesdir}/contentsetrootfs/usr/share/buildinfo/content_manifest.json | ||
| echo -n "Committing ${tmp_overridesdir}/contentsetrootfs... " | ||
| cat ${tmp_overridesdir}/contentsetrootfs/usr/share/buildinfo/content_manifest.json | ||
| ostree commit --repo=$tmprepo --tree=dir=${tmp_overridesdir}/contentsetrootfs -b contentset | ||
| cat >> "${override_manifest}" << EOF | ||
| - contentset | ||
| EOF |
There was a problem hiding this comment.
I think this whole section of code should be conditional on the presence of content_manifest.json
There was a problem hiding this comment.
I'm not sure how this code is supposed to work? The content_manifest.json is cat'ed, then an ostree commit is made, and the override manifest YAML doc has an empty -contentset entry added to it?
There was a problem hiding this comment.
Yes, pretty much but cat content_manifest.json was not necessary. So basically just ostree commit the json file to /usr/share/ and adding -contentset entry to manifest yaml doc.
|
Could you also expand the commit message to provide a bit more context on the "why?" for the change and link to the Jira card as part of it? |
| FORCE_IMAGE= | ||
| SKIP_PRUNE=0 | ||
| VERSION= | ||
| CONTENT_SETS=/srv/redhat-coreos/content_sets.yaml |
There was a problem hiding this comment.
Hmm, we shouldn't hardcode this path.
| STRICT= | ||
| rc=0 | ||
| options=$(getopt --options hft: --longoptions tag:,help,force,version:,parent:,parent-build:,delay-meta-merge,force-nocache,force-image,skip-prune,strict -- "$@") || rc=$? | ||
| options=$(getopt --options hft: --longoptions tag:,help,force,version:,content_sets:,parent:,parent-build:,delay-meta-merge,force-nocache,force-image,skip-prune,strict -- "$@") || rc=$? |
There was a problem hiding this comment.
In general, cosa uses conventions. I was thinking more that instead of passing a --content-sets switch, cosa just does the right thing if it detects that it's present in the configdir.
| fi | ||
| extra_compose_args+=("$parent_arg") | ||
|
|
||
| # Convert the yaml file of content_sets to json format |
There was a problem hiding this comment.
Further, maybe it'd be cleaner to make this part of a function in cmdlib.sh and call out to it from prepare_compose_overlays when we detect the YAML file is present.
|
/retest |
|
FCOS CI is failing on the ShellCheck step |
| else | ||
| rm -vf "${local_overrides_lockfile}" | ||
| fi | ||
| if [ -f /srv/redhat-coreos/content_sets.yaml ]; then |
| if [ -f /srv/redhat-coreos/content_sets.yaml ]; then | ||
| create_content_manifest | ||
| fi | ||
| if [ -f "${workdir}/tmp/buildinfo/content_manifest.json" ]; then |
There was a problem hiding this comment.
Can we combine these? E.g.
if [ -e "${configdir}/content_sets.yaml" ]; then
mkdir -p ...
create_content_manifest /path/to/output.json
...
fi
| echo -n "Committing ${tmp_overridesdir}/contentsetrootfs... " | ||
| ostree commit --repo="$tmprepo" --tree=dir="${tmp_overridesdir}"/contentsetrootfs -b contentset | ||
| cat >> "${override_manifest}" << EOF | ||
| - contentset |
There was a problem hiding this comment.
This needs to go under ostree-layers. So we should probably instead just add it to the layers variable and then move down the block that outputs ostree-layers to after this.
| create_content_manifest(){ | ||
| # Convert the yaml file of content_sets to json format | ||
| mkdir -p "${workdir}"/tmp/buildinfo | ||
| yaml2json /srv/redhat-coreos/content_sets.yaml "${workdir}"/tmp/buildinfo/content_manifest.json |
There was a problem hiding this comment.
Same note here re. hardcoded path. Maybe simpler to have the caller to this function pass in the path to the YAML file.
Re. yaml2json, this is OK, though it doesn't look necessary. We could directly read YAML in the Python code.
| repos=[]; | ||
| for i in data['repo_mapping']: | ||
| for j in data['repo_mapping'][i]: | ||
| if(j=='name'):repos.append(data['repo_mapping'][i][j]) |
There was a problem hiding this comment.
This looks like it's outputting every repo in the file, but instead I think what we want is to parse the flattened manifest and only output the mapped repos which are used.
| # Add the build info to content_manifest.json | ||
| echo $(jq --argjson repos "$REPOS" '. += | ||
| { | ||
| "metadata": { | ||
| "icm_version": 1, | ||
| "icm_spec": "https://raw.githubusercontent.com/containerbuildsystem/atomic-reactor/master/atomic_reactor/schemas/content_manifest.json", | ||
| "image_layer_index": 1 | ||
| }, | ||
| "content_sets": $repos, | ||
| "image_contents": [] | ||
| }' "$workdir"/tmp/buildinfo/content_manifest.json) > "$workdir"/tmp/buildinfo/content_manifest.json |
There was a problem hiding this comment.
Seems like it'd be cleaner to build the file entirely in the Python bits.
| "content_sets": $repos, | ||
| "image_contents": [] | ||
| }' "$workdir"/tmp/buildinfo/content_manifest.json) > "$workdir"/tmp/buildinfo/content_manifest.json | ||
| sed -i "s/\$ARCH/$(arch)/g" "$workdir"/tmp/buildinfo/content_manifest.json |
There was a problem hiding this comment.
Minor: the variable $arch should already be defined and accessible.
miabbott
left a comment
There was a problem hiding this comment.
Tested this locally with RHCOS and it worked great!
Saw the message about the missing repo:
Warning: No corresponding repo in repository-to-cpe.json for rhel-8-fast-datapath-aarch64
Committing /srv/tmp/override/contentsetrootfs... e261cf0d7d1cf17ca3725f83d07da9aebfa3c66ea2d8641d36dd1ffc608d79eb
And the end result looked perfect.
$ cat /usr/share/buildinfo/content_manifest.json
{
"metadata": {
"icm_version": 1,
"icm_spec": "https://raw.githubusercontent.com/containerbuildsystem/atomic-reactor/master/atomic_reactor/schemas/content_manifest.json",
"image_layer_index": 1
},
"content_sets": [
"rhel-8-for-x86_64-baseos-eus-rpms__8_DOT_4",
"rhel-8-for-x86_64-appstream-eus-rpms__8_DOT_4",
"fast-datapath-for-rhel-8-x86_64-rpms",
"rhocp-4.8-for-rhel-8-x86_64-rpms"
],
"image_contents": []
}
The content_sets was missing the NFV repo, but I understand that is only being used for kernel-rt in the extensions. I wonder if we should just include all the repos by default?
I don't think we need to block on that question, as this gets us most of the way there.
I don't think including all the repos would be a good idea but I am open to it if needed. |
|
Also, @miabbott are we still looking to add the symlink so that it is accessible as |
| echo "ostree-layers:" >> "${override_manifest}" | ||
| for layer in ${layers}; do | ||
| echo " - ${layer}" >> "${override_manifest}" | ||
| done |
| create_content_manifest "$configdir"/content_sets.yaml | ||
| mkdir -p "${tmp_overridesdir}"/contentsetrootfs/usr/share/buildinfo/ | ||
| jq . "${workdir}/tmp/buildinfo/content_manifest.json" > "${tmp_overridesdir}/contentsetrootfs/usr/share/buildinfo/content_manifest.json" |
There was a problem hiding this comment.
Could make this clearer by passing the output path to create_content_manifest so it directly writes to the rootfs.
| f.close(); | ||
| repos=[]; | ||
|
|
||
| for baseRepo in $base_repos: |
There was a problem hiding this comment.
Minor: base_repo would be more conventional.
| for i in data['repo_mapping'][baseRepo]: | ||
| if(i=='name'): |
There was a problem hiding this comment.
Hmm, why iterate over the dictionary? Isn't it directly accessible through data['repo_mapping'][baseRepo]['name']?
| if (baseRepo in data['repo_mapping'].keys()): | ||
| for i in data['repo_mapping'][baseRepo]: | ||
| if(i=='name'): | ||
| data['repo_mapping'][baseRepo][i]=data['repo_mapping'][baseRepo][i].replace('\$ARCH', '$(arch)'); |
There was a problem hiding this comment.
Let's use a separate variable to mutate instead of mutating the source data?
| repos.append(data['repo_mapping'][baseRepo][i]) | ||
| else: | ||
| # Printing this warning message till we figure out how to deal with these cases | ||
| print('Warning: No corresponding repo in repository-to-cpe.json for ' + baseRepo) |
There was a problem hiding this comment.
Shouldn't this say content_sets.yaml?
| repos.append(data['repo_mapping'][baseRepo][i]) | ||
| else: | ||
| # Printing this warning message till we figure out how to deal with these cases | ||
| print('Warning: No corresponding repo in repository-to-cpe.json for ' + baseRepo) |
There was a problem hiding this comment.
I wonder if we should tweak the semantics a bit: we include those repos that aren't in repository-to-cpe.json in content_sets.yaml but leave their name as "". Then here, we can warn and skip if the name is empty, otherwise explicitly error out. This ensures that if the set of manifest repo names changes, we're not just going to forget to update content_sets.yaml.
Another way to say this: we require that every repo in the manifest must have an entry in content_sets.yaml.
There was a problem hiding this comment.
Agree with it.
I was thinking we could have two different warning messages;
- one for the repos with
""as theirnamein yaml file - and another one if their is no entry for a
base_repoin the yaml file itself. This would help us to add an entry to the YAML file in case we miss one in the yaml file in the future.
| for i in data['repo_mapping'][baseRepo]: | ||
| if(i=='name'): | ||
| data['repo_mapping'][baseRepo][i]=data['repo_mapping'][baseRepo][i].replace('\$ARCH', '$(arch)'); | ||
| repos.append(data['repo_mapping'][baseRepo][i]) |
There was a problem hiding this comment.
Ideally here we'd be checking that the baseurls match. This would require parsing the repo files though. We can skip this for now.
| mkdir -p "${workdir}"/tmp/buildinfo | ||
| base_repos=$(jq .repos "${manifest_tmp_json}") | ||
| # Make an empty json file in tmp/buildinfo/ | ||
| echo {} > "$workdir"/tmp/buildinfo/content_manifest.json |
There was a problem hiding this comment.
Shouldn't need this since we should always be creating a JSON file by the end.
|
Also, maybe for the commit message, something like: "cmd-build: add support for |
jlebon
left a comment
There was a problem hiding this comment.
Some minor comments, but mostly LGTM! Looks like
Also should include a body containing a bit of context on why we're doing this and if needed links to more context.
still needs to be addressed.
| fi | ||
| done | ||
| rm -f "${manifest_tmp_json}" | ||
|
|
There was a problem hiding this comment.
Minor: spurious line deletion hunk.
| python3 -c " | ||
| import json, yaml; | ||
| # Open the yaml and load the data | ||
| f = open('$1') |
There was a problem hiding this comment.
Instead of using $1 and $2 like this, let's declare some local variables upfront at the beginning of the function with clearer names.
|
|
||
| create_content_manifest(){ | ||
| mkdir -p "${workdir}"/tmp/buildinfo | ||
| rpm-ostree compose tree --repo="${tmprepo}" --print-only "${manifest}" > "${manifest_tmp_json}" |
There was a problem hiding this comment.
Let's set manifest_tmp_json ourselves here as a local variable (and the manifest_tmp_json in prepare_build should probably also be local).
There was a problem hiding this comment.
Alternatively, we can formalize this as part of prepare_build and not delete the treefile like you had before but name the variable something like flattened_manifest and explicitly export it the same way we export manifest. Then here we can reuse it instead of rerunning rpm-ostree compose tree. Anyway, not a blocker!
| print('Warning: No corresponding repo in repository-to-cpe.json for ' + base_repo) | ||
| else: | ||
| # Warning message for repositories with no entry in content_sets.yaml | ||
| print('Warning: No corresponding entry in content_sets.yaml for ' + base_repo) |
There was a problem hiding this comment.
What I meant here is that we explicitly error out, but OK with this too to start. We can always tighten things later.
Actually, this is probably better for the developer case. So it's a good default and then we could add a switch for more stricter handling in production pipelines, a bit like how it is for lockfiles.
There was a problem hiding this comment.
Keeping as it for now.
| cmdlib.import_ostree_commit('${workdir:-$(pwd)}/tmp/repo', builddir, buildmeta) | ||
| ") | ||
| } | ||
| } No newline at end of file |
There was a problem hiding this comment.
Minor: looks like we're eating the file's final newline here.
| source_file=$1 | ||
| destination=$2 |
There was a problem hiding this comment.
Minor: these should be local. Not worth the respin though.
-Adding the buildindfo data to the json file to be able to identify which repos were used to build RHCOS. These changes will map the repos used to their respective pulp repository IDs from content_sets.yaml. - Issue: https://issues.redhat.com/browse/COS-54
Make a helper for committing OSTree layers which contains all the canonicalization flags. Notably `--timestamp` which ensures that we get a consistent checksum for the same source git commit. Fixes: openshift/os#712 Fixes: coreos#2603
Make a helper for committing OSTree layers which contains all the canonicalization flags. Notably `--timestamp` which ensures that we get a consistent checksum for the same source git commit. Fixes: openshift/os#712 Fixes: #2603
Make a helper for committing OSTree layers which contains all the canonicalization flags. Notably `--timestamp` which ensures that we get a consistent checksum for the same source git commit. Fixes: openshift/os#712 Fixes: coreos#2603
Make a helper for committing OSTree layers which contains all the canonicalization flags. Notably `--timestamp` which ensures that we get a consistent checksum for the same source git commit. Fixes: openshift/os#712 Fixes: coreos#2603
Make a helper for committing OSTree layers which contains all the canonicalization flags. Notably `--timestamp` which ensures that we get a consistent checksum for the same source git commit. Fixes: openshift/os#712 Fixes: #2603
Make a helper for committing OSTree layers which contains all the canonicalization flags. Notably `--timestamp` which ensures that we get a consistent checksum for the same source git commit. Fixes: openshift/os#712 Fixes: coreos#2603 (cherry picked from commit 3fac918) dustymabe: This cherry pick needed manual merge conflict resolution. No contentsets in 4.9.
Make a helper for committing OSTree layers which contains all the canonicalization flags. Notably `--timestamp` which ensures that we get a consistent checksum for the same source git commit. Fixes: openshift/os#712 Fixes: #2603 (cherry picked from commit 3fac918) dustymabe: This cherry pick needed manual merge conflict resolution. No contentsets in 4.9.
Make a helper for committing OSTree layers which contains all the canonicalization flags. Notably `--timestamp` which ensures that we get a consistent checksum for the same source git commit. Fixes: openshift/os#712 Fixes: #2603 (cherry picked from commit 3fac918) dustymabe: This cherry pick needed manual merge conflict resolution. No contentsets in 4.9.
We are adding the buildindfo data to the json file to be able to identify which repos were used to build RHCOS. The repo names used in manifest would match names in reposistory-to-CPE.json published by Red Hat
Got buildinfo from
content_sets.yamlwhich resides underredhat-coreosrepo and is copied over tosrc/config/. Extracted the repo names and mapped to their corresponding pulp repository IDs to add it to ourcontent_manifest.jsonfor buildinfo. The filecontent_manifest.jsonwill be available under/usr/share/buildinfo/aftercmdlib.shrunning is completed.Issue: https://issues.redhat.com/browse/GRPA-3731
Discussion: #2540