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}/*