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

Tracking issue regarding changes required to support new modules #257

Closed
4 tasks done
xynydev opened this issue Nov 10, 2024 · 16 comments
Closed
4 tasks done

Tracking issue regarding changes required to support new modules #257

xynydev opened this issue Nov 10, 2024 · 16 comments
Assignees
Labels
priority: medium Needs to be done soon state: in-progress Work has started type: feature Brand new functionality, features, pages, workflows, endpoints, etc.

Comments

@xynydev
Copy link
Member

xynydev commented Nov 10, 2024

We have discussed the usage of Nushell for developing modules here: blue-build/modules#212
We're working on a v2 of the default-flatpaks module here: blue-build/modules#336

Here's a quick list of things that need to be implemented in CLI to finish off the support for the new types of modules and default-flatpaks v2:

  • Support for modules published as separate images under the source image path
  • Support for specifying the version of the module to use (corresponding to the image tag)
    • Proposed syntax: type: default-flatpaks@v1, type: default-flatpaks@v2, type: default-flatpaks@latest etc.
    • Fetch @latest by default
    • Needs schema changes
    • feat: Support versioned modules #320
  • Support for module scripts without .sh suffix
    • A script in Nushell should not use the .sh suffix.
    • Need to figure out how to handle existing modules, including custom modules
    • Ideas:
      1. Expect .sh to be there by default, unless the module.yml declares that the module is in Nushell
      2. Expect .sh to not be there, rename the script files of all modules (would break builds with earlier versions, but could be mitigated with symlinks) (local modules might need a different procedure)
      3. Run the Nushell module with a bash wrapper (using an .sh file that is a shim for the .nu script) (no CLI changes required)
    • feat: Add support for NuShell scripts #312 - Approach taken: support module scripts with either .sh, .nu, or .bash suffixes.
  • Support for modules written in Nushell
    • https://github.com/blue-build/nushell-image shall be used as the distribution mechanism for Nushell
      • Ex. COPY --from=ghcr.io/blue-build/nushell-image:0.98.0 /nu/nu /usr/bin/nu
    • Ideally the supported Nu version is declared by the repository (or possibly even the module)
    • But it would be wasteful to ship multiple Nu binaries in the images
    • It would be wasteful to ship a Nu binary at all if the module does not have any post-boot elements
    • Ideas:
      1. Modules using Nushell declare the version the want in their module.yml, that is read by the CLI, and that image is bind-mounted to their RUN-step. If a module needs Nushell post-boot, it can cp the binary to the appropriate location.
      2. Modules using Nushell declare the version the want in their module.yml, that is read in the build process for the module repository, and the binaries are added into the image for the module alongside the source code. If a module needs Nushell post-boot, it can cp the binary to the appropriate location.
      3. Nushell replaces yq (and possibly others) and goes alongside bluebuild as one of the binaries that gets included in every image. The version is the same across all builds and modules (need to make sure all modules support the newer version before upgrading, but wasting resources on shipping multiple versions becomes impossible).
    • feat: Add support for NuShell scripts #312
      • Approach taken: see below, basically option c.
@xynydev xynydev added type: feature Brand new functionality, features, pages, workflows, endpoints, etc. state: pending Pending requirements, dependencies, data, or more information. priority: medium Needs to be done soon labels Nov 10, 2024
@gmpinder gmpinder self-assigned this Nov 23, 2024
@gmpinder
Copy link
Member

So if we're wanting to have a way to declare the version of NuShell used for the module, this might require having the binaries mounted for version and module call. We could then have the run_module script set the PATH variable with the mounted path for the nushell bins.

If the property for the nushell version doesn't exist, we could assume either:

  • No NuShell binary image is mounted
  • We default to the latest version

If we're going to go the route of allowing NuShell version specification, I don't think we would be able to ship images with a NuShell binary as they could be very different versions used. Which would mean that for runtime modules (modules that run when the user is booted), we should rely soley on using Bash since we can pretty much guarantee that shell will be available.

On another note, I think for ease of use we should have a label on the image containing the contents of module.yml as JSON so that the CLI can have an easier time getting that information for each versioned image.

@xynydev
Copy link
Member Author

xynydev commented Dec 27, 2024

If we're going to go the route of allowing NuShell version specification, I don't think we would be able to ship images with a NuShell binary as they could be very different versions used.

Could we set the version to be same for the whole repo? Keeping it updated while slightly controlling it such that the builds don't break would be ideal. Not having to re-release the CLI on every version change would be nice too.

Maybe a recipe parameter to set the Nushell version tag in the same vein as we can set the CLI version from the recipe. The default could be a special tag in our Nushell repo that points to the currently supported version.

@gmpinder
Copy link
Member

Could we set the version to be same for the whole repo? Keeping it updated while slightly controlling it such that the builds don't break would be ideal. Not having to re-release the CLI on every version change would be nice too.

I don't think that would work well with keeping versioned modules. If we ended up making a v2 of a module and started using a new version of nu, anyone using the v1 module could end up running into an issue where the code for that version is using features that are different/no longer exist in the new nu version.

Maybe a recipe parameter to set the Nushell version tag in the same vein as we can set the CLI version from the recipe. The default could be a special tag in our Nushell repo that points to the currently supported version.

I'd like to keep most maintenance burdens away from the user. They shouldn't have to manage which version of nushell they need to use for the different versions of modules. Remember the goal is to try to make image generation easy for users.

@xynydev
Copy link
Member Author

xynydev commented Dec 30, 2024

I'd like to keep most maintenance burdens away from the user. They shouldn't have to manage which version of nushell they need to use for the different versions of modules.

That was not my point; it was more that if one of our users would like to use a later version of Nushell for their own purposes they could do that, and that we could more effectively test using different Nushell versions with existing modules to see what, if anything, breaks.

I don't think that would work well with keeping versioned modules. If we ended up making a v2 of a module and started using a new version of nu, anyone using the v1 module could end up running into an issue where the code for that version is using features that are different/no longer exist in the new nu version.

There is nothing stopping us from changing the code of the v1 module to accommodate for the breaking changes. Nushell release blog posts neatly highlight all the breaking changes in a specific release, and being able to test modules on any arbitrary Nushell version would also help with that.

@gmpinder
Copy link
Member

There is nothing stopping us from changing the code of the v1 module to accommodate for the breaking changes. Nushell release blog posts neatly highlight all the breaking changes in a specific release, and being able to test modules on any arbitrary Nushell version would also help with that.

Yeah that's fair. In this case should we just install nushell from the Fedora repos and use that version? That way we reduce the burden of keeping track of the version ourselves and just keep pace with upstream.

Right now it looks like in both Fedora 40 and 41 the latest version is 0.99.1. https://repology.org/project/nushell/versions

@xynydev
Copy link
Member Author

xynydev commented Dec 30, 2024

In this case should we just install nushell from the Fedora repos and use that version?

In my mind the idea of using the nushell-container (which I already built and is unlikely to break any time soon) is, besides supporting non-Fedora base images and older versions of Fedora, is that we can perfecly control the Nushell version and only switch our users over once we're sure the modules are not broken on the new version.

@gmpinder
Copy link
Member

Ok after doing some digging, using the Fedora repos might not be the smartest idea since we are also supporting stages for other distros. The best thing to do at that point would be to just use the statically compiled version of the code. So we're back to specifying the version somehow. So how about we do:

  • Have a default version of nushell that is installed into the final image
  • Allow setting a nushell-version: property
    • Will mount the proper version of the image
    • Will set PATH to have the bins in that image first
export PATH="/tmp/nushell/:$PATH"
  • Allow module maintainers to set a label of org.blue-build.nushell-verison
    • The version is used to retrieve the correct version and do the same as if the user set it in nushell-version:

The biggest caveat being that our modules define the version that is installed into the final image. Though this does bring up the worry that a user might want to try to install the version that is supplied by Fedora packaging which would end up conflicting with what we supply.

Maybe we could go the libexec route and have our shell scripts explicitly call /usr/libexec/bluebuild/nushell-<version>/nu and source the plugins as needed. That way it wouldn't interfere with the Fedora packaging or what the user wants to install.

@xynydev
Copy link
Member Author

xynydev commented Dec 30, 2024

Have a default version of nushell that is installed into the final image

This all sounds pretty good.

Allow setting a nushell-version: property

Where is that set? I assumed it'd be the recipe, but I'm confused by the clarifying sublist.

My idea was that the nushell-version: property should exist:
A) So that we can more easily test modules with different Nushell versions
B) So that we can allow users to customize the version of Nushell they install if they so please

Allow module maintainers to set a label of org.blue-build.nushell-version

I guess this proposal is an alternative to the others? This is kind of the intuitive initial plan I had, but just including a single Nushell version per image, inside the image, sounds like the preferable option right now.

Though this does bring up the worry that a user might want to try to install the version that is supplied by Fedora packaging which would end up conflicting with what we supply. Maybe we could go the libexec route...

Installing Nushell to libexec by default sounds fine, if installing Nushell from repos potentially causes an error when it is already installed. Having two copies of Nushell in an image would be a bummer, though. Maybe it would be possible that if an user specifies nushell-version: default or something we include the BlueBuild default Nushell version in the PATH?


For the default version of Nushell, I think it should be based on a tag set for a specific version of nushell-image, since the default Nushell version is not something that can change when changing module repos, or should change when changing CLI versions.

@gmpinder
Copy link
Member

gmpinder commented Dec 30, 2024

Where is that set? I assumed it'd be the recipe, but I'm confused by the clarifying sublist.

That would be on the module definition itself. That way each module could run a specific version. The run_module.sh script could read nushell-version off the JSON that is passed in and update the PATH as necessary.

I guess this proposal is an alternative to the others? This is kind of the intuitive initial plan I had, but just including a single Nushell version per image, inside the image, sounds like the preferable option right now.

I think I'm starting to prefer it being specified as a LABEL. I don't think the module should have nushell itself inside it. We'll let the CLI template the Containerfile to pull the correct image version and copy the bins to /usr/libexec/bluebuild/nushell-<version>. That way it's dynamic and the CLI doesn't need to be updated to allow new versions.

For the default version of Nushell, I think it should be based on a tag set for a specific version of nushell-image, since the default Nushell version is not something that can change when changing module repos, or should change when changing CLI versions.

So the libexec way would just require that our scripts are sure to set the shebang to point to the correct version.

#!/usr/libexec/bluebuild/nushell-0.99.1/nu

Cause otherwise if you specify:

#!/usr/bin/env nu

That will rely on what is set in PATH. The "default" version of nushell feels like it would be too hard to keep track of (if we have our modules specify the version on a LABEL) unless it's the latest version which could introduce breaking changes. I think it would be better to require setting nushell-version on the module for custom local modules. If it's a container module, then we would grab the version from the LABEL and use that. If neither of these are specified, then we'll have to either let it error out or allow the user to install nushell into their image the way they want to. Whether that's using rpm-ostree/dnf or copying the binaries themselves into /usr/bin/.

@xynydev
Copy link
Member Author

xynydev commented Dec 31, 2024

I believe there's been some mutual misunderstanding here.

That would be on the module definition itself.

I don't think this is how it should be done. Say I'm reworking all modules that use Nushell to support a later Nushell version, it would be more straightforward to just set the Nushell version for the entire build. Or, I'm a user and want a specific Nushell version in my image, this approach makes it seem like that isn't even supported?

I think I'm starting to prefer it being specified as a LABEL.

If it's per-module I would agree, but I don't think it should be per-module.

I don't think the module should have nushell itself inside it.

I don't think so either, I mean that the image that the user is building is the one that should have a single version of Nushell in it, which is put there by us, and shipped with the image and not just there at build-time.


So I guess we have some conflicting ideas.

Your idea (I presume):

  • Module makers specify a label for the container image the module is built to that tells CLI which Nushell version is needed
  • CLI transparently inspects said label and mounts that Nushell version into the run environment
  • Post-boot parts of modules don't get to use Nushell
  • All modules get to specify the Nushell version separately
  • Users can optionally override the Nushell version used by a specific module for testing purposes

My idea:

  • We as BlueBuild maintainers (at least me) set the Nushell version to be used across all of BlueBuild. This version should be kept as up-to-date as possible while testing that the modules using Nushell run properly before changing the version.
  • I think this should be a tag on the nushell-image, which CLI could just use add to the image with ex. COPY --from=ghcr.io/blue-build/nushell-image:bluebuild-default ...
  • Post-boot parts of modules get to use Nushell
  • All modules use the same Nushell version (no need to ship multiple Nushells) while we make sure that official modules don't break
  • Users can optionally override the Nushell version shipped with their image to leverage newer Nushell versions and ideally also being able to use the BlueBuild-shipped Nushell for their own shell usage as well if they so please

Maybe lets come to a better consensus before starting contributions?

@gmpinder
Copy link
Member

Say I'm reworking all modules that use Nushell to support a later Nushell version, it would be more straightforward to just set the Nushell version for the entire build.

I don't think it should be per-module.

Ok we can work with that.

  • I think this should be a tag on the nushell-image, which CLI could just use add to the image with ex. COPY --from=ghcr.io/blue-build/nushell-image:bluebuild-default ...

Ok yeah this could totally work

  • All modules use the same Nushell version (no need to ship multiple Nushells) while we make sure that official modules don't break

Sure. I think this will be a good way forward.

Maybe lets come to a better consensus before starting contributions?

I'm a software engineer at heart. It's how I think. You can't stop me :P

@gmpinder
Copy link
Member

  • I think this should be a tag on the nushell-image, which CLI could just use add to the image with ex. COPY --from=ghcr.io/blue-build/nushell-image:bluebuild-default ...

Since this is ours, could we just go with default as the tag?

@xynydev
Copy link
Member Author

xynydev commented Dec 31, 2024

I'm a software engineer at heart. It's how I think. You can't stop me :P

It's good to have a software engineer around :P 💙

For me, thinking about software architecture is sometimes even more fun than coding haha

Since this is ours, could we just go with default as the tag?

I guess yeah, sure

@xynydev xynydev added state: in-progress Work has started and removed state: pending Pending requirements, dependencies, data, or more information. labels Jan 5, 2025
@xynydev
Copy link
Member Author

xynydev commented Jan 5, 2025

What do you think, should we:
a. Allow users to include the BlueBuild version of Nushell in their image's PATH (approach TBD) by setting the value of nushell-version (implicitly indicating that they want to use a specific version of Nushell)
b. Document the possibility to install Nushell by copying the binary from /usr/libexec/ to /usr/bin/
c. Instruct all users who want Nushell to install it using the package manager of their choice; the BlueBuild version of Nushell remains unused by everything else

@gmpinder
Copy link
Member

gmpinder commented Jan 5, 2025

What do you think, should we:
a. Allow users to include the BlueBuild version of Nushell in their image's PATH (approach TBD) by setting the value of nushell-version (implicitly indicating that they want to use a specific version of Nushell)
b. Document the possibility to install Nushell by copying the binary from /usr/libexec/ to /usr/bin/
c. Instruct all users who want Nushell to install it using the package manager of their choice; the BlueBuild version of Nushell remains unused by everything else

I'd be fine with both B and C with C being the preferred method.

@gmpinder
Copy link
Member

gmpinder commented Jan 5, 2025

Ok, nushell support has been released. We should be good to start converting the modules over.

@gmpinder gmpinder closed this as completed Jan 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: medium Needs to be done soon state: in-progress Work has started type: feature Brand new functionality, features, pages, workflows, endpoints, etc.
Projects
None yet
Development

No branches or pull requests

2 participants