Skip to content
Open
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
16 changes: 15 additions & 1 deletion cmd/chisel/cmd_cut.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package main
import (
"fmt"
"slices"
"sort"
"strings"
"time"

"github.com/jessevdk/go-flags"
Expand Down Expand Up @@ -79,6 +81,7 @@ func (cmd *cmdCut) Execute(args []string) error {
}

archives := make(map[string]archive.Archive)
var ignoredArchives []string
for archiveName, archiveInfo := range release.Archives {
openArchive, err := archive.Open(&archive.Options{
Label: archiveName,
Expand All @@ -94,13 +97,14 @@ func (cmd *cmdCut) Execute(args []string) error {
})
if err != nil {
if err == archive.ErrCredentialsNotFound {
logf("Archive %q ignored: credentials not found", archiveName)
ignoredArchives = append(ignoredArchives, archiveName)
continue
}
return err
}
archives[archiveName] = openArchive
}
logIgnoredProArchives(ignoredArchives)

hasMaintainedArchive := false
for _, archive := range archives {
Expand Down Expand Up @@ -128,3 +132,13 @@ func (cmd *cmdCut) Execute(args []string) error {
})
return err
}

// logIgnoredProArchives logs a single message listing the Ubuntu Pro archives
// that were ignored because no credentials were found for them.
func logIgnoredProArchives(archiveNames []string) {
if len(archiveNames) == 0 {
return
}
sort.Strings(archiveNames)
logf("Ubuntu Pro subscription not available, ignoring archives: %s", strings.Join(archiveNames, ", "))
}
4 changes: 3 additions & 1 deletion cmd/chisel/cmd_debug_check_release_archives.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func (cmd *cmdDebugCheckReleaseArchives) Execute(args []string) error {
}

archives := make(map[string]archive.Archive)
var ignoredArchives []string
for archiveName, archiveInfo := range release.Archives {
openArchive, err := archiveOpen(&archive.Options{
Label: archiveName,
Expand All @@ -77,13 +78,14 @@ func (cmd *cmdDebugCheckReleaseArchives) Execute(args []string) error {
OldRelease: archiveInfo.OldRelease,
})
if err == archive.ErrCredentialsNotFound {
logf("Archive %q ignored: credentials not found\n", archiveName)
ignoredArchives = append(ignoredArchives, archiveName)
continue
} else if err != nil {
return err
}
archives[archiveName] = openArchive
}
logIgnoredProArchives(ignoredArchives)

pathObs, err := computePathObservations(release, archives)
if err != nil {
Expand Down
65 changes: 65 additions & 0 deletions cmd/chisel/cmd_debug_check_release_archives_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main_test

import (
"bytes"
"log"
"os"
"path/filepath"
"slices"
Expand Down Expand Up @@ -541,6 +543,69 @@ func (s *ChiselSuite) TestRun(c *C) {

// makeChiselYaml returns a valid chisel.yaml that contains the archives
// supplied.
func (s *ChiselSuite) TestRunIgnoresProArchivesWithoutCredentials(c *C) {
var logBuf bytes.Buffer
chisel.SetLogger(log.New(&logBuf, "", 0))
defer chisel.SetLogger(nil)

// Build a chisel.yaml with a regular archive and an Ubuntu Pro archive.
chiselYaml := map[string]any{}
err := yaml.Unmarshal([]byte(testutil.Reindent(testutil.DefaultChiselYaml)), chiselYaml)
c.Assert(err, IsNil)
archivesYaml := chiselYaml["archives"].(map[string]any)
ubuntuArchive := archivesYaml["ubuntu"].(map[string]any)
ubuntuArchive["priority"] = 1
proArchive := deepCopyYAML(ubuntuArchive)
proArchive["priority"] = 2
proArchive["pro"] = "esm-apps"
archivesYaml["ubuntu-pro"] = proArchive
bs, err := yaml.Marshal(chiselYaml)
c.Assert(err, IsNil)

releaseDir := c.MkDir()
release := map[string]string{
"chisel.yaml": strings.ReplaceAll(string(bs), "T00:00:00Z", ""),
"slices/mydir/pkg-a.yaml": `
package: pkg-a
slices:
myslice:
contents:
`,
}
for path, data := range release {
fpath := filepath.Join(releaseDir, path)
err := os.MkdirAll(filepath.Dir(fpath), 0755)
c.Assert(err, IsNil)
err = os.WriteFile(fpath, testutil.Reindent(data), 0644)
c.Assert(err, IsNil)
}

restore := chisel.FakeArchiveOpen(func(options *archive.Options) (archive.Archive, error) {
if options.Pro != "" {
return nil, archive.ErrCredentialsNotFound
}
return &testutil.TestArchive{
Opts: *options,
Packages: map[string]*testutil.TestPackage{
"pkg-a": {
Name: "pkg-a",
Data: testutil.MustMakeDeb([]testutil.TarEntry{
testutil.Dir(0755, "./dir/"),
}),
},
},
}, nil
})
defer restore()

_, err = chisel.Parser().ParseArgs([]string{"debug", "check-release-archives", "--release", releaseDir})
c.Assert(err, IsNil)

logs := logBuf.String()
c.Assert(logs, Matches, "(?s).*Ubuntu Pro subscription not available, ignoring archives: ubuntu-pro\n.*")
c.Assert(strings.Contains(logs, "credentials not found"), Equals, false)
}

func makeChiselYaml(archives []string) string {
rawChiselYaml := testutil.Reindent(testutil.DefaultChiselYaml)

Expand Down
12 changes: 7 additions & 5 deletions internal/archive/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,19 @@ func findCredentials(repoURL string) (*credentials, error) {
}

// findCredentialsInDir searches for credentials for repoURL in configuration
// files in credsDir directory. If the directory does not exist, empty
// credentials structure with nil err is returned.
// files in credsDir directory. If the directory does not exist,
// ErrCredentialsNotFound is returned.
// Only files that do not begin with dot and have either no or ".conf"
// extension are searched. The files are searched in ascending lexicographic
// order. The first file that contains machine declaration matching repoURL
// ends the search. If no file contain matching machine declaration, empty
// credentials structure with nil err is returned.
// ends the search. If no file contain matching machine declaration,
// ErrCredentialsNotFound is returned.
func findCredentialsInDir(repoURL string, credsDir string) (*credentials, error) {
contents, err := os.ReadDir(credsDir)
if err != nil {
logf("Cannot open credentials directory %q: %v", credsDir, err)
if !os.IsNotExist(err) {
logf("Cannot open credentials directory %q: %v", credsDir, err)
}
return nil, ErrCredentialsNotFound
}

Expand Down
9 changes: 9 additions & 0 deletions internal/archive/credentials_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package archive_test

import (
"bytes"
"log"
"os"
"path/filepath"

Expand Down Expand Up @@ -252,12 +254,19 @@ func (s *S) TestFindCredentialsInDirMissingDir(c *C) {
var creds *archive.Credentials
var err error

var logBuf bytes.Buffer
archive.SetLogger(log.New(&logBuf, "", 0))
defer archive.SetLogger(c)

workDir := c.MkDir()
credsDir := filepath.Join(workDir, "auth.conf.d")

creds, err = archive.FindCredentialsInDir("https://example.com/foo/bar", credsDir)
c.Assert(err, ErrorMatches, "^credentials not found$")
c.Assert(creds, IsNil)
// A missing credentials directory is expected without Ubuntu Pro
// credentials and must not be logged as if it were an error.
c.Assert(logBuf.String(), Equals, "")

err = os.Mkdir(credsDir, 0755)
c.Assert(err, IsNil)
Expand Down