-
Notifications
You must be signed in to change notification settings - Fork 45
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: Check init tasks #478
Commits on Jul 10, 2024
-
feat: Make the launcher aware of cloud-init
This affects only the registration time. Subsequent boots don't check for cloud-init in any way. We check if there is a `cloud-init` command in PATH, and launch `cloud-init status --wait` right after registration is complete. This will wait until cloud-init completes what's doing or report error/disabled states. Cloud-init could have created Linux user accounts. Users could have been created in many other ways, even pre-created during image build. We expect the desired default user to be set via `/etc/wsl.conf`. That would work even without the distro launcher, so it's reasonable to assume the desired default to be present there. We "parse" that file and, if there is the default user entry, then we set it via WSL API (which is faster than terminanting and restarting the instance). When "parsing" /etc/wsl.conf (which is INI like syntax), we deliberately stop on the first occurence of the [section].key we're looking for. That matches the behavior observed in WSL itself. If we don't find a default user set, we check if the current default user is still root, in which case we look for any non-system user in the NSS passwd database (by launching getent), i.e. any user with UID between 1000 and 65534 (the nobody). Finally, we fallback to the interative user creation, i.e. the default upstream prompting. We do some effort to keep /etc/wsl.conf and the Windows registry (via WSL API) in sync, in the sense that whatever user we set as default via one means we also set in the other. I originally intended to put this implementation inside DistributionInfo.h/cpp to ensure less files being touched (thus less diff compared to upstream) but that doesn't play nice with CI 'Refresh releases and assets' workflow. So I placed the code in its own component, and inside a subdirectory, so if there comes a time we need to revert that change (it becomes obsolete or so) it remains easy to drop. Also, being inside a subdirectory allows me to drop a .clang-format in there without worrying of reformatting upstream code :) Lessons learned from the launcher old times: - We can put cpp files inside a subdirectory and still work with precompiled headers in Visual Studio if we either adjust the include path for every cpp file or adjust the path to the precompiled header for every cpp file (no winner :) )
Configuration menu - View commit details
-
Copy full SHA for b1b6b3c - Browse repository at this point
Copy the full SHA b1b6b3cView commit details -
Configuration menu - View commit details
-
Copy full SHA for 23f99fd - Browse repository at this point
Copy the full SHA 23f99fdView commit details -
Configuration menu - View commit details
-
Copy full SHA for 4baff0e - Browse repository at this point
Copy the full SHA 4baff0eView commit details -
Remove e2e test relying on the OOBE
And unnecessary assertion for empty stdout That's never the case.
1Configuration menu - View commit details
-
Copy full SHA for 8b7663b - Browse repository at this point
Copy the full SHA 8b7663bView commit details -
For now that's all we need from the golden testutils we have everywhere else.
1Configuration menu - View commit details
-
Copy full SHA for 679dd52 - Browse repository at this point
Copy the full SHA 679dd52View commit details -
It assumed distroName to match the AppID Which is not the case. Ubuntu24.04LTS is the AppID for the distroName Ubuntu-24.04. Thus we need to check for Ubuntu-WX.YZ :) This is yet a bit tricky because nowadays we set the policy during image build, So a rootfs meant to build an LTS app (thus Prompt=never) could be recycled to build Ubuntu-Preview during tests and that would break the assertion. TODO: Verify if CI is happy with just this change.
1Configuration menu - View commit details
-
Copy full SHA for fe75ee5 - Browse repository at this point
Copy the full SHA fe75ee5View commit details -
To check whether a file exists in the distro filesystem.
Configuration menu - View commit details
-
Copy full SHA for 8d64885 - Browse repository at this point
Copy the full SHA 8d64885View commit details -
We can now specify if we want the user to be root or not.
s/testUserNotRoot/testWhetherUserIsRoot Parameterized :)
Configuration menu - View commit details
-
Copy full SHA for a6f7ac9 - Browse repository at this point
Copy the full SHA a6f7ac9View commit details -
To allow reusing those test helpers inside testcases It pessimizes the existing TestBasicSetup a little bit But it's for a good reason.
Configuration menu - View commit details
-
Copy full SHA for 8a147a5 - Browse repository at this point
Copy the full SHA 8a147a5View commit details -
Implements tests that rely on cloud-init
Every testcase wipes out the WSL instance So not a lot can run in a reasonable way in CI Let's see how long those two will take. We use `<launcher.exe> install` to avoid the interactive shell in the end. If we append `--root` then the launcher should still wait for cloud-init but skip checking the creation of the default user. We check for the specific user set as default, different combinations of cloud-config may create users in different order and set or not in /etc/wsl.conf. This way we check if the launcher does the right thing even without /etc/wsl.conf and if it skips doing anything else when `install --root`.
Configuration menu - View commit details
-
Copy full SHA for 3b4636a - Browse repository at this point
Copy the full SHA 3b4636aView commit details -
Runs all existing tests and increase timeout
We have more to do It's reasonable to assume it will take longer :)
Configuration menu - View commit details
-
Copy full SHA for 2ed7d6e - Browse repository at this point
Copy the full SHA 2ed7d6eView commit details -
End-to-end tests with the latest LTS
Temporarily at least, as we don't have oracular images yet.
Configuration menu - View commit details
-
Copy full SHA for 2a46c82 - Browse repository at this point
Copy the full SHA 2a46c82View commit details -
Configuration menu - View commit details
-
Copy full SHA for fe16135 - Browse repository at this point
Copy the full SHA fe16135View commit details -
Add a TODO to use the Ubuntu app in end-to-end tests
once we have backported everything and Ubuntu is transitionned to 24.04
Configuration menu - View commit details
-
Copy full SHA for 5ace6b7 - Browse repository at this point
Copy the full SHA 5ace6b7View commit details -
Comments to clarify the search for the default user
Making sure to explain how we indirectly look for the registry.
Configuration menu - View commit details
-
Copy full SHA for cbcc93d - Browse repository at this point
Copy the full SHA cbcc93dView commit details -
Replace custom ini "parser" by GetPrivateProfileString
With a caveat: that function can only read local files, i.e. in the Windows OS filesystem. No shared mounts. Thus we make an effort to copy the instance's /etc/wsl.conf to a private (best effort) temporary path, using OS primitives to guaratee automatic deletion. From that place, it's just a function call to read the key we are interested in. Let's trust the OS can deliver us a suitable temporary file under %TEMP%. In production that's more likely, as the %TEMP% dir is private to the app when FS virtualization is ON.
Configuration menu - View commit details
-
Copy full SHA for 7585be3 - Browse repository at this point
Copy the full SHA 7585be3View commit details -
Do not attempt to fix /etc/wsl.conf
If the username is wrong, i.e. there is no matching UID in passwd ignore it and exit success. As a consequence we can totally remove writing into /etc/wsl.conf: 1. We won't fix any mistakes 2. If a default user is set from outside (WSL API/registry), it suffices to make such user the default, no need to keep both in sync. 3. If no default user is set, we do so via the WSL API, which unfolds into the reasoning above. And just to clarify, if both are set to different users, registry takes precedence over /etc/wsl.conf even after reboot.
Configuration menu - View commit details
-
Copy full SHA for a491c19 - Browse repository at this point
Copy the full SHA a491c19View commit details -
Ask for forgiveness, not permission
When approaching cloud-init, run it unconditionally Added a not-so-beautiful trick to avoid printing /bin/bash: error 1: cloud-init command not found. Finally, if it doesn't exit 0, show the long status cloud-init status --long.
Configuration menu - View commit details
-
Copy full SHA for 49994b7 - Browse repository at this point
Copy the full SHA 49994b7View commit details -
The most beautiful C++ passwd parser ever written ;)
Relying only on the UID may be misleading So we wanted to check the login shell (the last field of the line) to determine whether an account is a system or real user. That required parsing the passwd more carefully Using istringstreams as before would incur in potentially lots of small memory allocations. Writing an iteration scheme by hand with string_views prevents most of the unnecessary allocations while offering an elegant, idiomatic iteration and parsing on-the-flight. Most of that code wouldn't be needed in C++20, std::ranges::split would do most of this job, but with C++17 we need to craft the iteration by hand.
Configuration menu - View commit details
-
Copy full SHA for 722054a - Browse repository at this point
Copy the full SHA 722054aView commit details -
Configuration menu - View commit details
-
Copy full SHA for f17b114 - Browse repository at this point
Copy the full SHA f17b114View commit details -
Adds a test case with the default user already set in the registry
For that we need GoWSL, so let's import it. This whole idea is very prone to races. Let's see how it behaves in CI.
Configuration menu - View commit details
-
Copy full SHA for 8290991 - Browse repository at this point
Copy the full SHA 8290991View commit details -
[NEW!!!] Adds test cases for higher UIDs and broken passwd
We could break passwd in one way at a time, but I'm affraid of having tons of test cases making CI run for too long. So, as the system happily ignores broken lines, I'm all for breaking them in all the ways we want in the same tests and have few tests running with broken passwd.
Configuration menu - View commit details
-
Copy full SHA for 84fc27f - Browse repository at this point
Copy the full SHA 84fc27fView commit details -
Configuration menu - View commit details
-
Copy full SHA for 8ebea3d - Browse repository at this point
Copy the full SHA 8ebea3dView commit details -
Allow bash.exe handle symlinks on Windows
CI was failing because bash.exe didn't know how to handle symlinks. Powershell knows by default, but the resulting script would be uglier. It turns out it's just an MSYS toggle to fix bash.exe.
Configuration menu - View commit details
-
Copy full SHA for 4bf78f0 - Browse repository at this point
Copy the full SHA 4bf78f0View commit details -
Sprinkles some "Setup:" in log and error lines
Plus comments about the order we check for registry settnig errors.
Configuration menu - View commit details
-
Copy full SHA for 64fc551 - Browse repository at this point
Copy the full SHA 64fc551View commit details -
Fix syntax error on e2e workflow file
Apparently quoting is necessary for globing with a single '*'
Configuration menu - View commit details
-
Copy full SHA for 4eb3c22 - Browse repository at this point
Copy the full SHA 4eb3c22View commit details -
Prevents 'cannot index into null array' exception in powershell
When trying to download a rootfs
Configuration menu - View commit details
-
Copy full SHA for acfdc4a - Browse repository at this point
Copy the full SHA acfdc4aView commit details