-
Notifications
You must be signed in to change notification settings - Fork 63
store/cockpit: use ibcli for building image (HMS-9389) #3636
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
base: main
Are you sure you want to change the base?
Conversation
Codecov Report❌ Patch coverage is @@ Coverage Diff @@
## main #3636 +/- ##
==========================================
+ Coverage 82.01% 84.67% +2.66%
==========================================
Files 215 212 -3
Lines 25139 24719 -420
Branches 2587 2629 +42
==========================================
+ Hits 20617 20931 +314
+ Misses 4494 3762 -732
+ Partials 28 26 -2
... and 8 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
9aad14c
to
b8668ec
Compare
e5c10e6
to
cece867
Compare
I found a bug in ibcli: And pushed a fix here: |
This change refactors some of the cockpit api file end extracts all the helper functions to their own file. This just makes the file more manageable to work with.
This is not strictly needed, it just makes life a little easier.
cece867
to
0d8d38b
Compare
/jira-epic HMS-8666 |
Lol
|
Use cockpit's `long-running-process` to launch a `one-shot` systemd service that runs the image-build with the image-builder cli. This is a step towards removing our dependency on `osbuild-composer`. Results are saved to a file and are updated with the lifecycle events from the systemd service.
The image-builder cli handles the the available target clouds based on environment variables set on the host. For example, if configs and credentials exist in `~/.aws`, then aws image types will be surfaced as available image types. We will need a way to provide the image-build with the name of the aws bucket, so we need to add this as an option in the AWS step of the wizard.
0d8d38b
to
97ef36d
Compare
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.
Thank you! One quick inline command about the file spawning.
I also wonder what we can/could do to make testing easier for you? It seems for the most basic testing just having a way to override the location of image-builder and providing a mock script that e.g. fails with an error or that produceses some fake json would be the easiest. I almost wonder if ibcli provide this in its git repo. Like image-builder build failing-image
and the mock would behave depedning on file type (i.e. for failing-image fails, for slow-image take a long time etc). But maybe I'm overthinking this :)
// can't be started when in `init` state | ||
process.state = 'stopped'; | ||
|
||
process.run(['bash', '-ec', cmd.join(' ')]).catch(async () => { |
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 seems cockpit works with arrays of strings, so would process.run(cmd)
work? The only other change required would be HOME= needs to move into the "options" of process.run(), something like progress.run(cmd, environ={"HOME": ${user.home}})
(assuming python syntax here, I have no clue about typescript). As long as we control all inputs its problably fine as is but once there is user controlled input this turns into a command injection quickly and it seems we can just start with using the array of strings which makes command injections (or files with spaces) a non-issue.
It seems this could then also use the same trick that https://github.com/cockpit-project/cockpit/blob/main/examples/long-running-process/index.js#L20 is using, i.e. just monitor the jounal to get the output of ibcli, with that we could add image-builder build --progress=json
(we currently only have verbose,term,debug there) and then you could render your own progress this way. When we design the json we need to make sure that its self-contained, i.e. that we must assume that at any point a client could connect or reconect and that the client will not have state. This is not a property of the underlying osbuild json stream which will often use "context" which needs to be captured and remembered by the consumer of the json (but no worries, just spelling it out here, doing this will not be hard especially if we start simple).
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.
Ya I didn't like that either and adding HOME= is not ideal. But I ran into two issues here:
- the list of strings didn't work as expected and it was really hard to debug why
- adding the HOME as an env variable in the options also never worked and got ignored.
But those are both valid points and I will dig into it deeper and try figure out why that wasn't working.
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.
With the json progress that seems nice and we could probably implement that in the getComposeStatus endpoint
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.
@kingsleyzissou before you spend/waste too much time in debugging this please leave and maybe we can have a joint session where you can help me to reproduce so that I can dig into it a bit (if you want).
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.
Oh sorry I actually missed this comment. I came back to it today in preparation for Friday's call.
I filed a feature request in cockpit:
cockpit-project/cockpit#22454
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 (args.length && args[0] === 'uname') { | ||
resolve('x86_64'); | ||
} | ||
if (args.length && args[0] === 'image-builder' && args[1] === 'list') { |
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 was about to give you a comment that this might fail. But wow. TIL that you can access [1] even if the array is shorter.
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 think it's because args.length is non-zero :)
qcow2: 'guest-image', | ||
ami: 'aws', | ||
gce: 'gcp', | ||
vhd: 'azure', | ||
vmdk: 'vsphere', | ||
ova: 'vsphere-ova', |
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.
No oci for cockpit?
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 yet. No gcp and azure yet either. Getting there slowly
@kingsleyzissou Good question! I did not notice that I did not have image-builder cli installed at all. |
Ya that's a good point, I added it to the specfile but not to the makefile. I'll have a look at that |
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.
Thank you for exploring this! Personally I really like this approach. But curious to hear what ppl think.
const cmd = [ | ||
// the image build fails if we don't set | ||
// this for some reason | ||
`HOME=${user.home}`, |
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.
Might be because the systemd process is running as root? Not sure how we could drop it though.
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 put a note there and created a feature request for cockpit, basically the env variables aren't being set for the systemd service.
The solution is to either import the long-running-process
script and modify it or add the feature upstream.
const ibBpPath = path.join(composeDir, 'bp.json'); | ||
await cockpit | ||
.file(ibBpPath) | ||
.replace( |
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.
Oh why rewrite the blueprint 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.
We need it so we can pass it to ibcli
we need to save the on-prem version of the blueprint not the hosted version.
So we need to keep track of both.
process.state = 'stopped'; | ||
|
||
process.run(['bash', '-ec', cmd.join(' ')]).catch(async () => { | ||
await cockpit |
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 get image-builder-cli
to write some sort of results file? Like I wonder if we can infer the results from the build log, saves us from having to write the result file + in that case I think we can safely close the tab and still get a proper compose status.
Or could we attach updateComposeStatus
against all running systemd services on load?
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 get image-builder-cli to write some sort of results file
Yeah that's what we're doing, there is a callback that is handling this too and should be attached to the systemd service afaict. I'll have to double check this.
Thanks! Yeah I've scheduled a meeting for tomorrow (sorry I know it's friday) for us to discuss as a team |
This PR switches the image building from osbuild-composer to ibcli. It does this by making use of cockpits
long-running-process
. Under the hood, cockpit creates a one-shot systemd service that executes the image build. We then monitor the systemd service and save the result to a file which we then use for reporting a compose status.JIRA: HMS-9389