Skip to content

Commit

Permalink
Merge branch 'upstream/3.6' into 3.6-into-main
Browse files Browse the repository at this point in the history
  • Loading branch information
manadart committed Jun 5, 2024
2 parents a4e8871 + 3076211 commit 7f09e27
Show file tree
Hide file tree
Showing 26 changed files with 269 additions and 81 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cla.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check if CLA signed
uses: canonical/[email protected].2
uses: canonical/[email protected].3
with:
accept-existing-contributors: true
1 change: 0 additions & 1 deletion cmd/juju/application/bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ func ComposeAndVerifyBundle(ctx *cmd.Context, base BundleDataSource, pathToOverl
}

warnSeries(ctx, dsList)

return bundleData, unMarshallErrors, nil
}

Expand Down
1 change: 0 additions & 1 deletion cmd/juju/cloud/addcredential.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ Use --controller option to upload a credential to a controller.
Use --client option to add a credential to the current client.
`

const usageAddCredentialExamples = `
Expand Down
3 changes: 0 additions & 3 deletions cmd/juju/cloud/addcredential_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,6 @@ Enter credential name:
Using auth-type "jsonfile".
Enter path to the .json file containing a service account key for your project
(detailed instructions available at https://discourse.charmhub.io/t/1508).
Path:
`[1:]
stderr := `
Expand Down Expand Up @@ -973,7 +972,6 @@ Enter your choice, or type Q|q to quit: Enter credential name:
Using auth-type "jsonfile".
Enter path to the .json file containing a service account key for your project
(detailed instructions available at https://discourse.charmhub.io/t/1508).
Path:
Credential "blah" added locally for cloud "remote".
Expand Down Expand Up @@ -1002,7 +1000,6 @@ Enter credential name:
Using auth-type "jsonfile".
Enter path to the .json file containing a service account key for your project
(detailed instructions available at https://discourse.charmhub.io/t/1508).
Path:
`[1:]
stderr := `
Expand Down
19 changes: 19 additions & 0 deletions core/base/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,25 @@ func (b Base) IsCompatible(other Base) bool {
return b.OS == other.OS && b.Channel.Track == other.Channel.Track
}

// ubuntuLTSes lists the Ubuntu LTS releases that
// this version of Juju knows about
var ubuntuLTSes = []Base{
MakeDefaultBase(UbuntuOS, "20.04"),
MakeDefaultBase(UbuntuOS, "22.04"),
MakeDefaultBase(UbuntuOS, "24.04"),
}

// IsUbuntuLTS returns true if this base is a recognised
// Ubuntu LTS.
func (b Base) IsUbuntuLTS() bool {
for _, ubuntuLTS := range ubuntuLTSes {
if b.IsCompatible(ubuntuLTS) {
return true
}
}
return false
}

// DisplayString returns the base string ignoring risk.
func (b Base) DisplayString() string {
if b.Channel.Track == "" || b.OS == "" {
Expand Down
38 changes: 38 additions & 0 deletions core/base/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,41 @@ func (s *BaseSuite) TestParseManifestBases(c *gc.C) {
}
c.Assert(obtained, jc.DeepEquals, expected)
}

var ubuntuLTS = []Base{
MustParseBaseFromString("[email protected]"),
MustParseBaseFromString("[email protected]"),
MustParseBaseFromString("[email protected]"),
MustParseBaseFromString("[email protected]/stable"),
MustParseBaseFromString("[email protected]/edge"),
}

func (s *BaseSuite) TestIsUbuntuLTSForLTSes(c *gc.C) {
for i, lts := range ubuntuLTS {
c.Logf("Checking index %d base %v", i, lts)
c.Check(lts.IsUbuntuLTS(), jc.IsTrue)
}
}

var nonUbuntuLTS = []Base{
MustParseBaseFromString("[email protected]"),
MustParseBaseFromString("[email protected]"),
MustParseBaseFromString("[email protected]"),

MustParseBaseFromString("[email protected]"),
MustParseBaseFromString("[email protected]"),
MustParseBaseFromString("[email protected]"),

MustParseBaseFromString("[email protected]"),
MustParseBaseFromString("[email protected]"),

MustParseBaseFromString("centos@7"),
MustParseBaseFromString("[email protected]"),
}

func (s *BaseSuite) TestIsUbuntuLTSForNonLTSes(c *gc.C) {
for i, lts := range nonUbuntuLTS {
c.Logf("Checking index %d base %v", i, lts)
c.Check(lts.IsUbuntuLTS(), jc.IsFalse)
}
}
3 changes: 0 additions & 3 deletions internal/provider/azure/environ.go
Original file line number Diff line number Diff line change
Expand Up @@ -1083,9 +1083,6 @@ func newOSProfile(
}

instOS := ostype.OSTypeForName(instanceConfig.Base.OS)
if err != nil {
return nil, ostype.Unknown, errors.Trace(err)
}
switch instOS {
case ostype.Ubuntu, ostype.CentOS:
// SSH keys are handled by custom data, but must also be
Expand Down
2 changes: 1 addition & 1 deletion internal/provider/azure/instancetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ func (env *azureEnviron) findInstanceSpec(
if err != nil {
return nil, errors.Trace(err)
}
image, err := imageutils.SeriesImage(ctx, constraint.Base, imageStream, constraint.Region, client)
image, err := imageutils.BaseImage(ctx, constraint.Base, imageStream, constraint.Region, client)
if err != nil {
return nil, errors.Trace(err)
}
Expand Down
100 changes: 87 additions & 13 deletions internal/provider/azure/internal/imageutils/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ const (
ubuntuPublisher = "Canonical"

dailyStream = "daily"

plan = "server-gen1"
)

// SeriesImage gets an instances.Image for the specified series, image stream
// BaseImage gets an instances.Image for the specified base, image stream
// and location. The resulting Image's ID is in the URN format expected by
// Azure Resource Manager.
//
// For Ubuntu, we query the SKUs to determine the most recent point release
// for a series.
func SeriesImage(
func BaseImage(
ctx envcontext.ProviderCallContext,
base jujubase.Base, stream, location string,
client *armcompute.VirtualMachineImagesClient,
Expand Down Expand Up @@ -77,19 +79,91 @@ func SeriesImage(
}, nil
}

func offerForUbuntuSeries(series string) string {
return fmt.Sprintf("0001-com-ubuntu-server-%s", series)
// legacyUbuntuBases is a slice of bases which use the old-style offer
// id formatted like "0001-com-ubuntu-server-${series}".
//
// Recently Canonical changed the format for images offer ids
// and SKUs in Azure. The threshold for this change was noble, so if
// we want to deploy bases before noble, we must branch and use the
// old format.
//
// The old format offer ids have format `0001-com-ubuntu-server-${series}`
// or `001-com-ubuntu-server-${series}-daily` and have SKUs formatted
// `${version_number}-lts`, `${version_number}-gen2`, etc.
//
// The new format offer ids have format `ubuntu-${version_number}`,
// `ubuntu-${version_number}-lts`, `ubuntu-${version_number}-lts-daily`,
// etc. and have SKUs `server`, `server-gen1`m, `server-arm64`, etc.
//
// Since there are only a finte number of Ubuntu versions we support
// before Noble, we hardcode this list. So when new versions of Ubuntu
// are
//
// All Ubuntu images we support outside of this list have offer
// id like "ubuntu-${version}-lts" or "ubuntu-${version}"
var legacyUbuntuBases = []jujubase.Base{
jujubase.MustParseBaseFromString("[email protected]"),
jujubase.MustParseBaseFromString("[email protected]"),
jujubase.MustParseBaseFromString("[email protected]"),
jujubase.MustParseBaseFromString("[email protected]"),
jujubase.MustParseBaseFromString("[email protected]"),
jujubase.MustParseBaseFromString("[email protected]"),
jujubase.MustParseBaseFromString("[email protected]"),
jujubase.MustParseBaseFromString("[email protected]"),
}

func ubuntuBaseIslegacy(base jujubase.Base) bool {
for _, oldBase := range legacyUbuntuBases {
if base.IsCompatible(oldBase) {
return true
}
}
return false
}

// ubuntuSKU returns the best SKU for the Canonical:UbuntuServer offering,
// matching the given series.
//
// TODO(jack-w-shaw): Selecting the 'daily' stream is currently broken for legacy
// Ubuntu SKU selection. See the following lp bug:
// https://bugs.launchpad.net/juju/+bug/2067717
func ubuntuSKU(ctx envcontext.ProviderCallContext, base jujubase.Base, stream, location string, client *armcompute.VirtualMachineImagesClient) (string, string, error) {
if ubuntuBaseIslegacy(base) {
return legacyUbuntuSKU(ctx, base, stream, location, client)
}

offer := fmt.Sprintf("ubuntu-%s", strings.ReplaceAll(base.Channel.Track, ".", "_"))
if base.IsUbuntuLTS() {
offer = fmt.Sprintf("%s-lts", offer)
}
if stream == dailyStream {
offer = fmt.Sprintf("%s-daily", offer)
}

logger.Debugf("listing SKUs: Location=%s, Publisher=%s, Offer=%s", location, ubuntuPublisher, offer)
result, err := client.ListSKUs(ctx, location, ubuntuPublisher, offer, nil)
if err != nil {
return "", "", errorutils.HandleCredentialError(errors.Annotate(err, "listing Ubuntu SKUs"), ctx)
}
for _, img := range result.VirtualMachineImageResourceArray {
skuName := *img.Name
if skuName == plan {
logger.Debugf("found Azure SKU Name: %v", skuName)
return skuName, offer, nil
}
logger.Debugf("ignoring Azure SKU Name: %v", skuName)
}
return "", "", errors.NotFoundf("ubuntu %q SKUs for %v stream", base, stream)
}

func legacyUbuntuSKU(ctx envcontext.ProviderCallContext, base jujubase.Base, stream, location string, client *armcompute.VirtualMachineImagesClient) (string, string, error) {
series, err := jujubase.GetSeriesFromBase(base)
if err != nil {
return "", "", errors.Trace(err)
}
offer := offerForUbuntuSeries(series)
version := strings.ReplaceAll(base.Channel.Track, ".", "_")
offer := fmt.Sprintf("0001-com-ubuntu-server-%s", series)
desiredSKUPrefix := strings.ReplaceAll(base.Channel.Track, ".", "_")

logger.Debugf("listing SKUs: Location=%s, Publisher=%s, Offer=%s", location, ubuntuPublisher, offer)
result, err := client.ListSKUs(ctx, location, ubuntuPublisher, offer, nil)
if err != nil {
Expand All @@ -99,12 +173,12 @@ func ubuntuSKU(ctx envcontext.ProviderCallContext, base jujubase.Base, stream, l
var versions ubuntuVersions
for _, img := range result.VirtualMachineImageResourceArray {
skuName := *img.Name
logger.Debugf("Found Azure SKU Name: %v", skuName)
if !strings.HasPrefix(skuName, version) {
logger.Debugf("ignoring SKU %q (does not match base %q with version %q)", skuName, base, version)
logger.Debugf("found Azure SKU Name: %v", skuName)
if !strings.HasPrefix(skuName, desiredSKUPrefix) {
logger.Debugf("ignoring SKU %q (does not match series %q)", skuName, series)
continue
}
version, tag, err := parseUbuntuSKU(skuName)
version, tag, err := parselegacyUbuntuSKU(skuName)
if err != nil {
logger.Errorf("ignoring SKU %q (failed to parse: %s)", skuName, err)
continue
Expand All @@ -125,7 +199,7 @@ func ubuntuSKU(ctx envcontext.ProviderCallContext, base jujubase.Base, stream, l
versions = append(versions, version)
}
if len(versions) == 0 {
return "", "", errors.NotFoundf("Ubuntu SKUs for %s stream", stream)
return "", "", errors.NotFoundf("legacy ubuntu %q SKUs for %s stream", series, stream)
}
sort.Sort(versions)
bestVersion := versions[len(versions)-1]
Expand All @@ -138,9 +212,9 @@ type ubuntuVersion struct {
Point int
}

// parseUbuntuSKU splits an UbuntuServer SKU into its
// parselegacyUbuntuSKU splits an UbuntuServer SKU into its
// version ("22_04.3") and tag ("LTS") parts.
func parseUbuntuSKU(sku string) (ubuntuVersion, string, error) {
func parselegacyUbuntuSKU(sku string) (ubuntuVersion, string, error) {
var version ubuntuVersion
var tag string
var err error
Expand Down
Loading

0 comments on commit 7f09e27

Please sign in to comment.