Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: build and push image index #81

Merged
merged 2 commits into from
Mar 28, 2024
Merged

Conversation

codingben
Copy link
Member

@codingben codingben commented Feb 8, 2024

What this PR does / why we need it:

Push an image index to have multiple image manifests, instead of single image manifest when needed.

Jira-Url: https://issues.redhat.com/browse/CNV-38597

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):

Fixes #80

Release note:

Build and push image index

@kubevirt-bot kubevirt-bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. dco-signoff: yes Indicates the PR's author has DCO signed all their commits. labels Feb 8, 2024
@codingben codingben marked this pull request as draft February 8, 2024 18:57
@kubevirt-bot kubevirt-bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 8, 2024
artifacts/centos/centos.go Outdated Show resolved Hide resolved
@zhlhahaha
Copy link

Hi @codingben it is a good start, feel free to tell me if I can provide any help, I will review and verify the PR once the draft have done.
In terms of generate and publish multi-arch manifest, here is an shell script. https://github.com/kubevirt/kubevirtci/blob/main/cluster-provision/images/vm-image-builder/publish-multiarch-containerdisk.sh

@codingben
Copy link
Member Author

Hi @codingben it is a good start, feel free to tell me if I can provide any help, I will review and verify the PR once the draft have done. In terms of generate and publish multi-arch manifest, here is an shell script. https://github.com/kubevirt/kubevirtci/blob/main/cluster-provision/images/vm-image-builder/publish-multiarch-containerdisk.sh

Thanks a lot, it's really appreciated and helpful. I'll keep you updated once we have something to review here.

Makefile Outdated Show resolved Hide resolved
artifacts/centos/centos.go Outdated Show resolved Hide resolved
artifacts/centos/centos.go Outdated Show resolved Hide resolved
pkg/build/build.go Outdated Show resolved Hide resolved
@codingben
Copy link
Member Author

@0xFelix What do you think about just implementing image index functionality here, to push it via existing pipelines, and then open another PR to add arm64 image manifests?

@0xFelix
Copy link
Member

0xFelix commented Feb 26, 2024

IMO you can do it in a single PR, until then let's stick to our simple manifest without indexes.

@codingben codingben force-pushed the CNV-37406 branch 2 times, most recently from a4f4ac8 to 2ffb72a Compare February 28, 2024 09:19
@codingben
Copy link
Member Author

Hi @0xFelix, it's ready to be reviewed. I'll run local tests now. After it, I'll work on adding arm64 images (in another commit in this PR).

@codingben codingben marked this pull request as ready for review February 28, 2024 09:44
@kubevirt-bot kubevirt-bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 28, 2024
@kubevirt-bot kubevirt-bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 27, 2024
@@ -100,7 +104,7 @@ func gatherArtifacts(registry *[]Entry, gatherers []api.ArtifactsGatherer) {
} else {
for i := range artifacts {
*registry = append(*registry, Entry{
Artifact: artifacts[i],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That still looks wrong. The gatherer needs to return artifacts with multiple architectures and this loop needs to append them to the registry. (Artifacts: artifacts[i])

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you reviewed old revision. This is how it looks like today:

func gatherArtifacts(registry *[]Entry, gatherers []api.ArtifactsGatherer) {
	for _, gatherer := range gatherers {
		artifacts, err := gatherer.Gather()
		if err != nil {
			logrus.Warn("Failed to gather artifacts", err)
		} else {
			for i := range artifacts {
				*registry = append(*registry, Entry{
					Artifacts:    []api.Artifact{artifacts[0][i]},
					UseForDocs:   i == 0,
					UseForLatest: i == 0,
				})
			}
		}
	}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed the "left" side. The new is still wrong, since like this it probably run out of range. i is a range over the outer slice and you use it to access the inner slice. The artifacts returned by the gatherer should be [][]api.Artifact, then you can set each outer slice item as []api.Artifact in the loop below with artifacts[i]. IMO the gatherer should construct the multi-arch Artifact already. Like this you end up with a separate artifact for each architecture and version.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah got it, thanks Felix! :)

@codingben
Copy link
Member Author

@codingben PR needs rebase

I see. I wasn't able to produce image index with OCI yet, I'll continue debugging it tomorrow.

It seems like it's producing and pushing OCI image index, but the container registry locally shows it as Docker schema and not OCI.

I'm trying to push the image index to Quay directly, but there is an error of unauthorized access to Quay during running Medius (either push or promote).

Seems like remote.WithAuthFromKeychain(authn.DefaultKeychain) was missing in the options in PushImageIndex, but even then after adding it, it still returns an unauthorized error.

@codingben
Copy link
Member Author

Found another issue with uploads to quay.io:

felix@felix-p1 kubevirt/containerdisks (CNV-37406) » ./bin/medius images promote --dry-run=false --source-registry="$(./hack/kubevirtci.sh registry)" --target-registry=quay.io/fmatouschek --insecure-skip-tls --workers 3 --focus=cirros:6.1
INFO[0000] Copying localhost:45677/cirros:6.1-2403211715 -> quay.io/fmatouschek/cirros:6.1-2403211715  name=cirros version=6.1
ERRO[0018] Failed to copy image                          error="PUT https://quay.io/v2/fmatouschek/cirros/manifests/6.1-2403211715: MANIFEST_INVALID: manifest invalid; map[message:Unknown or unsupported manifest media type `application/vnd.docker.distribution.manifest.v2+json` not found in dict_keys(['application/vnd.oci.image.manifest.v1+json', 'application/vnd.oci.image.index.v1+json'])]" name=cirros version=6.1
ERRO[0018] PUT https://quay.io/v2/fmatouschek/cirros/manifests/6.1-2403211715: MANIFEST_INVALID: manifest invalid; map[message:Unknown or unsupported manifest media type `application/vnd.docker.distribution.manifest.v2+json` not found in dict_keys(['application/vnd.oci.image.manifest.v1+json', 'application/vnd.oci.image.index.v1+json'])]  name=cirros version=6.1
INFO[0018] Writing results file                         
FATA[0018] PUT https://quay.io/v2/fmatouschek/cirros/manifests/6.1-2403211715: MANIFEST_INVALID: manifest invalid; map[message:Unknown or unsupported manifest media type `application/vnd.docker.distribution.manifest.v2+json` not found in dict_keys(['application/vnd.oci.image.manifest.v1+json', 'application/vnd.oci.image.index.v1+json'])]

We need to update medius so it creates OCI image manifests and image indexes. Can you do that as a follow up first before continuing feature work please?

@0xFelix Can you please check if you tried to push an image index, or just single image manifest? Because I'm getting an unauthorized error when trying to push a new image index to Quay.

@codingben
Copy link
Member Author

@0xFelix I can confirm that I was able to push image index, the issue was that it required to run Medius with sudo locally so it can get an access to read ./docker folder. It was complaining about unauthorized error and not about permission denied - seems like a bug in the go-containerregistry library.

@0xFelix
Copy link
Member

0xFelix commented Mar 28, 2024

@0xFelix I can confirm that I was able to push image index, the issue was that it required to run Medius with sudo locally so it can get an access to read ./docker folder. It was complaining about unauthorized error and not about permission denied - seems like a bug in the go-containerregistry library.

IMO this is very specific to Mac OS on which you are running medius on. Mac OS is known to deny access to files in the home directory if not explicitly allowed.

@codingben
Copy link
Member Author

This PR is affected by this issue: containers/podman#22196 - We're not able to pull OCI image index via Podman, only Docker works correctly.

@codingben codingben force-pushed the CNV-37406 branch 2 times, most recently from c39ddf6 to 62c2f39 Compare March 28, 2024 11:54
@codingben
Copy link
Member Author

codingben commented Mar 28, 2024

@0xFelix I've tested push to local registry and promote it from there to Quay container registry - It works without issues:

╰─$ sudo ./bin/medius images promote --dry-run=false --source-registry="localhost:5000" --target-registry=quay.io/boukhano --insecure-skip-tls --focus=cirros:6.1 --results-file="results.json"
INFO[0001] Copying localhost:5000/cirros:6.1-2403281407 -> quay.io/boukhano/cirros:6.1-2403281407  name=cirros version=6.1
INFO[0014] Copying localhost:5000/cirros:6.1-2403281407 -> quay.io/boukhano/cirros:6.1  name=cirros version=6.1
INFO[0016] Writing results file 

Also podman pull works:

╰─$ sudo podman pull quay.io/boukhano/cirros:6.1                                                                                                          125 ↵
Trying to pull quay.io/boukhano/cirros:6.1...
Getting image source signatures
Copying blob sha256:982946d114cde2b91f867a5149ef078a2a5859c61769c5b495225d4fc4cd1ed0
Copying config sha256:b5af4dd60abc4e54a1acb5dd96d7e01a7890986c8b0973984296f29c4977e40c
Writing manifest to image destination
b5af4dd60abc4e54a1acb5dd96d7e01a7890986c8b0973984296f29c4977e40c

╰─$ sudo podman manifest inspect quay.io/boukhano/cirros:6.1 --tls-verify=false                                                                           125 ↵
{
    "schemaVersion": 2,
    "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
    "manifests": [
        {
            "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
            "size": 428,
            "digest": "sha256:3e2529ebfa5b79f2b10922b68b6a03e37d1f628536ce8e060892a31a15ac48f6",
            "platform": {
                "architecture": "amd64",
                "os": "linux"
            }
        },
        {
            "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
            "size": 428,
            "digest": "sha256:a30c9e081851feb38a90415d9dfab742faed9dd5db9df2bcef8a066af87623b1",
            "platform": {
                "architecture": "arm64",
                "os": "linux"
            }
        }
    ]
}

@codingben
Copy link
Member Author

/unhold

It works now - I've tested changes locally by pushing and promoting it to Quay container registry. Thanks @0xFelix :)

@kubevirt-bot kubevirt-bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Mar 28, 2024
@codingben
Copy link
Member Author

Unit tests should work now. Forgot to update fedora_test.go.

codingben and others added 2 commits March 28, 2024 15:14
Push an image index to have multiple
image manifests, instead of single image
manifest when needed.

Jira-Url: https://issues.redhat.com/browse/CNV-38597
Signed-off-by: Ben Oukhanov <boukhanov@redhat.com>
Empty image sets Docker manifest schema
and not OCI. Image manifests included in
OCI image index, and to keep consistency
all of them should have Docker media types.

Signed-off-by: Ben Oukhanov <boukhanov@redhat.com>
@0xFelix
Copy link
Member

0xFelix commented Mar 28, 2024

Thanks @codingben, to me it looks good!

@ksimon1 can you give this a final review please?

@codingben
Copy link
Member Author

@ksimon1 @akrejcir @jcanocan @lyarwood Hi, I'd appreciate /lgtm unless there is functionality that is broken. I also tested the code changes and it works, and I can improve code in another PR if needed.

@codingben
Copy link
Member Author

/test pull-containerdisks-test

@codingben
Copy link
Member Author

Hi @codingben it is a good start, feel free to tell me if I can provide any help, I will review and verify the PR once the draft have done. In terms of generate and publish multi-arch manifest, here is an shell script. https://github.com/kubevirt/kubevirtci/blob/main/cluster-provision/images/vm-image-builder/publish-multiarch-containerdisk.sh

@zhlhahaha Hi, can you please review? we're missing /lgtm label here.

@ksimon1
Copy link
Member

ksimon1 commented Mar 28, 2024

/lgtm

@kubevirt-bot kubevirt-bot added the lgtm Indicates that a PR is ready to be merged. label Mar 28, 2024
@kubevirt-bot kubevirt-bot merged commit b48a3cd into kubevirt:main Mar 28, 2024
9 checks passed
@zhlhahaha
Copy link

/lgtm
Thanks @codingben

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. dco-signoff: yes Indicates the PR's author has DCO signed all their commits. lgtm Indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ARM containerdisks
6 participants