Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 36 additions & 14 deletions internal/slicer/slicer.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ type contentChecker struct {
knownPaths map[string]pathData
}

// pkgSource holds the resolved source for a package: its architecture and a
// fetch function returning the package reader and metadata. The fetch
// function is bound at resolution time, so callers are agnostic to whether
// the package comes from an archive or a store.
type pkgSource struct {
arch string
fetch func() (io.ReadSeekCloser, *archive.PackageInfo, error)
}

func (cc *contentChecker) checkMutable(path string) error {
if !cc.knownPaths[path].mutable {
return fmt.Errorf("cannot write file which is not mutable: %s", path)
Expand Down Expand Up @@ -90,7 +99,7 @@ func Run(options *RunOptions) error {
targetDir = filepath.Join(dir, targetDir)
}

pkgArchive, err := selectPkgArchives(options.Archives, options.Selection)
pkgSources, err := resolvePkgSources(options.Archives, options.Selection)
if err != nil {
return err
}
Expand All @@ -108,7 +117,7 @@ func Run(options *RunOptions) error {
extractPackage = make(map[string][]tarball.ExtractInfo)
extract[slice.Package] = extractPackage
}
arch := pkgArchive[slice.Package].Options().Arch
arch := pkgSources[slice.Package].arch
for targetPath, pathInfo := range slice.Contents {
if targetPath == "" {
continue
Expand Down Expand Up @@ -153,7 +162,7 @@ func Run(options *RunOptions) error {
continue
}
pkg := options.Selection.Release.Packages[slice.Package]
reader, info, err := pkgArchive[slice.Package].Fetch(pkg.RealName)
reader, info, err := pkgSources[pkg.Name].fetch()
if err != nil {
return err
}
Expand Down Expand Up @@ -270,7 +279,7 @@ func Run(options *RunOptions) error {
// them to the appropriate slices.
relPaths := map[string][]*setup.Slice{}
for _, slice := range options.Selection.Slices {
arch := pkgArchive[slice.Package].Options().Arch
arch := pkgSources[slice.Package].arch
for relPath, pathInfo := range slice.Contents {
if len(pathInfo.Arch) > 0 && !slices.Contains(pathInfo.Arch, arch) {
continue
Expand Down Expand Up @@ -490,10 +499,13 @@ func createFile(targetDir, relPath string, pathInfo setup.PathInfo) (*fsutil.Ent
})
}

// selectPkgArchives selects the highest priority archive containing the package
// unless a particular archive is pinned within the slice definition file. It
// returns a map of archives indexed by package names.
func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Selection) (map[string]archive.Archive, error) {
// resolvePkgSources determines the source for each package in the selection.
// For archive packages it selects the highest priority archive containing the
// package unless a particular archive is pinned within the slice definition
// file. For store packages it records a fetch function that returns an error
// until store support is implemented. It returns a map of pkgSource indexed by
// package names.
func resolvePkgSources(archives map[string]archive.Archive, selection *setup.Selection) (map[string]pkgSource, error) {
sortedArchives := make([]*setup.Archive, 0, len(selection.Release.Archives))
for _, archive := range selection.Release.Archives {
if archive.Priority < 0 {
Expand All @@ -507,15 +519,20 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel
return b.Priority - a.Priority
})

pkgArchive := make(map[string]archive.Archive)
pkgSources := make(map[string]pkgSource)
for _, s := range selection.Slices {
if _, ok := pkgArchive[s.Package]; ok {
if _, ok := pkgSources[s.Package]; ok {
continue
}
pkg := selection.Release.Packages[s.Package]

if pkg.Store != "" {
return nil, fmt.Errorf("cannot fetch package %q from store %q: not implemented", pkg.Name, pkg.Store)
pkgSources[pkg.Name] = pkgSource{
// TODO: set the arch when implementing fetching from the store.
fetch: func() (io.ReadSeekCloser, *archive.PackageInfo, error) {
return nil, nil, fmt.Errorf("cannot fetch package %q from store %q: not implemented", pkg.Name, pkg.Store)
},
}
continue
}

var candidates []*setup.Archive
Expand All @@ -538,7 +555,12 @@ func selectPkgArchives(archives map[string]archive.Archive, selection *setup.Sel
if chosen == nil {
return nil, fmt.Errorf("cannot find package %q in archive(s)", pkg.RealName)
}
pkgArchive[pkg.Name] = chosen
pkgSources[pkg.Name] = pkgSource{
arch: chosen.Options().Arch,
fetch: func() (io.ReadSeekCloser, *archive.PackageInfo, error) {
return chosen.Fetch(pkg.RealName)
},
}
}
return pkgArchive, nil
return pkgSources, nil
}
24 changes: 16 additions & 8 deletions internal/slicer/slicer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1979,21 +1979,29 @@ var slicerTests = []slicerTest{{
"/dir/file": "file 0644 cc55e2ec {test-package_third}",
},
}, {
summary: "Store package is not yet implemented",
slices: []setup.SliceKey{{"bin-curl", "bin"}},
summary: "Store package fetching not yet implemented",
slices: []setup.SliceKey{{"test-package", "myslice"}, {"bin-store-pkg", "myslice"}},
arch: "amd64",
release: map[string]string{
"chisel.yaml": testutil.DefaultChiselYamlWithStores,
"slices/curl.yaml": `
package: curl
"slices/mydir/test-package.yaml": `
package: test-package
slices:
myslice:
contents:
/dir/file:
`,
"slices/mydir/store-pkg.yaml": `
package: store-pkg
store: bin
default-track: latest
default-track: 3.1
slices:
bin:
myslice:
contents:
/usr/bin/curl:
/dir/store-file:
`,
},
error: `cannot fetch package "bin-curl" from store "bin": not implemented`,
error: `cannot fetch package "bin-store-pkg" from store "bin": not implemented`,
}}

func (s *S) TestRun(c *C) {
Expand Down
Loading