-
Notifications
You must be signed in to change notification settings - Fork 23
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: fail if users try to run managed builds that would use a nonfunctional container #720
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. Seems possible to get this done with or without the loopback executor. I'd like to get @lengau's opinion on that, since he was talking about this when architecting craft-application.
Yeah you could. Taking a fresh look at it today I see a good way to refactor |
@mr-cal I think this is better, going this route and removing loopback executor unless you disagree: d2ff086 |
Also: - Fix text return for server version - Don't patch every BuilddBase, because that causes other BuilddBases to become MagicMocks, which breaks the issubclass check in ensure_guest_compatible. - Moved check obviates need for get_server_version calls
craft_providers/bases/ubuntu.py
Outdated
# between cgroupv1 and v2 support. | ||
# https://discourse.ubuntu.com/t/lxd-5-0-4-lts-has-been-released/49681#p-123331-support-for-ubuntu-oracular-containers-on-cgroupv2-hosts | ||
if ( | ||
host_base_alias > BuilddBaseAlias.FOCAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not keen on having this be such an Ubuntu-specific solution. We should be able to make the logic generic and just have a data set that we can add to for managing this. For example:
BASE_MINIMUM_REQUIREMENTS = {
BuilddBaseAlias.ORACULAR: {
"lxd": [(5, 0, 4), (5, 21, 2)],
"kernel": [(5, 15)],
},
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, this design would let us make changes in the future without needing to refactor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can make this change, but it does seem to me like we may be making this too generic.
If I do, then this data structure would really need to look like is something like this:
INVALID_VERSIONS = [
{
"host": BuilddBase.FOCAL,
"guest": BuilddBase.ORACULAR,
"lxd":
{
(4,): (float('inf'), float('inf')), # everything 4.x and below fails
(5, 0): (4,),
(5, 21): (2,),
(6,): (float('-inf'), float('-inf')), # everything 6.x and above passes
},
"kernel": [(5, 15)],
This way, your logic can say something like (pseudocode):
for invalid in INVALID_VERSIONS:
if host > invalid.host or guest < invalid.guest:
continue
lxd_version_in_family = lxd_version_match(lxd_version, invalid.lxd.keys())
if not lxd_version_in_family:
# Current lxd version doesn't match any of the keys
continue
# This is a lxd version that may be affected by the bug
if lxd_version_fail(lxd_version, lxd_version_in_family):
raise Ex('You need a newer lxd for this host/guest')
if kernel < invalid.kernel:
raise Ex('You need a newer kernel for this host/guest')
Since you and Callahan both agreed that it should look something like this, I'll start down this path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*Not exactly like that, I'm refining this design as I implement, but this is the gist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this is getting complex fast. Seems like we need a class or library to handle versioning more cleanly. I'd be fine to leave is as you originally implemented.
Also, this code may not be long-lived. It's going to be increasingly rare for someone to use these older minor versions of lxd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mr-cal The code I've got right now is working out a little more cleanly than the above would suggest, mainly by making some non-generic assumptions about lxd versions. I wasn't sold on this approach before, but I think what I'm settling on now is better - look for an update shortly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we forget about 5.0.4 and just check if the version tuple >= (5, 21, 2)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lengau, what's your rationale for 5.21 and not 5.0? Both are LTS versions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mr-cal my rationale is that anything after 5.21.2 works, but some things greater than 5.0.4 don't work.
craft_providers/bases/ubuntu.py
Outdated
if lxd_major == 5: | ||
# Major is 5, we care about patch versions given the minor | ||
if lxd_minor == 0 and lxd_patch < 4: | ||
raise lxd_exception |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can detect both the lxd version issue and the kernel version issue in one run and raise both problems simultaneously.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this is probably the pattern I'll move towards. The error messages will be a little less specific, but I think that's an acceptable tradeoff here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. Please re-request me after addressing Alex's comments
craft_providers/bases/ubuntu.py
Outdated
raise lxd_exception | ||
if lxd_minor == 21 and lxd_patch < 2: | ||
raise lxd_exception | ||
if lxd_major < 5: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if lxd_major < 5: | |
elif lxd_major < 5: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic will go away with the generic design Alex suggested above.
craft_providers/bases/ubuntu.py
Outdated
# between cgroupv1 and v2 support. | ||
# https://discourse.ubuntu.com/t/lxd-5-0-4-lts-has-been-released/49681#p-123331-support-for-ubuntu-oracular-containers-on-cgroupv2-hosts | ||
if ( | ||
host_base_alias > BuilddBaseAlias.FOCAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, this design would let us make changes in the future without needing to refactor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm +1 for your new design, readable and seems simpler since it separates this particular cgroups bug away from the if/else statements.
""" | ||
|
||
|
||
INVALID_VERSIONS = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, this is very readable
(5, 0, 4), | ||
(5, 21, 2), | ||
], | ||
"kernel_less_than": (5, 15), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about making this a list of triples as well and using the same function for matching lxd and kernels?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That symmetry would be sort of nice, but the complexity of the lxd logic isn't necessary for the kernel. We can't reason about any minor lxd versions under 5.x other than those listed, so we don't fail them. The kernel, on the other hand, is just a straight-up linear cutoff at 5.15.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not necessary now, but it could be necessary in the future, especially given OEM kernels.
tox
?New LXD versions were released that fix an issue we've seen where a mismatch between the support for cgroupsv1 and v2 between host and guest causes the container's systemd to become partially nonfunctional. Add checks to fail with a good error message if a user's system would launch such a container.
(CRAFT-3096)