diff --git a/cmd/chisel/cmd_cut.go b/cmd/chisel/cmd_cut.go index 5c3088b3..7091bc2f 100644 --- a/cmd/chisel/cmd_cut.go +++ b/cmd/chisel/cmd_cut.go @@ -1,6 +1,9 @@ package main import ( + "fmt" + "time" + "github.com/jessevdk/go-flags" "github.com/canonical/chisel/internal/archive" @@ -22,12 +25,14 @@ var cutDescs = map[string]string{ "release": "Chisel release name or directory (e.g. ubuntu-22.04)", "root": "Root for generated content", "arch": "Package architecture", + "ignore": "Conditions to ignore (e.g. unmaintained, unstable)", } type cmdCut struct { Release string `long:"release" value-name:""` RootDir string `long:"root" value-name:"" required:"yes"` Arch string `long:"arch" value-name:""` + Ignore string `long:"ignore" choice:"unmaintained" choice:"unstable" value-name:""` Positional struct { SliceRefs []string `positional-arg-name:"" required:"yes"` @@ -57,6 +62,16 @@ func (cmd *cmdCut) Execute(args []string) error { return err } + if time.Now().Before(release.Maintenance.Standard) { + if cmd.Ignore == "unstable" { + logf(`Warning: This release is in the "unstable" maintenance status. ` + + `See https://documentation.ubuntu.com/chisel/en/latest/reference/chisel-releases/chisel.yaml/#maintenance to be safe`) + } else { + return fmt.Errorf(`this release is in the "unstable" maintenance status, ` + + `see https://documentation.ubuntu.com/chisel/en/latest/reference/chisel-releases/chisel.yaml/#maintenance for details`) + } + } + selection, err := setup.Select(release, sliceKeys) if err != nil { return err @@ -73,6 +88,8 @@ func (cmd *cmdCut) Execute(args []string) error { Pro: archiveInfo.Pro, CacheDir: cache.DefaultDir("chisel"), PubKeys: archiveInfo.PubKeys, + Maintained: archiveInfo.Maintained, + OldRelease: archiveInfo.OldRelease, }) if err != nil { if err == archive.ErrCredentialsNotFound { @@ -84,6 +101,25 @@ func (cmd *cmdCut) Execute(args []string) error { archives[archiveName] = openArchive } + hasMaintainedArchive := false + for _, archive := range archives { + if archive.Options().Maintained { + hasMaintainedArchive = true + break + } + } + if !hasMaintainedArchive { + if cmd.Ignore == "unmaintained" { + logf(`Warning: No archive has "maintained" maintenance status. ` + + `Consider the different Ubuntu Pro subcriptions to be safe. ` + + `See https://documentation.ubuntu.com/chisel/en/latest/reference/chisel-releases/chisel.yaml/#maintenance for details.`) + } else { + return fmt.Errorf(`no archive has "maintained" maintenance status, ` + + `consider the different Ubuntu Pro subcriptions to be safe, ` + + `see https://documentation.ubuntu.com/chisel/en/latest/reference/chisel-releases/chisel.yaml/#maintenance for details`) + } + } + err = slicer.Run(&slicer.RunOptions{ Selection: selection, Archives: archives, diff --git a/cmd/chisel/cmd_debug_check_release_archives.go b/cmd/chisel/cmd_debug_check_release_archives.go index 746d1e1b..ae9a55e2 100644 --- a/cmd/chisel/cmd_debug_check_release_archives.go +++ b/cmd/chisel/cmd_debug_check_release_archives.go @@ -73,6 +73,8 @@ func (cmd *cmdDebugCheckReleaseArchives) Execute(args []string) error { Pro: archiveInfo.Pro, CacheDir: cache.DefaultDir("chisel"), PubKeys: archiveInfo.PubKeys, + Maintained: archiveInfo.Maintained, + OldRelease: archiveInfo.OldRelease, }) if err == archive.ErrCredentialsNotFound { logf("Archive %q ignored: credentials not found\n", archiveName) diff --git a/cmd/chisel/cmd_debug_check_release_archives_test.go b/cmd/chisel/cmd_debug_check_release_archives_test.go index 398d0b51..b358fcc1 100644 --- a/cmd/chisel/cmd_debug_check_release_archives_test.go +++ b/cmd/chisel/cmd_debug_check_release_archives_test.go @@ -277,19 +277,7 @@ func (s *ChiselSuite) TestRun(c *C) { // makeChiselYaml returns a valid chisel.yaml that contains the archives // supplied. func makeChiselYaml(archives []string) string { - archiveKey := testutil.PGPKeys["key-ubuntu-2018"] - rawChiselYaml := testutil.Reindent(` - format: v1 - archives: - ubuntu: - version: 22.04 - components: [main, universe] - suites: [jammy] - public-keys: [test-key] - public-keys: - test-key: - id: ` + archiveKey.ID + ` - armor: |` + "\n" + testutil.PrefixEachLine(archiveKey.PubKeyArmor, "\t\t\t\t\t\t")) + rawChiselYaml := testutil.Reindent(testutil.DefaultChiselYaml) chiselYaml := map[string]any{} err := yaml.Unmarshal([]byte(rawChiselYaml), chiselYaml) @@ -313,7 +301,9 @@ func makeChiselYaml(archives []string) string { if err != nil { panic(err) } - return string(bs) + out := string(bs) + // Maintenance dates get marshaled as T00:00:00Z by default. + return strings.ReplaceAll(out, "T00:00:00Z", "") } func deepCopyYAML(src map[string]any) map[string]any { diff --git a/cmd/chisel/cmd_info_test.go b/cmd/chisel/cmd_info_test.go index 0220d017..48827218 100644 --- a/cmd/chisel/cmd_info_test.go +++ b/cmd/chisel/cmd_info_test.go @@ -137,23 +137,8 @@ var infoTests = []infoTest{{ err: `no slice definitions found for: "foo_bar_foo", "a_b", "7_c", "a_b c", "a_b x_y"`, }} -var testKey = testutil.PGPKeys["key1"] - -var defaultChiselYaml = ` - format: v1 - archives: - ubuntu: - version: 22.04 - components: [main, universe] - suites: [jammy] - public-keys: [test-key] - public-keys: - test-key: - id: ` + testKey.ID + ` - armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") - var infoRelease = map[string]string{ - "chisel.yaml": string(defaultChiselYaml), + "chisel.yaml": string(testutil.DefaultChiselYaml), "slices/mypkg1.yaml": ` package: mypkg1 essential: diff --git a/internal/archive/archive.go b/internal/archive/archive.go index b1e091f4..4c44c88d 100644 --- a/internal/archive/archive.go +++ b/internal/archive/archive.go @@ -39,6 +39,11 @@ type Options struct { Pro string CacheDir string PubKeys []*packet.PublicKey + // Maintained is set when the archive is still being updated. + Maintained bool + // OldRelease is set for Ubuntu releases which are moved from the regular + // archive which happens after the release's end of life date. + OldRelease bool } func Open(options *Options) (Archive, error) { @@ -148,6 +153,7 @@ func (a *ubuntuArchive) Info(pkg string) (*PackageInfo, error) { } const ubuntuURL = "http://archive.ubuntu.com/ubuntu/" +const ubuntuOldReleasesURL = "http://old-releases.ubuntu.com/ubuntu/" const ubuntuPortsURL = "http://ports.ubuntu.com/ubuntu-ports/" const ( @@ -178,7 +184,7 @@ var proArchiveInfo = map[string]struct { }, } -func archiveURL(pro, arch string) (string, *credentials, error) { +func archiveURL(pro, arch string, oldRelease bool) (string, *credentials, error) { if pro != "" { archiveInfo, ok := proArchiveInfo[pro] if !ok { @@ -192,6 +198,10 @@ func archiveURL(pro, arch string) (string, *credentials, error) { return url, creds, nil } + if oldRelease { + return ubuntuOldReleasesURL, nil, nil + } + if arch == "amd64" || arch == "i386" { return ubuntuURL, nil, nil } @@ -209,7 +219,7 @@ func openUbuntu(options *Options) (Archive, error) { return nil, fmt.Errorf("archive options missing version") } - baseURL, creds, err := archiveURL(options.Pro, options.Arch) + baseURL, creds, err := archiveURL(options.Pro, options.Arch, options.OldRelease) if err != nil { return nil, err } diff --git a/internal/archive/archive_test.go b/internal/archive/archive_test.go index d8a243d2..ee3b6898 100644 --- a/internal/archive/archive_test.go +++ b/internal/archive/archive_test.go @@ -491,6 +491,31 @@ func (s *httpSuite) TestProArchives(c *C) { } } +func (s *httpSuite) TestOpenUnmaintainedArchives(c *C) { + s.base = "http://old-releases.ubuntu.com/ubuntu/" + s.prepareArchive("jammy", "22.04", "amd64", []string{"main", "universe"}) + + options := archive.Options{ + Label: "ubuntu", + Version: "22.04", + Arch: "amd64", + Suites: []string{"jammy"}, + Components: []string{"main", "universe"}, + CacheDir: c.MkDir(), + PubKeys: []*packet.PublicKey{s.pubKey}, + OldRelease: false, + } + + _, err := archive.Open(&options) + // Fails when OldRelease is not set because it attempts to contact the + // default ubuntu archive where the release is no longer available. + c.Assert(err, Not(IsNil)) + + options.OldRelease = true + _, err = archive.Open(&options) + c.Assert(err, IsNil) +} + type verifyArchiveReleaseTest struct { summary string pubKeys []*packet.PublicKey @@ -642,6 +667,7 @@ type realArchiveTest struct { suites []string components []string pro string + oldRelease bool archivePubKeys []*packet.PublicKey archs []string pkg string @@ -651,6 +677,7 @@ type realArchiveTest struct { var realArchiveTests = []realArchiveTest{{ name: "focal", version: "20.04", + oldRelease: false, suites: []string{"focal"}, components: []string{"main", "universe"}, archivePubKeys: []*packet.PublicKey{keyUbuntu2018.PubKey}, @@ -659,6 +686,7 @@ var realArchiveTests = []realArchiveTest{{ }, { name: "jammy", version: "22.04", + oldRelease: false, suites: []string{"jammy"}, components: []string{"main", "universe"}, archivePubKeys: []*packet.PublicKey{keyUbuntu2018.PubKey}, @@ -667,11 +695,21 @@ var realArchiveTests = []realArchiveTest{{ }, { name: "noble", version: "24.04", + oldRelease: false, suites: []string{"noble"}, components: []string{"main", "universe"}, archivePubKeys: []*packet.PublicKey{keyUbuntu2018.PubKey}, pkg: "hostname", path: "/usr/bin/hostname", +}, { + name: "mantic", + version: "23.10", + oldRelease: true, + suites: []string{"mantic"}, + components: []string{"main", "universe"}, + archivePubKeys: []*packet.PublicKey{keyUbuntu2018.PubKey}, + pkg: "hostname", + path: "/bin/hostname", }} var proArchiveTests = []realArchiveTest{{ @@ -797,6 +835,7 @@ func (s *S) testOpenArchiveArch(c *C, test realArchiveTest, arch string) { CacheDir: c.MkDir(), Pro: test.pro, PubKeys: test.archivePubKeys, + OldRelease: test.oldRelease, } testArchive, err := archive.Open(&options) diff --git a/internal/setup/setup.go b/internal/setup/setup.go index 18f25f05..dd4ac775 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" "strings" + "time" "golang.org/x/crypto/openpgp/packet" @@ -16,9 +17,17 @@ import ( // Release is a collection of package slices targeting a particular // distribution version. type Release struct { - Path string - Packages map[string]*Package - Archives map[string]*Archive + Path string + Packages map[string]*Package + Archives map[string]*Archive + Maintenance *Maintenance +} + +type Maintenance struct { + Standard time.Time + Expanded time.Time + Legacy time.Time + EndOfLife time.Time } // Archive is the location from which binary packages are obtained. @@ -30,6 +39,11 @@ type Archive struct { Priority int Pro string PubKeys []*packet.PublicKey + // Maintained is set when the archive is still being updated. + Maintained bool + // OldRelease is set for Ubuntu releases which are moved from the regular + // archive which happens after the release's end of life date. + OldRelease bool } // Package holds a collection of slices that represent parts of themselves. diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index 884c6df1..0137f259 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -4,6 +4,7 @@ import ( "os" "path/filepath" "strings" + "time" "golang.org/x/crypto/openpgp/packet" . "gopkg.in/check.v1" @@ -58,6 +59,9 @@ var setupTests = []setupTest{{ input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: ubuntu: version: 22.04 @@ -81,6 +85,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy", "jammy-security"}, Components: []string{"main", "other"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -90,6 +95,10 @@ var setupTests = []setupTest{{ Slices: map[string]*setup.Slice{}, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Coverage of multiple path kinds", @@ -122,6 +131,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -161,6 +171,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Empty contents", @@ -181,6 +195,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -199,6 +214,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Cycles are detected within packages", @@ -439,6 +458,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -463,6 +483,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Conflicting globs", @@ -651,6 +675,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -668,6 +693,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Multiple architecture selection", @@ -688,6 +717,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -705,6 +735,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Text can be empty", @@ -726,6 +760,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -744,12 +779,19 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Multiple archives with priorities", input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -781,6 +823,7 @@ var setupTests = []setupTest{{ Components: []string{"main", "universe"}, Priority: 20, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, "bar": { Name: "bar", @@ -789,6 +832,7 @@ var setupTests = []setupTest{{ Components: []string{"universe"}, Priority: -10, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -798,12 +842,19 @@ var setupTests = []setupTest{{ Slices: map[string]*setup.Slice{}, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Multiple archives inconsistent use of priorities", input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -831,6 +882,9 @@ var setupTests = []setupTest{{ input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -857,6 +911,9 @@ var setupTests = []setupTest{{ input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: ubuntu: version: 22.04 @@ -869,6 +926,9 @@ var setupTests = []setupTest{{ input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -897,6 +957,9 @@ var setupTests = []setupTest{{ input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -916,6 +979,9 @@ var setupTests = []setupTest{{ input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -935,6 +1001,10 @@ var setupTests = []setupTest{{ input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + madeUpKey7: whatever archives: ubuntu: version: 22.04 @@ -967,6 +1037,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy", "jammy-security"}, Components: []string{"main", "other"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -984,12 +1055,19 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Archives with public keys", input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -1024,6 +1102,7 @@ var setupTests = []setupTest{{ Components: []string{"main", "universe"}, Priority: 20, PubKeys: []*packet.PublicKey{extraTestKey.PubKey}, + Maintained: true, }, "bar": { Name: "bar", @@ -1032,6 +1111,7 @@ var setupTests = []setupTest{{ Components: []string{"universe"}, Priority: 10, PubKeys: []*packet.PublicKey{testKey.PubKey, extraTestKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -1041,6 +1121,10 @@ var setupTests = []setupTest{{ Slices: map[string]*setup.Slice{}, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Archive without public keys", @@ -1139,6 +1223,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -1156,6 +1241,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Very short, invalid package name", @@ -1190,6 +1279,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -1227,6 +1317,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Package essentials with slices from other packages", @@ -1257,6 +1351,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -1297,6 +1392,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Package essentials loop", @@ -1434,6 +1533,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -1451,6 +1551,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, selslices: []setup.SliceKey{{"mypkg", "myslice"}}, selection: &setup.Selection{ @@ -1481,6 +1585,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -1498,6 +1603,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, selslices: []setup.SliceKey{{"mypkg", "myslice"}}, selerror: `slice mypkg_myslice has invalid 'generate' for path /dir/\*\*: "foo"`, @@ -1570,6 +1679,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -1600,6 +1710,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Generate paths cannot conflict with any other path", @@ -1679,6 +1793,9 @@ var setupTests = []setupTest{{ input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: default: default: true @@ -1713,6 +1830,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, Priority: 1, }, "other-1": { @@ -1721,6 +1839,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, Priority: -2, }, "other-2": { @@ -1729,6 +1848,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, Priority: -3, }, }, @@ -1739,12 +1859,21 @@ var setupTests = []setupTest{{ Slices: map[string]*setup.Slice{}, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Pro values in archives", input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + expanded: 2100-01-01 + legacy: 2100-01-01 + end-of-life: 2100-01-01 archives: ubuntu: version: 20.04 @@ -1805,6 +1934,7 @@ var setupTests = []setupTest{{ Components: []string{"main"}, Priority: 10, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, "fips": { Name: "fips", @@ -1814,6 +1944,7 @@ var setupTests = []setupTest{{ Pro: "fips", Priority: 20, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, "fips-updates": { Name: "fips-updates", @@ -1823,6 +1954,7 @@ var setupTests = []setupTest{{ Pro: "fips-updates", Priority: 21, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, "esm-apps": { Name: "esm-apps", @@ -1832,6 +1964,7 @@ var setupTests = []setupTest{{ Pro: "esm-apps", Priority: 16, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, "esm-infra": { Name: "esm-infra", @@ -1841,6 +1974,7 @@ var setupTests = []setupTest{{ Pro: "esm-infra", Priority: 15, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -1850,12 +1984,21 @@ var setupTests = []setupTest{{ Slices: map[string]*setup.Slice{}, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + Expanded: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + Legacy: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Default is ignored", input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: default: default: true @@ -1887,6 +2030,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, Priority: 10, }, "other": { @@ -1895,6 +2039,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, Priority: 20, }, }, @@ -1905,6 +2050,10 @@ var setupTests = []setupTest{{ Slices: map[string]*setup.Slice{}, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Multiple default archives", @@ -1939,6 +2088,9 @@ var setupTests = []setupTest{{ input: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: ubuntu: version: 20.04 @@ -1972,6 +2124,7 @@ var setupTests = []setupTest{{ Components: []string{"main"}, Priority: 10, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, "fips": { Name: "fips", @@ -1981,6 +2134,7 @@ var setupTests = []setupTest{{ Pro: "fips", Priority: 20, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -1990,6 +2144,10 @@ var setupTests = []setupTest{{ Slices: map[string]*setup.Slice{}, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, }, { summary: "Cannot define same archive name in archives and v2-archives", @@ -2101,6 +2259,7 @@ var setupTests = []setupTest{{ Suites: []string{"jammy"}, Components: []string{"main", "universe"}, PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: true, }, }, Packages: map[string]*setup.Package{ @@ -2153,6 +2312,10 @@ var setupTests = []setupTest{{ }, }, }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, }, prefers: map[string]string{ "/path": "mypkg3", @@ -2496,21 +2659,775 @@ var setupTests = []setupTest{{ `, }, relerror: `chisel.yaml: v2-archives is deprecated since format v2`, -}} - -var defaultChiselYaml = ` - format: v1 - archives: - ubuntu: - version: 22.04 - components: [main, universe] - suites: [jammy] - public-keys: [test-key] - public-keys: - test-key: - id: ` + testKey.ID + ` - armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` -` +}, { + summary: "Maintenance all dates", + input: map[string]string{ + "chisel.yaml": ` + format: v1 + maintenance: + standard: 2001-02-03 + expanded: 2004-05-06 + legacy: 2007-08-09 + end-of-life: 2010-11-12 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + `, + "slices/mydir/mypkg.yaml": ` + package: mypkg + `, + }, + release: &setup.Release{ + Archives: map[string]*setup.Archive{ + "ubuntu": { + Name: "ubuntu", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main", "universe"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: false, + OldRelease: true, + }, + }, + Packages: map[string]*setup.Package{ + "mypkg": { + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, + }, + }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2001, time.February, 3, 0, 0, 0, 0, time.UTC), + Expanded: time.Date(2004, time.May, 6, 0, 0, 0, 0, time.UTC), + Legacy: time.Date(2007, time.August, 9, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2010, time.November, 12, 0, 0, 0, 0, time.UTC), + }, + }, +}, { + summary: "Maintenance: legacy and expanded are optional", + input: map[string]string{ + "chisel.yaml": ` + format: v1 + maintenance: + standard: 2001-02-03 + end-of-life: 2010-11-12 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + `, + "slices/mydir/mypkg.yaml": ` + package: mypkg + `, + }, + release: &setup.Release{ + Archives: map[string]*setup.Archive{ + "ubuntu": { + Name: "ubuntu", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main", "universe"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Maintained: false, + OldRelease: true, + }, + }, + Packages: map[string]*setup.Package{ + "mypkg": { + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, + }, + }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2001, time.February, 3, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2010, time.November, 12, 0, 0, 0, 0, time.UTC), + }, + }, +}, { + summary: "Maintenance: end-of-life is required", + input: map[string]string{ + "chisel.yaml": ` + format: v1 + maintenance: + standard: 2001-02-03 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + `, + "slices/mydir/mypkg.yaml": ` + package: mypkg + `, + }, + relerror: `chisel.yaml: cannot parse maintenance: "end-of-life" is unset`, +}, { + summary: "Maintenance: standard is required", + input: map[string]string{ + "chisel.yaml": ` + format: v1 + maintenance: + end-of-life: 2010-11-12 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + `, + "slices/mydir/mypkg.yaml": ` + package: mypkg + `, + }, + relerror: `chisel.yaml: cannot parse maintenance: "standard" is unset`, +}, { + summary: "Maintenance: invalid date format", + input: map[string]string{ + "chisel.yaml": ` + format: v1 + maintenance: + standard: 23 Oct 2010 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + `, + "slices/mydir/mypkg.yaml": ` + package: mypkg + `, + }, + relerror: `chisel.yaml: cannot parse maintenance: expected format for "standard" is YYYY-MM-DD`, +}, { + summary: "Maintenance: all in standard phase", + input: map[string]string{ + "chisel.yaml": ` + format: v1 + maintenance: + standard: 2025-01-01 + expanded: 2100-01-01 + legacy: 2100-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + priority: 3 + esm-apps: + version: 22.04 + components: [main] + suites: [jammy-apps-security] + pro: esm-apps + priority: 2 + public-keys: [test-key] + esm-infra: + version: 22.04 + components: [main] + suites: [jammy-infra-security] + pro: esm-infra + priority: 1 + public-keys: [test-key] + fips: + version: 22.04 + components: [main] + suites: [jammy] + pro: fips + priority: 20 + public-keys: [test-key] + fips-updates: + version: 22.04 + components: [main] + suites: [jammy-updates] + pro: fips-updates + priority: 21 + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + `, + "slices/mydir/mypkg.yaml": ` + package: mypkg + `, + }, + release: &setup.Release{ + Archives: map[string]*setup.Archive{ + "ubuntu": { + Name: "ubuntu", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main", "universe"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 3, + Maintained: true, + OldRelease: false, + }, + "esm-apps": { + Name: "esm-apps", + Pro: "esm-apps", + Version: "22.04", + Suites: []string{"jammy-apps-security"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 2, + Maintained: true, + }, + "esm-infra": { + Name: "esm-infra", + Pro: "esm-infra", + Version: "22.04", + Suites: []string{"jammy-infra-security"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 1, + Maintained: true, + }, + "fips": { + Name: "fips", + Pro: "fips", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 20, + Maintained: true, + }, + "fips-updates": { + Name: "fips-updates", + Pro: "fips-updates", + Version: "22.04", + Suites: []string{"jammy-updates"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 21, + Maintained: true, + }, + }, + Packages: map[string]*setup.Package{ + "mypkg": { + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, + }, + }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + Expanded: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + Legacy: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + }, +}, { + summary: "Maintenance: all archives in expanded phase", + input: map[string]string{ + "chisel.yaml": ` + format: v1 + maintenance: + standard: 2001-01-01 + expanded: 2025-01-01 + legacy: 2100-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + priority: 3 + esm-apps: + version: 22.04 + components: [main] + suites: [jammy-apps-security] + pro: esm-apps + priority: 2 + public-keys: [test-key] + esm-infra: + version: 22.04 + components: [main] + suites: [jammy-infra-security] + pro: esm-infra + priority: 1 + public-keys: [test-key] + fips: + version: 22.04 + components: [main] + suites: [jammy] + pro: fips + priority: 20 + public-keys: [test-key] + fips-updates: + version: 22.04 + components: [main] + suites: [jammy-updates] + pro: fips-updates + priority: 21 + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + `, + "slices/mydir/mypkg.yaml": ` + package: mypkg + `, + }, + release: &setup.Release{ + Archives: map[string]*setup.Archive{ + "ubuntu": { + Name: "ubuntu", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main", "universe"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 3, + Maintained: false, + OldRelease: false, + }, + "esm-apps": { + Name: "esm-apps", + Pro: "esm-apps", + Version: "22.04", + Suites: []string{"jammy-apps-security"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 2, + Maintained: true, + }, + "esm-infra": { + Name: "esm-infra", + Pro: "esm-infra", + Version: "22.04", + Suites: []string{"jammy-infra-security"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 1, + Maintained: true, + }, + "fips": { + Name: "fips", + Pro: "fips", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 20, + Maintained: true, + }, + "fips-updates": { + Name: "fips-updates", + Pro: "fips-updates", + Version: "22.04", + Suites: []string{"jammy-updates"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 21, + Maintained: true, + }, + }, + Packages: map[string]*setup.Package{ + "mypkg": { + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, + }, + }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC), + Expanded: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + Legacy: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + }, +}, { + summary: "Maintenance: all archives in legacy phase", + input: map[string]string{ + "chisel.yaml": ` + format: v1 + maintenance: + standard: 2001-01-01 + expanded: 2001-01-01 + legacy: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + priority: 3 + esm-apps: + version: 22.04 + components: [main] + suites: [jammy-apps-security] + pro: esm-apps + priority: 2 + public-keys: [test-key] + esm-infra: + version: 22.04 + components: [main] + suites: [jammy-infra-security] + pro: esm-infra + priority: 1 + public-keys: [test-key] + fips: + version: 22.04 + components: [main] + suites: [jammy] + pro: fips + priority: 20 + public-keys: [test-key] + fips-updates: + version: 22.04 + components: [main] + suites: [jammy-updates] + pro: fips-updates + priority: 21 + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + `, + "slices/mydir/mypkg.yaml": ` + package: mypkg + `, + }, + release: &setup.Release{ + Archives: map[string]*setup.Archive{ + "ubuntu": { + Name: "ubuntu", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main", "universe"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 3, + Maintained: false, + OldRelease: false, + }, + "esm-apps": { + Name: "esm-apps", + Pro: "esm-apps", + Version: "22.04", + Suites: []string{"jammy-apps-security"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 2, + Maintained: false, + }, + "esm-infra": { + Name: "esm-infra", + Pro: "esm-infra", + Version: "22.04", + Suites: []string{"jammy-infra-security"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 1, + Maintained: false, + }, + "fips": { + Name: "fips", + Pro: "fips", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 20, + Maintained: true, + }, + "fips-updates": { + Name: "fips-updates", + Pro: "fips-updates", + Version: "22.04", + Suites: []string{"jammy-updates"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 21, + Maintained: true, + }, + }, + Packages: map[string]*setup.Package{ + "mypkg": { + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, + }, + }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC), + Expanded: time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC), + Legacy: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + }, +}, { + summary: "Maintenance: all archives in end-of-life phase", + input: map[string]string{ + "chisel.yaml": ` + format: v1 + maintenance: + standard: 2001-01-01 + expanded: 2001-01-01 + legacy: 2001-01-01 + end-of-life: 2025-01-01 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + priority: 3 + esm-apps: + version: 22.04 + components: [main] + suites: [jammy-apps-security] + pro: esm-apps + priority: 2 + public-keys: [test-key] + esm-infra: + version: 22.04 + components: [main] + suites: [jammy-infra-security] + pro: esm-infra + priority: 1 + public-keys: [test-key] + fips: + version: 22.04 + components: [main] + suites: [jammy] + pro: fips + priority: 20 + public-keys: [test-key] + fips-updates: + version: 22.04 + components: [main] + suites: [jammy-updates] + pro: fips-updates + priority: 21 + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + `, + "slices/mydir/mypkg.yaml": ` + package: mypkg + `, + }, + release: &setup.Release{ + Archives: map[string]*setup.Archive{ + "ubuntu": { + Name: "ubuntu", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main", "universe"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 3, + Maintained: false, + OldRelease: true, + }, + "esm-apps": { + Name: "esm-apps", + Pro: "esm-apps", + Version: "22.04", + Suites: []string{"jammy-apps-security"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 2, + Maintained: false, + }, + "esm-infra": { + Name: "esm-infra", + Pro: "esm-infra", + Version: "22.04", + Suites: []string{"jammy-infra-security"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 1, + Maintained: false, + }, + "fips": { + Name: "fips", + Pro: "fips", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 20, + Maintained: false, + }, + "fips-updates": { + Name: "fips-updates", + Pro: "fips-updates", + Version: "22.04", + Suites: []string{"jammy-updates"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 21, + Maintained: false, + }, + }, + Packages: map[string]*setup.Package{ + "mypkg": { + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, + }, + }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC), + Expanded: time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC), + Legacy: time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + }, +}, { + summary: "Maintenance: pro archives default to end-of-life when expanded or legacy missing", + input: map[string]string{ + "chisel.yaml": ` + format: v1 + maintenance: + standard: 2001-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + priority: 3 + esm-apps: + version: 22.04 + components: [main] + suites: [jammy-apps-security] + pro: esm-apps + priority: 2 + public-keys: [test-key] + esm-infra: + version: 22.04 + components: [main] + suites: [jammy-infra-security] + pro: esm-infra + priority: 1 + public-keys: [test-key] + fips: + version: 22.04 + components: [main] + suites: [jammy] + pro: fips + priority: 20 + public-keys: [test-key] + fips-updates: + version: 22.04 + components: [main] + suites: [jammy-updates] + pro: fips-updates + priority: 21 + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` + `, + "slices/mydir/mypkg.yaml": ` + package: mypkg + `, + }, + release: &setup.Release{ + Archives: map[string]*setup.Archive{ + "ubuntu": { + Name: "ubuntu", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main", "universe"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 3, + Maintained: true, + OldRelease: false, + }, + "esm-apps": { + Name: "esm-apps", + Pro: "esm-apps", + Version: "22.04", + Suites: []string{"jammy-apps-security"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 2, + Maintained: true, + }, + "esm-infra": { + Name: "esm-infra", + Pro: "esm-infra", + Version: "22.04", + Suites: []string{"jammy-infra-security"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 1, + Maintained: true, + }, + "fips": { + Name: "fips", + Pro: "fips", + Version: "22.04", + Suites: []string{"jammy"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 20, + Maintained: true, + }, + "fips-updates": { + Name: "fips-updates", + Pro: "fips-updates", + Version: "22.04", + Suites: []string{"jammy-updates"}, + Components: []string{"main"}, + PubKeys: []*packet.PublicKey{testKey.PubKey}, + Priority: 21, + Maintained: true, + }, + }, + Packages: map[string]*setup.Package{ + "mypkg": { + Name: "mypkg", + Path: "slices/mydir/mypkg.yaml", + Slices: map[string]*setup.Slice{}, + }, + }, + Maintenance: &setup.Maintenance{ + Standard: time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + }, +}} func (s *S) TestParseRelease(c *C) { // Run tests for "archives" field in "v1" format. @@ -2554,7 +3471,7 @@ func runParseReleaseTests(c *C, tests []setupTest) { c.Logf("Summary: %s", test.summary) if _, ok := test.input["chisel.yaml"]; !ok { - test.input["chisel.yaml"] = string(defaultChiselYaml) + test.input["chisel.yaml"] = string(testutil.DefaultChiselYaml) } if test.prefers == nil { test.prefers = make(map[string]string) @@ -2620,7 +3537,7 @@ func (s *S) TestPackageMarshalYAML(c *C) { data, ok := test.input["chisel.yaml"] if !ok { - data = defaultChiselYaml + data = testutil.DefaultChiselYaml } dir := c.MkDir() @@ -2757,7 +3674,7 @@ func (s *S) TestPackageYAMLFormat(c *C) { c.Logf("Summary: %s", test.summary) if _, ok := test.input["chisel.yaml"]; !ok { - test.input["chisel.yaml"] = defaultChiselYaml + test.input["chisel.yaml"] = testutil.DefaultChiselYaml } dir := c.MkDir() diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index d873f226..a31ff991 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -2,10 +2,12 @@ package setup import ( "bytes" + "errors" "fmt" "path" "slices" "strings" + "time" "golang.org/x/crypto/openpgp/packet" "gopkg.in/yaml.v3" @@ -23,9 +25,10 @@ func (p *Package) MarshalYAML() (interface{}, error) { var _ yaml.Marshaler = (*Package)(nil) type yamlRelease struct { - Format string `yaml:"format"` - Archives map[string]yamlArchive `yaml:"archives"` - PubKeys map[string]yamlPubKey `yaml:"public-keys"` + Format string `yaml:"format"` + Maintenance yamlMaintenance `yaml:"maintenance"` + Archives map[string]yamlArchive `yaml:"archives"` + PubKeys map[string]yamlPubKey `yaml:"public-keys"` // "v2-archives" is used for backwards compatibility with Chisel <= 1.0.0, // where it will be ignored. In new versions, it will be parsed with the new // fields that break said compatibility (e.g. "pro" archives) and merged @@ -219,12 +222,14 @@ func parseRelease(baseDir, filePath string, data []byte) (*Release, error) { if len(details.Components) == 0 { return nil, fmt.Errorf("%s: archive %q missing components field", fileName, archiveName) } + switch details.Pro { case "", archive.ProApps, archive.ProFIPS, archive.ProFIPSUpdates, archive.ProInfra: default: logf("Archive %q ignored: invalid pro value: %q", archiveName, details.Pro) continue } + if details.Default && defaultArchive != "" { if archiveName < defaultArchive { archiveName, defaultArchive = defaultArchive, archiveName @@ -234,6 +239,7 @@ func parseRelease(baseDir, filePath string, data []byte) (*Release, error) { if details.Default { defaultArchive = archiveName } + if len(details.PubKeys) == 0 { return nil, fmt.Errorf("%s: archive %q missing public-keys field", fileName, archiveName) } @@ -245,6 +251,7 @@ func parseRelease(baseDir, filePath string, data []byte) (*Release, error) { } archiveKeys = append(archiveKeys, key) } + priority := 0 if details.Priority != nil { hasPriority = true @@ -258,6 +265,7 @@ func parseRelease(baseDir, filePath string, data []byte) (*Release, error) { archiveNoPriority = archiveName } } + release.Archives[archiveName] = &Archive{ Name: archiveName, Version: details.Version, @@ -288,6 +296,55 @@ func parseRelease(baseDir, filePath string, data []byte) (*Release, error) { release.Archives[defaultArchive].Priority = 1 } + var maintenance Maintenance + if yamlVar.Maintenance == (yamlMaintenance{}) { + // Use default if key not present in yaml, best effort if "ubuntu" + // archive is present. + // TODO remove the defaults some time after chisel-releases is updated. + ubuntuArchive, ok := release.Archives["ubuntu"] + if ok { + maintenance = defaultMaintenance[ubuntuArchive.Version] + } + } + if maintenance == (Maintenance{}) { + maintenance, err = parseYamlMaintenance(&yamlVar.Maintenance) + if err != nil { + return nil, fmt.Errorf("%s: cannot parse maintenance: %s", fileName, err) + } + } + release.Maintenance = &maintenance + for archiveName, details := range release.Archives { + oldRelease := false + maintained := true + switch details.Pro { + case "": + // The standard archive is no longer maintained during Expanded + // Security Maintenance for LTS, or after End of Life for interim + // releases. + if release.Maintenance.Expanded != (time.Time{}) { + maintained = time.Now().Before(release.Maintenance.Expanded) + } else { + maintained = time.Now().Before(release.Maintenance.EndOfLife) + } + oldRelease = time.Now().After(release.Maintenance.EndOfLife) + case archive.ProInfra, archive.ProApps: + // Legacy support requires a different subscription and a different + // archive. + if release.Maintenance.Legacy != (time.Time{}) { + maintained = time.Now().Before(release.Maintenance.Legacy) + } else { + maintained = time.Now().Before(release.Maintenance.EndOfLife) + } + default: + // FIPS archives are not included in the support window, they need + // a different subscription and have a different lifetime. + maintained = time.Now().Before(release.Maintenance.EndOfLife) + } + details.Maintained = maintained + details.OldRelease = oldRelease + release.Archives[archiveName] = details + } + return release, err } @@ -546,3 +603,91 @@ func packageToYAML(p *Package) (*yamlPackage, error) { } return pkg, nil } + +type yamlMaintenance struct { + Standard string `yaml:"standard"` + Expanded string `yaml:"expanded"` + Legacy string `yaml:"legacy"` + EndOfLife string `yaml:"end-of-life"` +} + +func parseYamlMaintenance(yamlVar *yamlMaintenance) (Maintenance, error) { + maintenance := Maintenance{} + + if yamlVar.Standard == "" { + return Maintenance{}, errors.New(`"standard" is unset`) + } + date, err := time.Parse(time.DateOnly, yamlVar.Standard) + if err != nil { + return Maintenance{}, errors.New(`expected format for "standard" is YYYY-MM-DD`) + } + maintenance.Standard = date + + if yamlVar.EndOfLife == "" { + return Maintenance{}, errors.New(`"end-of-life" is unset`) + } + date, err = time.Parse(time.DateOnly, yamlVar.EndOfLife) + if err != nil { + return Maintenance{}, errors.New(`expected format for "end-of-life" is YYYY-MM-DD`) + } + maintenance.EndOfLife = date + + if yamlVar.Expanded != "" { + date, err = time.Parse(time.DateOnly, yamlVar.Expanded) + if err != nil { + return Maintenance{}, errors.New(`expected format for "expanded" is YYYY-MM-DD`) + } + maintenance.Expanded = date + } + + if yamlVar.Legacy != "" { + date, err = time.Parse(time.DateOnly, yamlVar.Legacy) + if err != nil { + return Maintenance{}, errors.New(`expected format for "legacy" is YYYY-MM-DD`) + } + maintenance.Legacy = date + } + + return maintenance, nil +} + +var defaultMaintenance = map[string]Maintenance{ + "20.04": { + Standard: time.Date(2020, time.April, 23, 0, 0, 0, 0, time.UTC), + Expanded: time.Date(2025, time.May, 29, 0, 0, 0, 0, time.UTC), + Legacy: time.Date(2030, time.April, 23, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2032, time.April, 27, 0, 0, 0, 0, time.UTC), + }, + "22.04": { + Standard: time.Date(2022, time.April, 21, 0, 0, 0, 0, time.UTC), + Expanded: time.Date(2027, time.June, 1, 0, 0, 0, 0, time.UTC), + Legacy: time.Date(2032, time.April, 21, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2034, time.April, 25, 0, 0, 0, 0, time.UTC), + }, + "22.10": { + Standard: time.Date(2022, time.October, 20, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2023, time.July, 20, 0, 0, 0, 0, time.UTC), + }, + "23.04": { + Standard: time.Date(2023, time.April, 20, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2024, time.January, 25, 0, 0, 0, 0, time.UTC), + }, + "23.10": { + Standard: time.Date(2023, time.October, 12, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2024, time.July, 11, 0, 0, 0, 0, time.UTC), + }, + "24.04": { + Standard: time.Date(2024, time.April, 25, 0, 0, 0, 0, time.UTC), + Expanded: time.Date(2029, time.May, 31, 0, 0, 0, 0, time.UTC), + Legacy: time.Date(2034, time.April, 25, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2036, time.April, 29, 0, 0, 0, 0, time.UTC), + }, + "24.10": { + Standard: time.Date(2024, time.October, 10, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2025, time.July, 10, 0, 0, 0, 0, time.UTC), + }, + "25.04": { + Standard: time.Date(2025, time.April, 17, 0, 0, 0, 0, time.UTC), + EndOfLife: time.Date(2026, time.January, 15, 0, 0, 0, 0, time.UTC), + }, +} diff --git a/internal/slicer/slicer_test.go b/internal/slicer/slicer_test.go index 72f81d8d..600a6f61 100644 --- a/internal/slicer/slicer_test.go +++ b/internal/slicer/slicer_test.go @@ -812,6 +812,9 @@ var slicerTests = []slicerTest{{ release: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -884,6 +887,9 @@ var slicerTests = []slicerTest{{ release: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -937,6 +943,9 @@ var slicerTests = []slicerTest{{ release: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -974,6 +983,9 @@ var slicerTests = []slicerTest{{ release: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -1014,6 +1026,9 @@ var slicerTests = []slicerTest{{ release: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -1051,6 +1066,9 @@ var slicerTests = []slicerTest{{ release: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: foo: version: 22.04 @@ -1465,6 +1483,9 @@ var slicerTests = []slicerTest{{ release: map[string]string{ "chisel.yaml": ` format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 archives: invalid: version: 20.04 @@ -1889,20 +1910,6 @@ var slicerTests = []slicerTest{{ logOutput: `(?s).*Warning: Path "/parent/" has diverging modes in different packages\. Please report\..*`, }} -var defaultChiselYaml = ` - format: v1 - archives: - ubuntu: - version: 22.04 - components: [main, universe] - suites: [jammy] - public-keys: [test-key] - public-keys: - test-key: - id: ` + testKey.ID + ` - armor: |` + "\n" + testutil.PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") + ` -` - func (s *S) TestRun(c *C) { // Run tests for "archives" field in "v1" format. runSlicerTests(s, c, slicerTests) @@ -1948,7 +1955,7 @@ func runSlicerTests(s *S, c *C, tests []slicerTest) { c.Logf("Summary: %s", test.summary) if _, ok := test.release["chisel.yaml"]; !ok { - test.release["chisel.yaml"] = defaultChiselYaml + test.release["chisel.yaml"] = testutil.DefaultChiselYaml } if test.pkgs == nil { test.pkgs = []*testutil.TestPackage{{ diff --git a/internal/testutil/defaults.go b/internal/testutil/defaults.go new file mode 100644 index 00000000..fa08b4e6 --- /dev/null +++ b/internal/testutil/defaults.go @@ -0,0 +1,19 @@ +package testutil + +var testKey = PGPKeys["key1"] + +var DefaultChiselYaml = ` + format: v1 + maintenance: + standard: 2025-01-01 + end-of-life: 2100-01-01 + archives: + ubuntu: + version: 22.04 + components: [main, universe] + suites: [jammy] + public-keys: [test-key] + public-keys: + test-key: + id: ` + testKey.ID + ` + armor: |` + "\n" + PrefixEachLine(testKey.PubKeyArmor, "\t\t\t\t\t\t") diff --git a/spread.yaml b/spread.yaml index cf584a6e..a0dc890c 100644 --- a/spread.yaml +++ b/spread.yaml @@ -5,6 +5,10 @@ path: /chisel environment: OS: ubuntu PRO_TOKEN: $(HOST:echo $PRO_TOKEN) + RELEASE/jammy: 22.04 + RELEASE/focal: 20.04 + RELEASE/noble: 24.04 + RELEASE/mantic: 23.10 backends: # Cannot use LXD backend due to https://github.com/snapcore/spread/issues/154 @@ -54,7 +58,3 @@ prepare: | suites: tests/: summary: Tests common scenarios - environment: - RELEASE/jammy: 22.04 - RELEASE/focal: 20.04 - RELEASE/noble: 24.04 diff --git a/tests/basic/task.yaml b/tests/basic/task.yaml index 03fdb5a8..fdb69bfe 100644 --- a/tests/basic/task.yaml +++ b/tests/basic/task.yaml @@ -3,8 +3,16 @@ summary: Ensure multiple slices (with mutation scripts) are properly installed execute: | rootfs_folder=rootfs_${RELEASE} mkdir -p $rootfs_folder + + EXTRA_OPTIONS="" + if [ "$RELEASE" = "23.10" -o "$RELEASE" = "20.04" ]; then + EXTRA_OPTIONS="--ignore=unmaintained " + fi + chisel cut --release ${OS}-${RELEASE} \ - --root $rootfs_folder base-passwd_data openssl_bins + --root $rootfs_folder \ + $EXTRA_OPTIONS \ + base-passwd_data openssl_bins # make sure $rootfs_folder is not empty ls ${rootfs_folder}/* diff --git a/tests/unmaintained/release-23.10/chisel.yaml b/tests/unmaintained/release-23.10/chisel.yaml new file mode 100644 index 00000000..608277da --- /dev/null +++ b/tests/unmaintained/release-23.10/chisel.yaml @@ -0,0 +1,48 @@ +format: v2 + +maintenance: + standard: 2023-10-01 + end-of-life: 2024-04-01 + +archives: + ubuntu: + version: 23.10 + components: [main, universe] + suites: [mantic, mantic-security, mantic-updates] + public-keys: [ubuntu-archive-key-2018] + +public-keys: + # Ubuntu Archive Automatic Signing Key (2018) + # rsa4096/f6ecb3762474eda9d21b7022871920d1991bc93c 2018-09-17T15:01:46Z + ubuntu-archive-key-2018: + id: "871920D1991BC93C" + armor: | + -----BEGIN PGP PUBLIC KEY BLOCK----- + + mQINBFufwdoBEADv/Gxytx/LcSXYuM0MwKojbBye81s0G1nEx+lz6VAUpIUZnbkq + dXBHC+dwrGS/CeeLuAjPRLU8AoxE/jjvZVp8xFGEWHYdklqXGZ/gJfP5d3fIUBtZ + HZEJl8B8m9pMHf/AQQdsC+YzizSG5t5Mhnotw044LXtdEEkx2t6Jz0OGrh+5Ioxq + X7pZiq6Cv19BohaUioKMdp7ES6RYfN7ol6HSLFlrMXtVfh/ijpN9j3ZhVGVeRC8k + KHQsJ5PkIbmvxBiUh7SJmfZUx0IQhNMaDHXfdZAGNtnhzzNReb1FqNLSVkrS/Pns + AQzMhG1BDm2VOSF64jebKXffFqM5LXRQTeqTLsjUbbrqR6s/GCO8UF7jfUj6I7ta + LygmsHO/JD4jpKRC0gbpUBfaiJyLvuepx3kWoqL3sN0LhlMI80+fA7GTvoOx4tpq + VlzlE6TajYu+jfW3QpOFS5ewEMdL26hzxsZg/geZvTbArcP+OsJKRmhv4kNo6Ayd + yHQ/3ZV/f3X9mT3/SPLbJaumkgp3Yzd6t5PeBu+ZQk/mN5WNNuaihNEV7llb1Zhv + Y0Fxu9BVd/BNl0rzuxp3rIinB2TX2SCg7wE5xXkwXuQ/2eTDE0v0HlGntkuZjGow + DZkxHZQSxZVOzdZCRVaX/WEFLpKa2AQpw5RJrQ4oZ/OfifXyJzP27o03wQARAQAB + tEJVYnVudHUgQXJjaGl2ZSBBdXRvbWF0aWMgU2lnbmluZyBLZXkgKDIwMTgpIDxm + dHBtYXN0ZXJAdWJ1bnR1LmNvbT6JAjgEEwEKACIFAlufwdoCGwMGCwkIBwMCBhUI + AgkKCwQWAgMBAh4BAheAAAoJEIcZINGZG8k8LHMQAKS2cnxz/5WaoCOWArf5g6UH + beOCgc5DBm0hCuFDZWWv427aGei3CPuLw0DGLCXZdyc5dqE8mvjMlOmmAKKlj1uG + g3TYCbQWjWPeMnBPZbkFgkZoXJ7/6CB7bWRht1sHzpt1LTZ+SYDwOwJ68QRp7DRa + Zl9Y6QiUbeuhq2DUcTofVbBxbhrckN4ZteLvm+/nG9m/ciopc66LwRdkxqfJ32Cy + q+1TS5VaIJDG7DWziG+Kbu6qCDM4QNlg3LH7p14CrRxAbc4lvohRgsV4eQqsIcdF + kuVY5HPPj2K8TqpY6STe8Gh0aprG1RV8ZKay3KSMpnyV1fAKn4fM9byiLzQAovC0 + LZ9MMMsrAS/45AvC3IEKSShjLFn1X1dRCiO6/7jmZEoZtAp53hkf8SMBsi78hVNr + BumZwfIdBA1v22+LY4xQK8q4XCoRcA9G+pvzU9YVW7cRnDZZGl0uwOw7z9PkQBF5 + KFKjWDz4fCk+K6+YtGpovGKekGBb8I7EA6UpvPgqA/QdI0t1IBP0N06RQcs1fUaA + QEtz6DGy5zkRhR4pGSZn+dFET7PdAjEK84y7BdY4t+U1jcSIvBj0F2B7LwRL7xGp + SpIKi/ekAXLs117bvFHaCvmUYN7JVp1GMmVFxhIdx6CFm3fxG8QjNb5tere/YqK+ + uOgcXny1UlwtCUzlrSaP + =9AdM + -----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/unmaintained/release-23.10/slices/hello.yaml b/tests/unmaintained/release-23.10/slices/hello.yaml new file mode 100644 index 00000000..7bd1a393 --- /dev/null +++ b/tests/unmaintained/release-23.10/slices/hello.yaml @@ -0,0 +1,13 @@ +package: hello + +essential: + - hello_copyright + +slices: + bins: + contents: + /usr/bin/hello: + + copyright: + contents: + /usr/share/doc/hello/copyright: diff --git a/tests/unmaintained/task.yaml b/tests/unmaintained/task.yaml new file mode 100644 index 00000000..4658fa3e --- /dev/null +++ b/tests/unmaintained/task.yaml @@ -0,0 +1,25 @@ +summary: Chisel can fetch packages from unmaintained releases + +variants: + - mantic + +environment: + ROOTFS: rootfs + +execute: | + mkdir "${ROOTFS}" + + # TODO: change to the upstream release when it has maintenance set. + ! OUTPUT=$(chisel cut --release ./release-${RELEASE} --root ${ROOTFS} hello_bins 2>&1) + echo "$OUTPUT" | grep "no archive has \"maintained\" maintenance status, consider the different Ubuntu Pro subcriptions to be safe, see https://documentation.ubuntu.com/chisel/en/latest/reference/chisel-releases/chisel.yaml/#maintenance for details" + + OUTPUT=$(chisel cut --release ./release-${RELEASE} --root ${ROOTFS} --ignore=unmaintained hello_bins 2>&1) + echo "$OUTPUT" | grep "Warning: No archive has \"maintained\" maintenance status. Consider the different Ubuntu Pro subcriptions to be safe. See https://documentation.ubuntu.com/chisel/en/latest/reference/chisel-releases/chisel.yaml/#maintenance for details." + + test -f ${ROOTFS}/usr/bin/hello + test -f ${ROOTFS}/usr/share/doc/hello/copyright + + # Remove the maintenance block. + sed -e "/maintenance:/,+3d" -i ./release-${RELEASE}/chisel.yaml + ! chisel cut --release ./release-${RELEASE} --root ${ROOTFS} --ignore=unmaintained + ! chisel cut --release ./release-${RELEASE} --root ${ROOTFS} hello_bins diff --git a/tests/unstable/task.yaml b/tests/unstable/task.yaml new file mode 100644 index 00000000..11459646 --- /dev/null +++ b/tests/unstable/task.yaml @@ -0,0 +1,31 @@ +summary: Chisel can fetch packages from unmaintained releases + +variants: + # No reason we should run this test for all releases. + - noble + +environment: + ROOTFS: rootfs + +execute: | + # Install yq. + wget -q https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq &&\ + chmod +x /usr/bin/yq + + mkdir "${ROOTFS}" + + git clone --depth=1 -b ${OS}-${RELEASE} \ + https://github.com/canonical/chisel-releases release-${RELEASE} + + # Add dates for the release to be unstable. + yq -i '.maintenance.standard = "2100-01-01"' ./release-${RELEASE}/chisel.yaml + yq -i '.maintenance.end-of-life = "2200-01-01"' ./release-${RELEASE}/chisel.yaml + + ! OUTPUT=$(chisel cut --release ./release-${RELEASE} --root ${ROOTFS} hello_bins 2>&1) + echo "$OUTPUT" | grep "this release is in the \"unstable\" maintenance status, see https://documentation.ubuntu.com/chisel/en/latest/reference/chisel-releases/chisel.yaml/#maintenance for details" + + OUTPUT=$(chisel cut --release ./release-${RELEASE} --root ${ROOTFS} --ignore=unstable hello_bins 2>&1) + echo "$OUTPUT" | grep "Warning: This release is in the \"unstable\" maintenance status. See https://documentation.ubuntu.com/chisel/en/latest/reference/chisel-releases/chisel.yaml/#maintenance to be safe" + + test -f ${ROOTFS}/usr/bin/hello + test -f ${ROOTFS}/usr/share/doc/hello/copyright diff --git a/tests/use-a-custom-chisel-release/task.yaml b/tests/use-a-custom-chisel-release/task.yaml index 2345bf0b..ed11228d 100644 --- a/tests/use-a-custom-chisel-release/task.yaml +++ b/tests/use-a-custom-chisel-release/task.yaml @@ -25,8 +25,16 @@ execute: | /chisel/**: {generate: manifest} EOF - chisel cut --release $chisel_release --root $rootfs_folder base-files_myslice base-files_manifest - + EXTRA_OPTIONS="" + if [ "$RELEASE" = "23.10" -o "$RELEASE" = "20.04" ]; then + EXTRA_OPTIONS="--ignore=unmaintained " + fi + + chisel cut --release $chisel_release \ + --root $rootfs_folder \ + $EXTRA_OPTIONS \ + base-files_myslice base-files_manifest + # make sure $rootfs_folder is not empty ls ${rootfs_folder}/*