diff --git a/artifacts.go b/artifacts.go index 93592a487..cb33300ea 100644 --- a/artifacts.go +++ b/artifacts.go @@ -24,6 +24,8 @@ type Artifacts struct { ConfigFiles map[string]ArtifactConfig `yaml:"configFiles,omitempty" json:"configFiles,omitempty"` // Docs is a list of doc files included in the package Docs map[string]ArtifactConfig `yaml:"docs,omitempty" json:"docs,omitempty"` + // InfoFiles is a list of info files included in the package + InfoFiles map[string]ArtifactConfig `yaml:"infoFiles,omitempty" json:"infoFiles,omitempty"` // Licenses is a list of doc files included in the package Licenses map[string]ArtifactConfig `yaml:"licenses,omitempty" json:"licenses,omitempty"` // Systemd is the list of systemd units and dropin files for the package @@ -123,15 +125,16 @@ func (a *Artifacts) IsEmpty() bool { if len(a.ConfigFiles) > 0 { return false } - if a.Systemd != nil && (len(a.Systemd.Units) > 0 || len(a.Systemd.Dropins) > 0) { return false } - if len(a.Docs) > 0 { return false } + if len(a.InfoFiles) > 0 { + return false + } if len(a.Licenses) > 0 { return false } diff --git a/docs/spec.schema.json b/docs/spec.schema.json index e2c27b00f..00014f239 100644 --- a/docs/spec.schema.json +++ b/docs/spec.schema.json @@ -123,6 +123,13 @@ "type": "object", "description": "Docs is a list of doc files included in the package" }, + "infoFiles": { + "additionalProperties": { + "$ref": "#/$defs/ArtifactConfig" + }, + "type": "object", + "description": "InfoFiles is a list of info files included in the package" + }, "licenses": { "additionalProperties": { "$ref": "#/$defs/ArtifactConfig" diff --git a/frontend/deb/debroot.go b/frontend/deb/debroot.go index 24aea4782..33e3dfab8 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.InfoFiles) > 0 { + sorted := dalec.SortMapKeys(spec.Artifacts.InfoFiles) + for _, key := range sorted { + cfg := spec.Artifacts.InfoFiles[key] + resolved := cfg.ResolveName(key) + writeInstall(key, filepath.Join("/usr/share/info", cfg.SubPath), resolved) + } + } + if len(spec.Artifacts.Libexec) > 0 { sorted := dalec.SortMapKeys(spec.Artifacts.Libexec) for _, key := range sorted { diff --git a/frontend/rpm/template.go b/frontend/rpm/template.go index 80e6a7aea..604afeb93 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.InfoFiles != nil { + infoFileKeys := dalec.SortMapKeys(w.Spec.Artifacts.InfoFiles) + for _, k := range infoFileKeys { + f := w.Spec.Artifacts.InfoFiles[k] + copyArtifact(`%{buildroot}/%{_infodir}`, k, &f) + } + } + if w.Spec.Artifacts.Libexec != nil { libexecFileKeys := dalec.SortMapKeys(w.Spec.Artifacts.Libexec) for _, k := range libexecFileKeys { @@ -607,6 +615,15 @@ func (w *specWrapper) Files() fmt.Stringer { } } + if w.Spec.Artifacts.InfoFiles != nil { + infoFileKeys := dalec.SortMapKeys(w.Spec.Artifacts.InfoFiles) + for _, k := range infoFileKeys { + f := w.Spec.Artifacts.DataDirs[k] + fullPath := filepath.Join(`%{_infodir}`, f.SubPath, f.ResolveName(k)) + fmt.Fprintln(b, fullPath) + } + } + if w.Spec.Artifacts.Libexec != nil { dataKeys := dalec.SortMapKeys(w.Spec.Artifacts.Libexec) for _, k := range dataKeys { diff --git a/test/azlinux_test.go b/test/azlinux_test.go index 7a0b33147..26f0a157f 100644 --- a/test/azlinux_test.go +++ b/test/azlinux_test.go @@ -1131,6 +1131,104 @@ Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/boot }) }) + t.Run("test info file installation", func(t *testing.T) { + t.Parallel() + spec := &dalec.Spec{ + Name: "infofiles-test", + Version: "0.0.1", + Revision: "1", + License: "MIT", + Website: "https://github.com/azure/dalec", + Vendor: "Dalec", + Packager: "Dalec", + Description: "Should install specified info 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, + }, + }, + }, + "nested_subpath": { + Inline: &dalec.SourceInline{ + File: &dalec.SourceInlineFile{ + Contents: "#!/usr/bin/env bash\necho hello world", + Permissions: 0o755, + }, + }, + }, + }, + Artifacts: dalec.Artifacts{ + InfoFiles: map[string]dalec.ArtifactConfig{ + "no_name_no_subpath": {}, + "name_only": { + Name: "this_is_the_name_only", + }, + "subpath_only": { + SubPath: "custom", + }, + "name_and_subpath": { + SubPath: "subpath", + Name: "custom_name", + }, + "nested_subpath": { + SubPath: "info-test/abcdefg", + }, + }, + }, + } + + 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/share/info/no_name_no_subpath", 0o755); err != nil { + t.Fatal(err) + } + if err := validatePathAndPermissions(ctx, ref, "/usr/share/info/this_is_the_name_only", 0o755); err != nil { + t.Fatal(err) + } + if err := validatePathAndPermissions(ctx, ref, "/usr/share/info/subpath/custom_name", 0o755); err != nil { + t.Fatal(err) + } + if err := validatePathAndPermissions(ctx, ref, "/usr/share/info/custom/subpath_only", 0o755); err != nil { + t.Fatal(err) + } + if err := validatePathAndPermissions(ctx, ref, "/usr/share/info/info-test/abcdefg/nested_subpath", 0o755); err != nil { + t.Fatal(err) + } + }) + }) + t.Run("test config files handled", func(t *testing.T) { t.Parallel() spec := &dalec.Spec{