From f930ca405256c0ee0d77e0ebdf202f366762eb8b Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Mon, 21 Oct 2024 16:29:47 -0400 Subject: [PATCH 1/9] Enable libexec artifacts 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 --- artifacts.go | 2 ++ docs/spec.schema.json | 7 +++++++ frontend/rpm/template.go | 8 ++++++++ load.go | 7 +++++++ 4 files changed, 24 insertions(+) diff --git a/artifacts.go b/artifacts.go index f19b8677a..93592a487 100644 --- a/artifacts.go +++ b/artifacts.go @@ -12,6 +12,8 @@ import ( type Artifacts struct { // Binaries is the list of binaries to include in the package. Binaries map[string]ArtifactConfig `yaml:"binaries,omitempty" json:"binaries,omitempty"` + // Libexec is the list of additional binaries that may be invoked by the main package binary. + Libexec map[string]ArtifactConfig `yaml:"libexec,omitempty" json:"libexec,omitempty"` // Manpages is the list of manpages to include in the package. Manpages map[string]ArtifactConfig `yaml:"manpages,omitempty" json:"manpages,omitempty"` // DataDirs is a list of read-only architecture-independent data files, to be placed in /usr/share/ diff --git a/docs/spec.schema.json b/docs/spec.schema.json index 26ac5b994..71dbf8898 100644 --- a/docs/spec.schema.json +++ b/docs/spec.schema.json @@ -76,6 +76,13 @@ "type": "object", "description": "Binaries is the list of binaries to include in the package." }, + "libexec": { + "additionalProperties": { + "$ref": "#/$defs/ArtifactConfig" + }, + "type": "object", + "description": "Libexec is the list of additional binaries that may be invoked by the main package binary." + }, "manpages": { "additionalProperties": { "$ref": "#/$defs/ArtifactConfig" diff --git a/frontend/rpm/template.go b/frontend/rpm/template.go index a446308d5..e63efe8ca 100644 --- a/frontend/rpm/template.go +++ b/frontend/rpm/template.go @@ -499,6 +499,14 @@ func (w *specWrapper) Install() fmt.Stringer { } } + if w.Spec.Artifacts.Libexec != nil { + libexecFileKeys := dalec.SortMapKeys(w.Spec.Artifacts.Libexec) + for _, k := range libexecFileKeys { + le := w.Spec.Artifacts.Libexec[k] + copyArtifact(`%{buildroot}/%{_libexecdir}`, k, &le) + } + } + configKeys := dalec.SortMapKeys(w.Spec.Artifacts.ConfigFiles) for _, c := range configKeys { cfg := w.Spec.Artifacts.ConfigFiles[c] diff --git a/load.go b/load.go index 0ccccbe6c..ad6749dfe 100644 --- a/load.go +++ b/load.go @@ -445,6 +445,13 @@ func (s *Spec) FillDefaults() { s.Patches[k][i].Strip = &strip } } + + for k, ac := range s.Artifacts.Libexec { + if s.Artifacts.Libexec[k].SubPath == "" { + ac.SubPath = s.Name + s.Artifacts.Libexec[k] = ac + } + } } func (s Spec) Validate() error { From 049dd28dba6aed223f122bb98b708ce3789a5318 Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Mon, 21 Oct 2024 17:09:21 -0400 Subject: [PATCH 2/9] Add libexec capability for debian-based distros Signed-off-by: Peter Engelbert --- frontend/deb/debroot.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/frontend/deb/debroot.go b/frontend/deb/debroot.go index 483998862..f818da080 100644 --- a/frontend/deb/debroot.go +++ b/frontend/deb/debroot.go @@ -452,6 +452,15 @@ func createInstallScripts(worker llb.State, spec *dalec.Spec, dir string) []llb. } } + if len(spec.Artifacts.Libexec) > 0 { + sorted := dalec.SortMapKeys(spec.Artifacts.Libexec) + for _, key := range sorted { + cfg := spec.Artifacts.Libexec[key] + resolved := cfg.ResolveName(key) + writeInstall(key, filepath.Join("/usr/libexec", cfg.SubPath), resolved) + } + } + if len(spec.Artifacts.Libs) > 0 { sorted := dalec.SortMapKeys(spec.Artifacts.Libs) for _, key := range sorted { From b3341812e605b8e746e7561f042d1f8b5e9c2fcd Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Mon, 21 Oct 2024 17:30:37 -0400 Subject: [PATCH 3/9] Add documentation for libexec artifacts Signed-off-by: Peter Engelbert --- website/docs/artifacts.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/website/docs/artifacts.md b/website/docs/artifacts.md index a7869a1b7..a367ff9da 100644 --- a/website/docs/artifacts.md +++ b/website/docs/artifacts.md @@ -45,6 +45,32 @@ artifacts: You may use a trailing wildcard to specify multiple binaries in a directory, though behavior may differ between different OS's/distros. +### Libexec + +Libexec files are additional executable files that may be executed by one of +the main package executables. On Linux these would typically get installed into +`/usr/libexec/`. + +Files under libexec are a mapping of file path to [artifact configuration](#artifact-configuration). +If `subpath` is not supplied, it will default to the package name. The file +path is the path to a file that must be available after the build section has +finished. This path is relative to the working directory of the build phase +*before* any directory changes are made. + +Example: + +```yaml +name: my_package + +artifacts: + # the following config will install my_bin at /usr/libexec/my package/my_bin + libexec: + src/my_bin: +``` + +You may use a trailing wildcard to specify multiple binaries in a directory, +though behavior may differ between different OS's/distros. + ### Manpages Manpages is short for manual pages. From d83205855195875539dd088b0018d67600006ac3 Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Mon, 21 Oct 2024 18:04:21 -0400 Subject: [PATCH 4/9] Add tests for libexec Signed-off-by: Peter Engelbert --- frontend/rpm/template.go | 9 ++++ test/azlinux_test.go | 90 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/frontend/rpm/template.go b/frontend/rpm/template.go index e63efe8ca..c8b915cf4 100644 --- a/frontend/rpm/template.go +++ b/frontend/rpm/template.go @@ -607,6 +607,15 @@ func (w *specWrapper) Files() fmt.Stringer { } } + if w.Spec.Artifacts.Libexec != nil { + dataKeys := dalec.SortMapKeys(w.Spec.Artifacts.Libexec) + for _, k := range dataKeys { + df := w.Spec.Artifacts.Libexec[k] + fullPath := filepath.Join(`%{_libexecdir}`, df.SubPath, df.ResolveName(k)) + fmt.Fprintln(b, fullPath) + } + } + configKeys := dalec.SortMapKeys(w.Spec.Artifacts.ConfigFiles) for _, c := range configKeys { cfg := w.Spec.Artifacts.ConfigFiles[c] diff --git a/test/azlinux_test.go b/test/azlinux_test.go index 0e50e4b98..e1dcfdc0e 100644 --- a/test/azlinux_test.go +++ b/test/azlinux_test.go @@ -1015,6 +1015,96 @@ Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/boot }) }) + t.Run("test libexec file installation", func(t *testing.T) { + t.Parallel() + spec := &dalec.Spec{ + Name: "libexec-test", + Version: "0.0.1", + Revision: "1", + License: "MIT", + Website: "https://github.com/azure/dalec", + Vendor: "Dalec", + Packager: "Dalec", + Description: "Should install specified data files", + Sources: map[string]dalec.Source{ + "no_name_no_subpath": { + Inline: &dalec.SourceInline{ + File: &dalec.SourceInlineFile{ + Contents: "#!/usr/bin/env bash\necho hello world", + Permissions: 0o755, + }, + }, + }, + "name_only": { + Inline: &dalec.SourceInline{ + File: &dalec.SourceInlineFile{ + Contents: "#!/usr/bin/env bash\necho hello world", + Permissions: 0o755, + }, + }, + }, + "name_and_subpath": { + Inline: &dalec.SourceInline{ + File: &dalec.SourceInlineFile{ + Contents: "#!/usr/bin/env bash\necho hello world", + Permissions: 0o755, + }, + }, + }, + "subpath_only": { + Inline: &dalec.SourceInline{ + File: &dalec.SourceInlineFile{ + Contents: "#!/usr/bin/env bash\necho hello world", + Permissions: 0o755, + }, + }, + }, + }, + Build: dalec.ArtifactBuild{}, + Artifacts: dalec.Artifacts{ + Binaries: map[string]dalec.ArtifactConfig{ + "no_name_no_subpath": {}, + }, + Libexec: map[string]dalec.ArtifactConfig{ + "no_name_no_subpath": {}, + "name_only": { + Name: "name_only", + }, + "name_and_subpath": { + SubPath: "custom/subpath", + Name: "custom_name", + }, + "subpath_only": dalec.ArtifactConfig{ + SubPath: "custom", + }, + }, + }, + } + + testEnv.RunTest(ctx, t, func(ctx context.Context, client gwclient.Client) { + req := newSolveRequest(withBuildTarget(testConfig.Target.Container), withSpec(ctx, t, spec)) + res := solveT(ctx, t, client, req) + + ref, err := res.SingleRef() + if err != nil { + t.Fatal(err) + } + + if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/libexec-test/no_name_no_subpath", 0o755); err != nil { + t.Fatal(err) + } + if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/libexec-test/name_only", 0o755); err != nil { + t.Fatal(err) + } + if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/custom/subpath/custom_name", 0o755); err != nil { + t.Fatal(err) + } + if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/custom/subpath_only", 0o755); err != nil { + t.Fatal(err) + } + }) + }) + t.Run("test config files handled", func(t *testing.T) { t.Parallel() spec := &dalec.Spec{ From 4ac97450ef5e70d86bb7327adaaddf081ae92e1e Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Tue, 22 Oct 2024 12:30:13 -0400 Subject: [PATCH 5/9] Move subpath defaulting for libexec artifacts 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 --- frontend/deb/debroot.go | 4 +++- frontend/rpm/template.go | 10 ++++++++-- frontend/template.go | 11 +++++++++++ load.go | 7 ------- 4 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 frontend/template.go diff --git a/frontend/deb/debroot.go b/frontend/deb/debroot.go index f818da080..e9f396751 100644 --- a/frontend/deb/debroot.go +++ b/frontend/deb/debroot.go @@ -15,6 +15,7 @@ import ( _ "embed" "github.com/Azure/dalec" + "github.com/Azure/dalec/frontend" "github.com/Azure/dalec/frontend/pkg/bkfs" "github.com/moby/buildkit/client/llb" gwclient "github.com/moby/buildkit/frontend/gateway/client" @@ -457,7 +458,8 @@ func createInstallScripts(worker llb.State, spec *dalec.Spec, dir string) []llb. for _, key := range sorted { cfg := spec.Artifacts.Libexec[key] resolved := cfg.ResolveName(key) - writeInstall(key, filepath.Join("/usr/libexec", cfg.SubPath), resolved) + subPath := frontend.DefaultLibexecSubpath(spec, key) + writeInstall(key, filepath.Join("/usr/libexec", subPath), resolved) } } diff --git a/frontend/rpm/template.go b/frontend/rpm/template.go index c8b915cf4..39aba523b 100644 --- a/frontend/rpm/template.go +++ b/frontend/rpm/template.go @@ -10,6 +10,7 @@ import ( "text/template" "github.com/Azure/dalec" + "github.com/Azure/dalec/frontend" "golang.org/x/exp/maps" "golang.org/x/exp/slices" ) @@ -503,7 +504,11 @@ func (w *specWrapper) Install() fmt.Stringer { libexecFileKeys := dalec.SortMapKeys(w.Spec.Artifacts.Libexec) for _, k := range libexecFileKeys { le := w.Spec.Artifacts.Libexec[k] - copyArtifact(`%{buildroot}/%{_libexecdir}`, k, &le) + leCopy := dalec.ArtifactConfig{ + SubPath: frontend.DefaultLibexecSubpath(w.Spec, k), + Name: le.Name, + } + copyArtifact(`%{buildroot}/%{_libexecdir}`, k, &leCopy) } } @@ -611,7 +616,8 @@ func (w *specWrapper) Files() fmt.Stringer { dataKeys := dalec.SortMapKeys(w.Spec.Artifacts.Libexec) for _, k := range dataKeys { df := w.Spec.Artifacts.Libexec[k] - fullPath := filepath.Join(`%{_libexecdir}`, df.SubPath, df.ResolveName(k)) + subPath := frontend.DefaultLibexecSubpath(w.Spec, k) + fullPath := filepath.Join(`%{_libexecdir}`, subPath, df.ResolveName(k)) fmt.Fprintln(b, fullPath) } } diff --git a/frontend/template.go b/frontend/template.go new file mode 100644 index 000000000..de1c9d988 --- /dev/null +++ b/frontend/template.go @@ -0,0 +1,11 @@ +package frontend + +import "github.com/Azure/dalec" + +func DefaultLibexecSubpath(s *dalec.Spec, k string) string { + if s.Artifacts.Libexec[k].SubPath != "" { + return s.Artifacts.Libexec[k].SubPath + } + + return s.Name +} diff --git a/load.go b/load.go index ad6749dfe..0ccccbe6c 100644 --- a/load.go +++ b/load.go @@ -445,13 +445,6 @@ func (s *Spec) FillDefaults() { s.Patches[k][i].Strip = &strip } } - - for k, ac := range s.Artifacts.Libexec { - if s.Artifacts.Libexec[k].SubPath == "" { - ac.SubPath = s.Name - s.Artifacts.Libexec[k] = ac - } - } } func (s Spec) Validate() error { From dcbeca1a8b9e10cd5ad7804bcaefbe014ccf04c8 Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Tue, 22 Oct 2024 14:40:36 -0400 Subject: [PATCH 6/9] Address PR comments Add `PackageName` to `ArtifactConfig` struct. Rearrange defaulting logic for libexec directories. Signed-off-by: Peter Engelbert --- artifacts.go | 3 +++ frontend/deb/debroot.go | 11 ++++++++--- frontend/rpm/template.go | 32 ++++++++++++++++++++++++-------- frontend/template.go | 11 ----------- test/azlinux_test.go | 7 ++++--- 5 files changed, 39 insertions(+), 25 deletions(-) delete mode 100644 frontend/template.go diff --git a/artifacts.go b/artifacts.go index 93592a487..23ee1cf7e 100644 --- a/artifacts.go +++ b/artifacts.go @@ -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"` } func (a *ArtifactConfig) ResolveName(path string) string { diff --git a/frontend/deb/debroot.go b/frontend/deb/debroot.go index e9f396751..0909a319e 100644 --- a/frontend/deb/debroot.go +++ b/frontend/deb/debroot.go @@ -15,7 +15,6 @@ import ( _ "embed" "github.com/Azure/dalec" - "github.com/Azure/dalec/frontend" "github.com/Azure/dalec/frontend/pkg/bkfs" "github.com/moby/buildkit/client/llb" gwclient "github.com/moby/buildkit/frontend/gateway/client" @@ -457,9 +456,15 @@ func createInstallScripts(worker llb.State, spec *dalec.Spec, dir string) []llb. sorted := dalec.SortMapKeys(spec.Artifacts.Libexec) for _, key := range sorted { cfg := spec.Artifacts.Libexec[key] + + packageName := cfg.PackageName + if packageName == "" { + packageName = spec.Name + } + resolved := cfg.ResolveName(key) - subPath := frontend.DefaultLibexecSubpath(spec, key) - writeInstall(key, filepath.Join("/usr/libexec", subPath), resolved) + targetDir := filepath.Join(`/usr/libexec`, packageName, cfg.SubPath) + writeInstall(key, targetDir, resolved) } } diff --git a/frontend/rpm/template.go b/frontend/rpm/template.go index 39aba523b..6ec114959 100644 --- a/frontend/rpm/template.go +++ b/frontend/rpm/template.go @@ -10,7 +10,6 @@ import ( "text/template" "github.com/Azure/dalec" - "github.com/Azure/dalec/frontend" "golang.org/x/exp/maps" "golang.org/x/exp/slices" ) @@ -504,11 +503,23 @@ func (w *specWrapper) Install() fmt.Stringer { libexecFileKeys := dalec.SortMapKeys(w.Spec.Artifacts.Libexec) for _, k := range libexecFileKeys { le := w.Spec.Artifacts.Libexec[k] - leCopy := dalec.ArtifactConfig{ - SubPath: frontend.DefaultLibexecSubpath(w.Spec, k), - Name: le.Name, + + packageName := le.PackageName + if packageName == "" { + packageName = w.Spec.Name + } + + targetDir := filepath.Join(`%{buildroot}/%{_libexecdir}`, packageName, le.SubPath) + fmt.Fprintln(b, "mkdir -p", targetDir) + + var targetPath string + file := le.ResolveName(k) + if !strings.Contains(file, "*") { + targetPath = filepath.Join(targetDir, file) + } else { + targetPath = targetDir + "/" } - copyArtifact(`%{buildroot}/%{_libexecdir}`, k, &leCopy) + fmt.Fprintln(b, "cp -r", k, targetPath) } } @@ -615,9 +626,14 @@ func (w *specWrapper) Files() fmt.Stringer { if w.Spec.Artifacts.Libexec != nil { dataKeys := dalec.SortMapKeys(w.Spec.Artifacts.Libexec) for _, k := range dataKeys { - df := w.Spec.Artifacts.Libexec[k] - subPath := frontend.DefaultLibexecSubpath(w.Spec, k) - fullPath := filepath.Join(`%{_libexecdir}`, subPath, df.ResolveName(k)) + le := w.Spec.Artifacts.Libexec[k] + packageName := le.PackageName + if packageName == "" { + packageName = w.Spec.Name + } + + targetDir := filepath.Join(`%{_libexecdir}`, packageName, le.SubPath) + fullPath := filepath.Join(targetDir, le.ResolveName(k)) fmt.Fprintln(b, fullPath) } } diff --git a/frontend/template.go b/frontend/template.go deleted file mode 100644 index de1c9d988..000000000 --- a/frontend/template.go +++ /dev/null @@ -1,11 +0,0 @@ -package frontend - -import "github.com/Azure/dalec" - -func DefaultLibexecSubpath(s *dalec.Spec, k string) string { - if s.Artifacts.Libexec[k].SubPath != "" { - return s.Artifacts.Libexec[k].SubPath - } - - return s.Name -} diff --git a/test/azlinux_test.go b/test/azlinux_test.go index e1dcfdc0e..1657a013f 100644 --- a/test/azlinux_test.go +++ b/test/azlinux_test.go @@ -1071,8 +1071,9 @@ Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/boot Name: "name_only", }, "name_and_subpath": { - SubPath: "custom/subpath", - Name: "custom_name", + SubPath: "subpath", + Name: "custom_name", + PackageName: "custom", }, "subpath_only": dalec.ArtifactConfig{ SubPath: "custom", @@ -1099,7 +1100,7 @@ Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/boot if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/custom/subpath/custom_name", 0o755); err != nil { t.Fatal(err) } - if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/custom/subpath_only", 0o755); err != nil { + if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/libexec-test/custom/subpath_only", 0o755); err != nil { t.Fatal(err) } }) From 0d4ecc2ddd17ecfe234302708f3f1b61e0ead6d6 Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Tue, 22 Oct 2024 14:49:36 -0400 Subject: [PATCH 7/9] Run `go generate` Signed-off-by: Peter Engelbert --- docs/spec.schema.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/spec.schema.json b/docs/spec.schema.json index 71dbf8898..248dcd52e 100644 --- a/docs/spec.schema.json +++ b/docs/spec.schema.json @@ -36,6 +36,10 @@ "name": { "type": "string", "description": "Name is file or dir name to use for the artifact in the package.\nIf empty, the file or dir name from the produced artifact will be used." + }, + "packageName": { + "type": "string", + "description": "PackageName is the name of the package. This can be used to replace\n`spec.Name` when destination paths are generated." } }, "additionalProperties": false, From 0d1a89e06f66692137f96189d1048ac7321deafc Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Wed, 23 Oct 2024 13:02:01 -0400 Subject: [PATCH 8/9] Don't insert name in path for libexec artifacts 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 --- artifacts.go | 3 --- docs/spec.schema.json | 4 ---- frontend/deb/debroot.go | 8 +------- frontend/rpm/template.go | 25 ++----------------------- test/azlinux_test.go | 29 +++++++++++++++++++++-------- 5 files changed, 24 insertions(+), 45 deletions(-) diff --git a/artifacts.go b/artifacts.go index 23ee1cf7e..93592a487 100644 --- a/artifacts.go +++ b/artifacts.go @@ -97,9 +97,6 @@ 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"` } func (a *ArtifactConfig) ResolveName(path string) string { diff --git a/docs/spec.schema.json b/docs/spec.schema.json index 248dcd52e..71dbf8898 100644 --- a/docs/spec.schema.json +++ b/docs/spec.schema.json @@ -36,10 +36,6 @@ "name": { "type": "string", "description": "Name is file or dir name to use for the artifact in the package.\nIf empty, the file or dir name from the produced artifact will be used." - }, - "packageName": { - "type": "string", - "description": "PackageName is the name of the package. This can be used to replace\n`spec.Name` when destination paths are generated." } }, "additionalProperties": false, diff --git a/frontend/deb/debroot.go b/frontend/deb/debroot.go index 0909a319e..24aea4782 100644 --- a/frontend/deb/debroot.go +++ b/frontend/deb/debroot.go @@ -456,14 +456,8 @@ func createInstallScripts(worker llb.State, spec *dalec.Spec, dir string) []llb. sorted := dalec.SortMapKeys(spec.Artifacts.Libexec) for _, key := range sorted { cfg := spec.Artifacts.Libexec[key] - - packageName := cfg.PackageName - if packageName == "" { - packageName = spec.Name - } - resolved := cfg.ResolveName(key) - targetDir := filepath.Join(`/usr/libexec`, packageName, cfg.SubPath) + targetDir := filepath.Join(`/usr/libexec`, cfg.SubPath) writeInstall(key, targetDir, resolved) } } diff --git a/frontend/rpm/template.go b/frontend/rpm/template.go index 6ec114959..80e6a7aea 100644 --- a/frontend/rpm/template.go +++ b/frontend/rpm/template.go @@ -503,23 +503,7 @@ func (w *specWrapper) Install() fmt.Stringer { libexecFileKeys := dalec.SortMapKeys(w.Spec.Artifacts.Libexec) for _, k := range libexecFileKeys { le := w.Spec.Artifacts.Libexec[k] - - packageName := le.PackageName - if packageName == "" { - packageName = w.Spec.Name - } - - targetDir := filepath.Join(`%{buildroot}/%{_libexecdir}`, packageName, le.SubPath) - fmt.Fprintln(b, "mkdir -p", targetDir) - - var targetPath string - file := le.ResolveName(k) - if !strings.Contains(file, "*") { - targetPath = filepath.Join(targetDir, file) - } else { - targetPath = targetDir + "/" - } - fmt.Fprintln(b, "cp -r", k, targetPath) + copyArtifact(`%{buildroot}/%{_libexecdir}`, k, &le) } } @@ -627,12 +611,7 @@ func (w *specWrapper) Files() fmt.Stringer { dataKeys := dalec.SortMapKeys(w.Spec.Artifacts.Libexec) for _, k := range dataKeys { le := w.Spec.Artifacts.Libexec[k] - packageName := le.PackageName - if packageName == "" { - packageName = w.Spec.Name - } - - targetDir := filepath.Join(`%{_libexecdir}`, packageName, le.SubPath) + targetDir := filepath.Join(`%{_libexecdir}`, le.SubPath) fullPath := filepath.Join(targetDir, le.ResolveName(k)) fmt.Fprintln(b, fullPath) } diff --git a/test/azlinux_test.go b/test/azlinux_test.go index 1657a013f..de0df37cf 100644 --- a/test/azlinux_test.go +++ b/test/azlinux_test.go @@ -1059,6 +1059,14 @@ Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/boot }, }, }, + "nested_subpath": { + Inline: &dalec.SourceInline{ + File: &dalec.SourceInlineFile{ + Contents: "#!/usr/bin/env bash\necho hello world", + Permissions: 0o755, + }, + }, + }, }, Build: dalec.ArtifactBuild{}, Artifacts: dalec.Artifacts{ @@ -1068,16 +1076,18 @@ Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/boot Libexec: map[string]dalec.ArtifactConfig{ "no_name_no_subpath": {}, "name_only": { - Name: "name_only", + Name: "this_is_the_name_only", }, "name_and_subpath": { - SubPath: "subpath", - Name: "custom_name", - PackageName: "custom", + SubPath: "subpath", + Name: "custom_name", }, "subpath_only": dalec.ArtifactConfig{ SubPath: "custom", }, + "nested_subpath": dalec.ArtifactConfig{ + SubPath: "libexec-test/abcdefg", + }, }, }, } @@ -1091,16 +1101,19 @@ Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/boot t.Fatal(err) } - if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/libexec-test/no_name_no_subpath", 0o755); err != nil { + if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/no_name_no_subpath", 0o755); err != nil { + t.Fatal(err) + } + if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/this_is_the_name_only", 0o755); err != nil { t.Fatal(err) } - if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/libexec-test/name_only", 0o755); err != nil { + if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/subpath/custom_name", 0o755); err != nil { t.Fatal(err) } - if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/custom/subpath/custom_name", 0o755); err != nil { + if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/custom/subpath_only", 0o755); err != nil { t.Fatal(err) } - if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/libexec-test/custom/subpath_only", 0o755); err != nil { + if err := validatePathAndPermissions(ctx, ref, "/usr/libexec/libexec-test/abcdefg/nested_subpath", 0o755); err != nil { t.Fatal(err) } }) From fa22e9076881e446e6b0e35ac4917e661c2d1b4f Mon Sep 17 00:00:00 2001 From: Peter Engelbert Date: Wed, 23 Oct 2024 13:06:32 -0400 Subject: [PATCH 9/9] Update docs Signed-off-by: Peter Engelbert --- website/docs/artifacts.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/docs/artifacts.md b/website/docs/artifacts.md index a367ff9da..85ba0a29b 100644 --- a/website/docs/artifacts.md +++ b/website/docs/artifacts.md @@ -49,13 +49,13 @@ though behavior may differ between different OS's/distros. Libexec files are additional executable files that may be executed by one of the main package executables. On Linux these would typically get installed into -`/usr/libexec/`. +`/usr/libexec/` or `/usr/libexec/`. Files under libexec are a mapping of file path to [artifact configuration](#artifact-configuration). -If `subpath` is not supplied, it will default to the package name. The file -path is the path to a file that must be available after the build section has -finished. This path is relative to the working directory of the build phase -*before* any directory changes are made. +If `subpath` is not supplied, the artifact will be installed in `/usr/libexec` +directly. The file path is the path to a file that must be available after the +build section has finished. This path is relative to the working directory of +the build phase *before* any directory changes are made. Example: