refactor!: commandline interface design discussion
I'm not on the computer right now, so can't give a detailed account. I'll put down some thoughts, though.
I understand how template and build are separate commands, even though build necessitates generating the Containerfile, because the usecases are slightly different. What I don't understand is build / rebase / upgrade. Correct me if I'm wrong, but all of these build the OCI image first, then do something with it. build --pushes if specified, others do a local rebase.
If there's so many commands to build the Containerfile and image and then do something with it, why not put them under one subcommand? Or do some of these not build the image, is there a point to doing multiple commands to build and rebse, how would that even work?
Wouldn't it be cleaner to have one build subcommand, that took (mutually incompatible) parameters like --push, --rebase, --only-containerfile, etc.? Wouldn't even need the template command, the naming of which I slightly dislike due to the template-aspect being a mere implementation detail, the main function being "compiling" or "building" the recipe into a Containerfile. I'm not even sure if having the possibility to use a custom template file (which I believe was possible at some point at least) is useful.
If we're gonna make this API nice, this is the time!
So the subcommands to the following:
-
template- reads in the recipe file and prints the resulting
Containerfiletostdout(good for chaining commands if someone would like to do that) - Given the option, can print to a file using
-o
- reads in the recipe file and prints the resulting
-
build- Runs
templatewith specific args to print aContainerfileto current dir given path to recipe - Orchestrates calling all the proper commands to do the following based on env vars and recipe
- find OS version from base image
- generate image name
- generate image tags
- build image
- push image given
--push - sign image either private/public key pair or OIDC keyless
- export image to an archive file given dir arg
-a/--archive(used by rebase/upgrade)
- Runs
-
rebase- Cleans out
/etc/bluebuild/of any.tar.gzfiles to reduce disk space usage - Runs
buildwith arg of recipe path and archive dir (being/etc/bluebuild/) - Calls
rpm-ostree rebasewith the correct URI parameters to rebase onto a local archive
- Cleans out
-
upgrade/update- Essentially the same as
rebaseexcept:- checks for the existence of the same archive file before continuing
- calls
rpm-ostree upgradeinstead ofrebaseas it will fail to rebase onto the same file path
- Essentially the same as
Sounds like rebase and upgrade could be merged with an rpm-ostree status check, right? And --push being an arg and rebase being a subcommand doesn't make entire sense to me. I get that they give some specific arguments, but wouldn't it be possible to have those as the defaults?
If we could combine rebase and upgrade into a arg term under build that would match what we're trying to do, then I would be ok with that. We could totally check the output of rpm-ostree status to figure out whether to do a rebase or upgrade.
I'm still of the opinion that we keep the template subcommand in case other devs want to take advantage of the Containerfile generation part and handle their build process the way they want. I see our build subcommand as just our opinionated way of building these images and managing them in CI for the user.
How about renaming template to generate, as that verb is commonly used in our docs and makes sense for what it's doing.
I'm still for merging rebase and upgrade into build, but merging them with each other would be the first course of action.
What if we called it --local-boot?
The rebase option? I think --push and --rebase rhyme better. If we don't want to use the "rebase" term, I guess --switch would be the correct choice (per bootc switch becoming the standard).
Ok yeah I like --switch. Are we going to assume that --archive-dir shouldn't be used at the same time as --push and --switch? Cause each of those affects where the image is output to
I think it should be possible to make the build command fail if any of those incompatible parameters are defined at once.
I suggest using something like:
bluebuild build --install-image
bluebuild install image /path/to/the/bluebuild-image
for replacing rpm-ostree image on your system, which would cover rebase & upgrade command.
bluebuild install image-update-integration
for installing systemd service for scheduled updates of locally built images.
Still not ideal in my view, so I will try to think more.
I like bluebuild replace for rebasing. Upgrading seems like it should just be --update
bluebuild build --replace => rebase
bluebuild build --update => upgrade
I do want to keep the workflow the same as it is right now where it will take in the path to the recipe, generate the Containerfile, build it, then use rpm-ostree to rebase/upgrade so keep that in mind with the suggestions.
I don't like the install and replace command/flag names. I think it should be either rebase per rpm-ostree rebase or switch per bootc switch. I also think the build and switch should happen in one command transparently, instead of the user having to specify a file path.
I'm fine with bluebuild build --switch
Essentially we can have the build command be the main driver and just have small flags designate which action to use after building the image
Ok so it sounds like the changes should be:
- Remove
rebaseandupgradein favor of--switchon thebuildcommand - Add
--switcharg that is mutually exclusive to--pushand--archive - Update
templateto begenerate
Are there any other changes before I start working on this change?
That sounds good!
@gmpinder ETA?
I think I'll work on trying to finish it this weekend. I think I was pretty close as-is, but got distracted with fixing other bugs