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

✨ OpenStackImage controller #2130

Merged
merged 2 commits into from
Aug 13, 2024

Conversation

mdbooth
Copy link
Contributor

@mdbooth mdbooth commented Jun 21, 2024

A new controller for creating glances images. Will initially support creation
from a remote URL including:

  • Validation of downloaded data by verifying a hash
  • Decompression of downloaded data

It supports both glance-direct and web-download, although because the feature set of web-download is limited it will only be used if no hash verification or decompression is required.

This controller uses server-side apply and uses applyconfigurations generated by code-gen added in #2133.

The controller is implemented as the first of a new generation of https://k-orc.cloud/ controller. We also incubate the ORC project as a subdirectory of CAPO until it's ready to be split out.

TODO:

/hold

@k8s-ci-robot
Copy link
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@k8s-ci-robot k8s-ci-robot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 21, 2024
Copy link

netlify bot commented Jun 21, 2024

Deploy Preview for kubernetes-sigs-cluster-api-openstack ready!

Name Link
🔨 Latest commit 3090a6c
🔍 Latest deploy log https://app.netlify.com/sites/kubernetes-sigs-cluster-api-openstack/deploys/66b5fd5d3d286b0008b90e07
😎 Deploy Preview https://deploy-preview-2130--kubernetes-sigs-cluster-api-openstack.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.


// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=10
type ImageContainerFormat string

Choose a reason for hiding this comment

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

Is this actually an enum? Or can this vary OSP to OSP? Formats typically are enums

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is an enum, but unfortunately strictly speaking I think it's variable. Same for disk format.

In practise nobody's ever actually going to use this at all, only disk format. I almost took it out entirely.

I may revisit this once I've got an initial implementation. Perhaps be opinionated with a pragmatic set of formats (for both this and disk format).


// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
type ImageTag string

Choose a reason for hiding this comment

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

Can this be regexed or refined to a particular character set?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The docs don't specify one, only a maximum length. I'd have to check the code to determine if there are any other practical constraints. It's not impossible, as the docs suck.

@stephenfin can you think of any reason this wouldn't just be utf-8?

// +kubebuilder:validation:MaxLength:=10
type ImageDiskFormat string

// kubebuilder:validation:Enum:=public;private;shared;community

Choose a reason for hiding this comment

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

Kube APIs use PascalCase for enums, even if the backing implementation needs a translation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ack. That would presumably also apply to the hash algorithms.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

FYI I initially made this change, then after I'd lived with it for a while I reverted it. I did this because I found myself having to write conversions for every one of these in code, and realising that users will also mentally have to do the same thing. This is a proxy API, so these strings only have meaning in OpenStack glance, which is the documentation a user is most likely to be looking at when working out what to put here. If I Pascal-ise them, they also need to mentally translate the glance value to whatever I picked here.

I think it's a case of 'pick what you're going to be inconsistent with'. I think following the API we're proxying is less bad here.

// kubebuilder:validation:Enum:=public;private;shared;community
type ImageVisibility string

// kubebuilder:validation:Enum:=md5;sha1;sha256;sha512

Choose a reason for hiding this comment

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

Use PascalCase

ImageHashAlgorithmSHA512 ImageHashAlgorithm = "sha512"
)

// +kubebuilder:validation:XValidation:rule="!in(self, ['created_at', 'updated_at', 'status', 'checksum', 'size', 'virtual_size', 'direct_url', 'self', 'file', 'schema', 'id', 'os_hash_algo', 'os_hash_value', 'location', 'deleted', 'deleted_at', 'container_format', 'disk_format', 'min_disk', 'min_ram', 'name', 'tags', 'owner', 'visibility', 'protected', 'os_hidden'])"

Choose a reason for hiding this comment

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

Would be better to use Kube like constants and translate to OSP like constants on the backend

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are truly free-form. They're just going to be merged without translation into the OpenStack request.

As discussed I'll look into removing this entirely in favour of an opinionated set of properties, at least until a customer comes to us with a request for an escape hatch.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I decided to remove this entirely in favour of an opinionated set. I considered leaving AdditionalProperties as an escape hatch, but I'm going to try without it for now.

// DiskFormat is the format of the disk image.
// Normal values are "qcow2", or "raw". Glance may be configured to support others.
// +optional
DiskFormat *ImageDiskFormat `json:"diskFormat,omitempty"`

Choose a reason for hiding this comment

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

Enum-able?

// Protected specifies that the image is protected from deletion.
// If not specified, the default is false.
// +optional
Protected *bool `json:"protected,omitempty"`

Choose a reason for hiding this comment

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

Eww, bools. Suggest to use an enum instead that could be expanded in the future if, for example, you needed to support something like ProtectedWithPassword or ProtectedWithPrivateKey or something

Copy link
Contributor Author

@mdbooth mdbooth Jun 21, 2024

Choose a reason for hiding this comment

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

This is a bool in the glance API, and it actually means 'Not Deletable'. I think this one's ok.


// Tags is a list of tags which will be applied to the image. A tag has a maximum length of 255 characters.
// +optional
Tags []ImageTag `json:"tags,omitempty"`

Choose a reason for hiding this comment

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

Need an SSA listType tag, is this a map list with a key? Else mark explicitly as atomic

Comment on lines 180 to 395
// SizeB is the size of the image data, in bytes
SizeB *int64 `json:"sizeB,omitempty"`

Choose a reason for hiding this comment

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

Why not make this something that's going to be more human readable? Bytes will be a large number, what about KB or something larger with a small amount of rounding?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually think all APIs should use bytes for everything and translate only on input or display.

For this, it's a value that's directly given to us by the underlying API. I'd probably leave it alone in case anybody is expecting to be able to do a comparison with it.

// +patchStrategy=merge
// +listType=map
// +listMapKey=type
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`

Choose a reason for hiding this comment

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

Idiomatically the conditions should be the first item in the list. Don't need the protobuf marker on this line either

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd wondered about the protobuf thing! Also patchMergeKey and patchStrategy.

I'll take them out, but it's probably worth noting that I copied them from the docstring of the Condition struct: https://github.com/kubernetes/kubernetes/blob/7060e485694e82698c050a6a6c6ae2af20cf5e57/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L1517-L1528

@k8s-ci-robot k8s-ci-robot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jul 10, 2024
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 10, 2024
@mdbooth mdbooth marked this pull request as ready for review July 11, 2024 06:01
@k8s-ci-robot k8s-ci-robot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. and removed do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. labels Jul 11, 2024
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 15, 2024
@mdbooth mdbooth force-pushed the imagecontroller branch 2 times, most recently from 32f1a02 to fc5c870 Compare July 15, 2024 15:18
@jichenjc
Copy link
Contributor

/test pull-cluster-api-provider-openstack-e2e-test

@mdbooth
Copy link
Contributor Author

mdbooth commented Jul 18, 2024

/test pull-cluster-api-provider-openstack-e2e-full-test

@mdbooth mdbooth force-pushed the imagecontroller branch 3 times, most recently from 006641e to d68dda6 Compare July 18, 2024 11:54
@mdbooth mdbooth changed the title Add OpenStackImage API and scaffolding ✨ OpenStackImage controller Jul 25, 2024
@EmilienM
Copy link
Contributor

We spent some time with Matt pair reviewing this PR.
My comments (non blocking this PR but for later):

  • missing integration with the OpenStackMachine controller and this means the user will have to handle the images first before their machines / clusters with bastion.
  • missing config documentation

Otherwise this is really good work, I think this is ready to go and we can iterate later. Thanks for this huge effort!

/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: EmilienM

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 26, 2024
@mdbooth mdbooth force-pushed the imagecontroller branch 10 times, most recently from a6de868 to 4420a30 Compare August 8, 2024 15:04
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 9, 2024
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 9, 2024
This commits creates a new home for ORC, initially incubated in CAPO.
The initial implementation of ORC has an image controller.

The image controller is integrated with OpenStackServer and from there
into both OpenStackMachine and the bastion.

The E2E tests are updated to use the new image controller. Images are
now loaded dynamically by the test suite.
@EmilienM
Copy link
Contributor

@pierreprinetti would you mind LGTM if you agree with this PR?

@pierreprinetti
Copy link
Contributor

Thank you @mdbooth for your initiative of coding the OpenStackImage API as a building block of ORC.

I see that this PR goes out of its way to make the future migration of this code into its natural repository as painless as possible, and I do see benefit in it being incubated here.

As discussed out of band:

  • ORC code must not depend on CAPO code
  • as a matter of fact, the OpenStackImage controller lives in CAPO and depends on CAPO's Gophercloud wrappers
    • (Gophercloud v3 functions should accept the ServiceClient as an interface. This change should remove the need for the wrappers and the CAPO dependency with it)
  • the development of ORC will happen here as long as it can continue unencumbered AND at the same time CAPO needs frequent side-by-side changes in both ORC and CAPO. This requirement is likely to rapidly vanish once we move ORC-related controllers to ORC.

With this, I am happy to leave my
/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 13, 2024
@EmilienM
Copy link
Contributor

/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 13, 2024
@k8s-ci-robot k8s-ci-robot merged commit 90da86d into kubernetes-sigs:main Aug 13, 2024
9 checks passed
@pierreprinetti pierreprinetti deleted the imagecontroller branch August 13, 2024 21:54
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. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

6 participants