diff --git a/internal/setup/setup.go b/internal/setup/setup.go index db3d9518..b59e30f9 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -12,6 +12,7 @@ import ( "golang.org/x/crypto/openpgp/packet" "github.com/canonical/chisel/internal/apacheutil" + "github.com/canonical/chisel/internal/deb" "github.com/canonical/chisel/internal/strdist" ) @@ -369,7 +370,7 @@ func order(pkgs map[string]*Package, keys []SliceKey, arch string) ([]SliceKey, fqslice := slice.String() predecessors := successors[fqslice] for req, info := range slice.Essential { - if len(info.Arch) > 0 && !slices.Contains(info.Arch, arch) { + if len(info.Arch) > 0 && arch != "" && !slices.Contains(info.Arch, arch) { continue } fqreq := req.String() @@ -465,6 +466,16 @@ func stripBase(baseDir, path string) string { func Select(release *Release, slices []SliceKey, arch string) (*Selection, error) { logf("Selecting slices...") + var err error + if arch == "" { + arch, err = deb.InferArch() + } else { + err = deb.ValidateArch(arch) + } + if err != nil { + return nil, err + } + selection := &Selection{ Release: release, } diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index ac956ce1..96495800 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -3548,6 +3548,44 @@ var setupTests = []setupTest{{ `, }, relerror: `package "mypkg" repeats mypkg_myslice2 in essential fields`, +}, { + summary: "Cycles are detected with 'v3-essential'", + input: map[string]string{ + "slices/mydir/mypkg1.yaml": ` + package: mypkg1 + slices: + myslice: + v3-essential: + mypkg2_myslice: {arch: [amd64, i386]} + `, + "slices/mydir/mypkg2.yaml": ` + package: mypkg2 + slices: + myslice: + v3-essential: + mypkg1_myslice: {arch: [amd64, i386]} + `, + }, + relerror: "essential loop detected: mypkg1_myslice, mypkg2_myslice", +}, { + summary: "Cycles are detected with 'v3-essential' without architecture", + input: map[string]string{ + "slices/mydir/mypkg1.yaml": ` + package: mypkg1 + slices: + myslice: + v3-essential: + mypkg2_myslice: + `, + "slices/mydir/mypkg2.yaml": ` + package: mypkg2 + slices: + myslice: + v3-essential: + mypkg1_myslice: {arch: [amd64, i386]} + `, + }, + relerror: "essential loop detected: mypkg1_myslice, mypkg2_myslice", }} func (s *S) TestParseRelease(c *C) { @@ -3625,7 +3663,7 @@ func runParseReleaseTests(c *C, tests []setupTest) { } if test.selslices != nil { - selection, err := setup.Select(release, test.selslices, "") + selection, err := setup.Select(release, test.selslices, "amd64") if test.selerror != "" { c.Assert(err, ErrorMatches, test.selerror) continue @@ -3850,3 +3888,52 @@ func (s *S) TestYAMLPathGenerate(c *C) { c.Assert(result, Equals, test.result) } } + +var selectWithArchTests = []struct { + summary string + arch string + input map[string]string + selerror string +}{{ + summary: "Empty arch", + arch: "", +}, { + summary: "Invalid arch", + arch: "foo", + selerror: "invalid package architecture: foo", +}} + +func (s *S) TestSelectWithArch(c *C) { + input := map[string]string{ + "chisel.yaml": string(testutil.DefaultChiselYaml), + "slices/mydir/mypkg.yaml": ` + package: mypkg + slices: + myslice: + contents: + /dir/file1: {} + `, + } + selslices := []setup.SliceKey{{"mypkg", "myslice"}} + dir := c.MkDir() + for path, data := range input { + fpath := filepath.Join(dir, path) + err := os.MkdirAll(filepath.Dir(fpath), 0o755) + c.Assert(err, IsNil) + err = os.WriteFile(fpath, testutil.Reindent(data), 0o644) + c.Assert(err, IsNil) + } + + release, err := setup.ReadRelease(dir) + c.Assert(err, IsNil) + + for _, test := range selectWithArchTests { + _, err = setup.Select(release, selslices, test.arch) + if test.selerror != "" { + c.Assert(err, ErrorMatches, test.selerror) + continue + } else { + c.Assert(err, IsNil) + } + } +}