Skip to content

Commit

Permalink
Merge pull request #17182 from jack-w-shaw/3.5-into-main
Browse files Browse the repository at this point in the history
#17182

Merges:
- #17105
- #17117
- #17139
- #17152
- #17158
- #17118
- #17167
- #17175

Conflicts:
- internal/provider/vsphere/image_metadata.go
- internal/provider/vsphere/vm_template.go

Conflicts resulted from the usual context change. Resolved trivially
  • Loading branch information
jujubot committed Apr 11, 2024
2 parents 7a5f538 + 8cd722f commit 3ee4962
Show file tree
Hide file tree
Showing 20 changed files with 220 additions and 35 deletions.
8 changes: 2 additions & 6 deletions environs/imagemetadata/simplestreams.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,8 @@ const (
ReleasedStream = "released"
)

// ImageRelease maps a legacy series to an image version.
func ImageRelease(imSeries string) (string, error) {
base, err := corebase.GetBaseFromSeries(imSeries)
if err != nil {
return "", errors.Trace(err)
}
// ImageRelease maps a base to an image version.
func ImageRelease(base corebase.Base) (string, error) {
if base.OS != "centos" {
return base.Channel.Track, nil
}
Expand Down
8 changes: 1 addition & 7 deletions internal/provider/ec2/environ.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"github.com/juju/juju/cloud"
"github.com/juju/juju/controller"
"github.com/juju/juju/core/arch"
corebase "github.com/juju/juju/core/base"
"github.com/juju/juju/core/constraints"
corecontext "github.com/juju/juju/core/context"
"github.com/juju/juju/core/instance"
Expand Down Expand Up @@ -490,12 +489,7 @@ func (e *environ) AgentMetadataLookupParams(region string) (*simplestreams.Metad
// ImageMetadataLookupParams returns parameters which are used to query image simple-streams metadata.
func (e *environ) ImageMetadataLookupParams(region string) (*simplestreams.MetadataLookupParams, error) {
base := config.PreferredBase(e.ecfg())
baseSeries, err := corebase.GetSeriesFromBase(base)
if err != nil {
return nil, errors.Trace(err)
}

release, err := imagemetadata.ImageRelease(baseSeries)
release, err := imagemetadata.ImageRelease(base)
if err != nil {
return nil, errors.Trace(err)
}
Expand Down
8 changes: 1 addition & 7 deletions internal/provider/openstack/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import (

"github.com/juju/juju/cloud"
"github.com/juju/juju/cmd/juju/interact"
corebase "github.com/juju/juju/core/base"
"github.com/juju/juju/core/constraints"
"github.com/juju/juju/core/instance"
"github.com/juju/juju/core/network"
Expand Down Expand Up @@ -2289,12 +2288,7 @@ func (e *Environ) AgentMetadataLookupParams(region string) (*simplestreams.Metad
// ImageMetadataLookupParams returns parameters which are used to query image simple-streams metadata.
func (e *Environ) ImageMetadataLookupParams(region string) (*simplestreams.MetadataLookupParams, error) {
base := config.PreferredBase(e.ecfg())
baseSeries, err := corebase.GetSeriesFromBase(base)
if err != nil {
return nil, errors.Trace(err)
}

release, err := imagemetadata.ImageRelease(baseSeries)
release, err := imagemetadata.ImageRelease(base)
if err != nil {
return nil, errors.Trace(err)
}
Expand Down
5 changes: 3 additions & 2 deletions internal/provider/vsphere/image_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/juju/errors"

"github.com/juju/juju/core/base"
"github.com/juju/juju/environs"
"github.com/juju/juju/environs/imagemetadata"
"github.com/juju/juju/environs/simplestreams"
Expand All @@ -33,8 +34,8 @@ func init() {
simplestreams.RegisterStructTags(OvaFileMetadata{})
}

func findImageMetadata(ctx context.Context, env environs.Environ, arch string, series string) (*OvaFileMetadata, error) {
vers, err := imagemetadata.ImageRelease(series)
func findImageMetadata(ctx context.Context, env environs.Environ, arch string, b base.Base) (*OvaFileMetadata, error) {
vers, err := imagemetadata.ImageRelease(b)
if err != nil {
return nil, errors.Trace(err)
}
Expand Down
7 changes: 6 additions & 1 deletion internal/provider/vsphere/vm_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"

"github.com/juju/juju/core/base"
"github.com/juju/juju/environs"
"github.com/juju/juju/environs/imagemetadata"
"github.com/juju/juju/internal/provider/vsphere/internal/vsphereclient"
Expand Down Expand Up @@ -181,7 +182,11 @@ func (v *vmTemplateManager) downloadAndImportTemplate(
if err != nil {
return nil, "", errors.Trace(err)
}
img, err := findImageMetadata(ctx, v.env, arch, series)
b, err := base.GetBaseFromSeries(series)
if err != nil {
return nil, "", environs.ZoneIndependentError(err)
}
img, err := findImageMetadata(ctx, v.env, arch, b)
if err != nil {
return nil, "", environs.ZoneIndependentError(err)
}
Expand Down
9 changes: 9 additions & 0 deletions internal/worker/uniter/container/workload.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
// ReadyEvent is triggered when the container/pebble starts up.
ReadyEvent WorkloadEventType = iota
CustomNoticeEvent
ChangeUpdatedEvent
)

// WorkloadEvent contains information about the event type and data associated with
Expand Down Expand Up @@ -199,6 +200,14 @@ func (r *workloadHookResolver) NextOp(
NoticeType: evt.NoticeType,
NoticeKey: evt.NoticeKey,
})
case ChangeUpdatedEvent:
op, err = opFactory.NewRunHook(hook.Info{
Kind: hooks.PebbleChangeUpdated,
WorkloadName: evt.WorkloadName,
NoticeID: evt.NoticeID,
NoticeType: evt.NoticeType,
NoticeKey: evt.NoticeKey,
})
case ReadyEvent:
op, err = opFactory.NewRunHook(hook.Info{
Kind: hooks.PebbleReady,
Expand Down
43 changes: 43 additions & 0 deletions internal/worker/uniter/container/workload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,46 @@ func (s *workloadSuite) TestWorkloadCustomNoticeHook(c *gc.C) {
NoticeKey: "example.com/foo",
})
}

func (s *workloadSuite) TestWorkloadChangeUpdatedHook(c *gc.C) {
events := container.NewWorkloadEvents()
expectedErr := errors.Errorf("expected error")
handler := func(err error) {
c.Assert(err, gc.Equals, expectedErr)
}
containerResolver := container.NewWorkloadHookResolver(
loggo.GetLogger("test"),
events,
events.RemoveWorkloadEvent)
localState := resolver.LocalState{
State: operation.State{
Kind: operation.Continue,
Step: operation.Pending,
},
}
remoteState := remotestate.Snapshot{
WorkloadEvents: []string{
events.AddWorkloadEvent(container.WorkloadEvent{
Type: container.ChangeUpdatedEvent,
WorkloadName: "test",
NoticeID: "123",
NoticeType: "change-update",
NoticeKey: "42",
}, handler),
},
}
opFactory := &mockOperations{}
op, err := containerResolver.NextOp(context.Background(), localState, remoteState, opFactory)
c.Assert(err, jc.ErrorIsNil)
c.Assert(op, gc.NotNil)
op = operation.Unwrap(op)
hookOp, ok := op.(*mockRunHookOp)
c.Assert(ok, jc.IsTrue)
c.Assert(hookOp.hookInfo, gc.DeepEquals, hook.Info{
Kind: "pebble-change-updated",
WorkloadName: "test",
NoticeID: "123",
NoticeType: "change-update",
NoticeKey: "42",
})
}
2 changes: 1 addition & 1 deletion internal/worker/uniter/hook/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (hi Info) Validate() error {
return errors.Errorf("%q hook has a remote unit but no application", hi.Kind)
}
return nil
case hooks.PebbleCustomNotice:
case hooks.PebbleCustomNotice, hooks.PebbleChangeUpdated:
if hi.WorkloadName == "" {
return errors.Errorf("%q hook requires a workload name", hi.Kind)
}
Expand Down
6 changes: 6 additions & 0 deletions internal/worker/uniter/hook/hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ var validateTests = []struct {
}, {
hook.Info{Kind: hooks.PebbleCustomNotice, WorkloadName: "test"},
`"pebble-custom-notice" hook requires a notice ID, type, and key`,
}, {
hook.Info{Kind: hooks.PebbleChangeUpdated},
`"pebble-change-updated" hook requires a workload name`,
}, {
hook.Info{Kind: hooks.PebbleChangeUpdated, WorkloadName: "test"},
`"pebble-change-updated" hook requires a notice ID, type, and key`,
}, {
hook.Info{Kind: hooks.PreSeriesUpgrade},
`"pre-series-upgrade" hook requires a target base`,
Expand Down
2 changes: 2 additions & 0 deletions internal/worker/uniter/pebblenotices.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ func (n *pebbleNoticer) processNotice(containerName string, notice *client.Notic
switch notice.Type {
case client.CustomNotice:
eventType = container.CustomNoticeEvent
case client.ChangeUpdateNotice:
eventType = container.ChangeUpdatedEvent
default:
n.logger.Debugf("container %q: ignoring %s notice", containerName, notice.Type)
return nil
Expand Down
19 changes: 19 additions & 0 deletions internal/worker/uniter/pebblenotices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,25 @@ func (s *pebbleNoticerSuite) TestWaitNotices(c *gc.C) {
})
}

func (s *pebbleNoticerSuite) TestChangeUpdate(c *gc.C) {
s.setUpWorker(c, []string{"c1"})
defer workertest.CleanKill(c, s.worker)

s.clients["c1"].AddNotice(c, &client.Notice{
ID: "1",
Type: "change-update",
Key: "42",
LastRepeated: time.Now(),
})
s.waitWorkloadEvent(c, container.WorkloadEvent{
Type: container.ChangeUpdatedEvent,
WorkloadName: "c1",
NoticeID: "1",
NoticeType: "change-update",
NoticeKey: "42",
})
}

func (s *pebbleNoticerSuite) TestWaitNoticesError(c *gc.C) {
s.setUpWorker(c, []string{"c1"})
defer workertest.CleanKill(c, s.worker)
Expand Down
2 changes: 1 addition & 1 deletion internal/worker/uniter/runner/context/contextfactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ func (f *contextFactory) HookContext(stdCtx context.Context, hookInfo hook.Info)
ctx.workloadName = hookInfo.WorkloadName
hookName = fmt.Sprintf("%s-%s", hookInfo.WorkloadName, hookName)
switch hookInfo.Kind {
case hooks.PebbleCustomNotice:
case hooks.PebbleCustomNotice, hooks.PebbleChangeUpdated:
ctx.noticeID = hookInfo.NoticeID
ctx.noticeType = hookInfo.NoticeType
ctx.noticeKey = hookInfo.NoticeKey
Expand Down
7 changes: 1 addition & 6 deletions juju/testing/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (

"github.com/juju/juju/api"
"github.com/juju/juju/core/arch"
corebase "github.com/juju/juju/core/base"
"github.com/juju/juju/core/constraints"
"github.com/juju/juju/core/instance"
"github.com/juju/juju/core/model"
Expand Down Expand Up @@ -187,11 +186,7 @@ func FillInStartInstanceParams(env environs.Environ, machineId string, isControl
preferredBase := config.PreferredBase(env.Config())

if params.ImageMetadata == nil {
preferredSeries, err := corebase.GetSeriesFromBase(preferredBase)
if err != nil {
return errors.Trace(err)
}
vers, err := imagemetadata.ImageRelease(preferredSeries)
vers, err := imagemetadata.ImageRelease(preferredBase)
if err != nil {
return errors.Trace(err)
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/dqlite/scripts/dqlite/dqlite-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ build() {
sudo ln -s /usr/include/linux /usr/local/musl/include/linux || true

# Grab the queue.h file that does not ship with musl
sudo wget https://dev.midipix.org/compat/musl-compat/raw/main/f/include/sys/queue.h -O /usr/local/musl/include/sys/queue.h
sudo wget https://raw.githubusercontent.com/juju/musl-compat/main/include/sys/queue.h -O /usr/local/musl/include/sys/queue.h

# Install compile dependencies for statically linking everything:
# --------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ parts:
ln -s /usr/include/linux /usr/local/musl/include/linux
musl-compat:
source: https://dev.midipix.org/compat/musl-compat.git
source: https://github.com/juju/musl-compat.git
source-type: git
source-depth: 1
plugin: nil
Expand Down
31 changes: 31 additions & 0 deletions testcharms/charms/pebble-notices/src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ def __init__(self, *args):
self.framework.observe(self.on["redis"].pebble_ready, self._on_pebble_ready)
self.framework.observe(self.on["redis"].pebble_custom_notice, self._on_custom_notice)

# TODO(benhoyt): update to use pebble_change_updated once ops supports that:
# https://github.com/canonical/operator/pull/1170
import os
import pathlib

dispatch_path = pathlib.Path(os.environ.get("JUJU_DISPATCH_PATH", ""))
event_name = dispatch_path.name.replace("-", "_")
logger.info(f"__init__: path={dispatch_path} event={event_name}")
if event_name == "redis_pebble_change_updated":
event = ops.PebbleNoticeEvent(
None,
self.unit.get_container(os.environ["JUJU_WORKLOAD_NAME"]),
os.environ["JUJU_NOTICE_ID"],
os.environ["JUJU_NOTICE_TYPE"],
os.environ["JUJU_NOTICE_KEY"],
)
self._on_change_updated(event)

def _on_pebble_ready(self, event):
self.unit.status = ops.ActiveStatus()

Expand All @@ -28,6 +46,19 @@ def _on_custom_notice(self, event):
# Don't include the (arbitrary) ID in the status message
self.unit.status = ops.MaintenanceStatus(f"notice type={notice_type} key={notice_key}")

def _on_change_updated(self, event):
notice_id = event.notice.id
notice_type = (
event.notice.type if isinstance(event.notice.type, str) else event.notice.type.value
)
notice_key = event.notice.key
logger.info(f"_on_change_updated: id={notice_id} type={notice_type} key={notice_key}")

change = event.workload.pebble.get_change(notice_key)
self.unit.status = ops.MaintenanceStatus(
f"notice type={notice_type} kind={change.kind} status={change.status}"
)


if __name__ == "__main__":
ops.main(PebbleNoticesCharm)

0 comments on commit 3ee4962

Please sign in to comment.