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

Enable libexec artifacts #408

Merged
merged 9 commits into from
Oct 23, 2024

Conversation

pmengelbert
Copy link
Contributor

@pmengelbert pmengelbert commented Oct 21, 2024

This commit allows the user to specify artifacts to be installed under usr/libexec. I used the following documentation as a guide:

/usr/libexec

Below, you can see at a glance what the behavior of various settings will be. The following examples assume we are building a spec with top-level name: docker. The subpath field defaults to the package name.

# goes to /usr/libexec/docker/docker-compose
libexec:
  bin/docker-compose:

# goes to /usr/libexec/docker/cli-plugins/docker-compose
libexec:
  bin/docker-compose:
    subpath: docker/cli-plugins

# goes to /usr/libexec/something_else/cli-plugins/docker-compose
libexec:
  bin/docker-compose:
    subpath: something_else/cli-plugins

# goes to /usr/libexec/docker/cli-plugins/hello
libexec:
  bin/docker-compose:
    subpath: docker/cli-plugins
    name: hello

# goes to /usr/libexec/docker/hello
libexec:
  bin/docker-compose:
    name: hello

What this PR does / why we need it:

Which issue(s) this PR fixes (optional, using fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when the PR gets merged):
Addresses (but does not finish) #242

Special notes for your reviewer:

@pmengelbert pmengelbert requested a review from a team as a code owner October 21, 2024 20:38
@pmengelbert pmengelbert force-pushed the pmengelbert/rpm_path_macros/1 branch 2 times, most recently from d3aa46d to baa3fc3 Compare October 21, 2024 20:44
frontend/rpm/template.go Show resolved Hide resolved
@pmengelbert pmengelbert force-pushed the pmengelbert/rpm_path_macros/1 branch from baa3fc3 to f758d96 Compare October 21, 2024 20:51
This commit allows the user to specify artifacts to be installed under
`usr/libexec`. I used the following documentation as a guide:

https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s07.html#:~:text=Purpose,subdirectory%20under%20%2Fusr%2Flibexec%20.

Below, you can see at a glance what the behavior of various settings
will be. The following examples assume we are building a spec with
top-level `name: docker`. The subpath field defaults to the package
name.

```yaml
 # goes to /usr/libexec/docker/docker-compose
libexec:
  bin/docker-compose:

 # goes to /usr/libexec/docker/cli-plugins/docker-compose
libexec:
  bin/docker-compose:
    subpath: docker/cli-plugins

 # goes to /usr/libexec/something_else/cli-plugins/docker-compose
libexec:
  bin/docker-compose:
    subpath: something_else/cli-plugins

 # goes to /usr/libexec/docker/cli-plugins/hello
libexec:
  bin/docker-compose:
    subpath: docker/cli-plugins
    name: hello

 # goes to /usr/libexec/docker/hello
libexec:
  bin/docker-compose:
    name: hello

```

Signed-off-by: Peter Engelbert <pmengelbert@gmail.com>
@pmengelbert pmengelbert force-pushed the pmengelbert/rpm_path_macros/1 branch from f758d96 to f930ca4 Compare October 21, 2024 21:07
Signed-off-by: Peter Engelbert <pmengelbert@gmail.com>
Signed-off-by: Peter Engelbert <pmengelbert@gmail.com>
Signed-off-by: Peter Engelbert <pmengelbert@gmail.com>
@pmengelbert pmengelbert force-pushed the pmengelbert/rpm_path_macros/1 branch from 7afc527 to d832058 Compare October 21, 2024 22:06
load.go Outdated
@@ -445,6 +445,13 @@ func (s *Spec) FillDefaults() {
s.Patches[k][i].Strip = &strip
}
}

for k, ac := range s.Artifacts.Libexec {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not doing this for any of the other artifact types, I think it would be good to leave this up to the underlying implementation to deal with rather than changing it in the spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Move the defaulting logic to the implementations, instead of modifying
the spec at the outset. This will leave the spec unchanged.

Signed-off-by: Peter Engelbert <pmengelbert@gmail.com>

import "github.com/Azure/dalec"

func DefaultLibexecSubpath(s *dalec.Spec, k string) string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right.
The way we handle this for the other types (like libs) is always <base>/<spec name>/<subpath>/<artifact name>

As an example, see how Libs are handled.

Also at this time I'd like to avoid abstracting the behavior here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me double check a real system for common libexec usage, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think that's the way to go, and if someone needs something directly in /usr/libexec or somewhere else they can use a symlink.

Copy link
Contributor Author

@pmengelbert pmengelbert Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about when packages are renamed from upstream? For example, if we have the moby-buildx package, we want the docker-buildx binary to go into /usr/libexec/docker/cli-plugins/docker-buildx rather than /usr/libexec/moby-buildx/cli-plugins/docker-buildx. IMO we should let the user do the right thing without adding extra steps.

Copy link
Contributor Author

@pmengelbert pmengelbert Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right. The way we handle this for the other types (like libs) is always <base>/<spec name>/<subpath>/<artifact name>

That seems pretty non-standard. Pretty much everything in my /usr/libexec directory is either in /usr/libexec directly, or nested under a single subdirectory bearing the main application's name. There's only a few files nested deeper than the application's name.

If someone needs something directly in /usr/libexec or somewhere else they can use a symlink.

That would violate the standard referenced in the PR description: "Applications may use a single subdirectory under /usr/libexec". If we create a symlink, we have one application (docker) with two subdirectories under /usr/libexec (/usr/libexec/docker and /usr/libexec/moby-buildx).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a separate field to overwrite the package name is worthwhile in this case.
Or just a bool like OmitAutoPackageName

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Add `PackageName` to `ArtifactConfig` struct. Rearrange defaulting
logic for libexec directories.

Signed-off-by: Peter Engelbert <pmengelbert@gmail.com>
Signed-off-by: Peter Engelbert <pmengelbert@gmail.com>
artifacts.go Outdated
@@ -97,6 +97,9 @@ type ArtifactConfig struct {
// Name is file or dir name to use for the artifact in the package.
// If empty, the file or dir name from the produced artifact will be used.
Name string `yaml:"name,omitempty" json:"name,omitempty"`
// PackageName is the name of the package. This can be used to replace
// `spec.Name` when destination paths are generated.
PackageName string `yaml:"packageName,omitempty" json:"packageName,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My reasoning for suggesting a bool here is because the package name can go into SubPath and we'd just skip including the spec's package name with that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next time I will clarify what you want before I implement the solution. I thought you meant that either was acceptable

Copy link
Contributor Author

@pmengelbert pmengelbert Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tldr: I think we should just use subPath and not do anything automatically. With an empty subPath, things go directly into /usr/libexec (which is standard). Otherwise, you can set subPath to docker if you want things to go into /usr/libexec/docker or docker/cli-plugins if you want /usr/libexec/docker/cli-plugins. Detailed explanation follows.

My reasoning for suggesting a bool here is because the package name can go into SubPath and we'd just skip including the spec's package name with that.

So then in order to get the desired behavior in the example I've been using, you would need

name: moby-buildx

artifacts:
  libexec:
    bin/docker-buildx:
      subPath: docker/cli-plugins
      omitAutoPackageName: true 

What I don't like about that is it kind of overloads the subPath field. When we don't need to change the package name, it would be

name: docker

artifacts:
  libexec:
    bin/docker-buildx:
      subPath: cli-plugins

Both with the bool and without, it's a leaky abstraction. The user has to know several things:

  1. the name field from the spec (which is usually at the top of the file, dozens of lines away) is inserted some times but not others (yes in /usr/lib artifacts, no in /usr/bin artifacts)
  2. libexec will be one of the times when the name is inserted
  3. in order to avoid inserting the name you need to set the bool
  4. the bool changes the meaning of the subPath field, and changes the absolute path depth.

It's too much to ask of the user IMO. Better to just have /usr/libexec be the default (since that's a pretty standard thing to do) and have the user add the application name to the subpath if they want things nested in a subdirectory..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the issue is its 50/50 (literally on my system it is right at the 50/50 mark).
In this case also I guess the package name may not line up exactly with what's being installed as well (beyond docker cli plugins) since we need to differentiate package names from upstreams.

Ok, it seems fine to just not use the package name in the path here (and add to the docs).
Thanks for the diligence here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

libexec artifacts with an empty `subPath` field will be installed into
`/usr/libexec` directly. Otherwise, the subpath and resolved name will
be appended to `/usr/libexec/`.

Signed-off-by: Peter Engelbert <pmengelbert@gmail.com>
Signed-off-by: Peter Engelbert <pmengelbert@gmail.com>
@cpuguy83 cpuguy83 merged commit eb8c95c into Azure:main Oct 23, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants