Skip to content

Commit

Permalink
Merge branch '2.9' of github.com:juju/juju into feature/ecr
Browse files Browse the repository at this point in the history
  • Loading branch information
ycliuhw committed Sep 23, 2021
2 parents 7a9d145 + e5f2da6 commit 96412f6
Show file tree
Hide file tree
Showing 168 changed files with 5,328 additions and 894 deletions.
1 change: 1 addition & 0 deletions acceptancetests/assess_model_migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ def assert_model_migrated_successfully(
assert_deployed_charm_is_responding(client, resource_contents)
ensure_model_is_functional(client, application)


def migrate_model_to_controller(
source_model, source_client, dest_client, include_user_name=False):
log.info('Initiating migration process')
Expand Down
5 changes: 1 addition & 4 deletions acceptancetests/assess_model_migration_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ def assess_model_migration_versions(stable_bsm, devel_bsm, args):
stable_client = stable_bsm.client
devel_client = devel_bsm.client
resource_contents = get_random_string()
# Possible stable version doesn't handle migration subords (a fixed
# bug in later versions.)
test_stable_model, application = deploy_simple_server_to_new_model(
stable_client,
'version-migration',
Expand All @@ -77,14 +75,13 @@ def assess_model_migration_versions(stable_bsm, devel_bsm, args):
another_bsm.client.get_controller_client().wait_for(
AllMachinesRunning())
another_migration_client = migrate_model_to_controller(
test_stable_model,
migration_target_client.acquire_model_client('version-migration'),
migration_target_client, another_bsm.client)
assert_model_migrated_successfully(
another_migration_client, application, resource_contents)


class AllMachinesRunning(BaseCondition):

def iter_blocking_state(self, status):
for machine_no, status in status.iter_machines():
if status['machine-status']['current'] != 'running':
Expand Down
14 changes: 9 additions & 5 deletions acceptancetests/deploy_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -1086,11 +1086,15 @@ def runtime_context(self, addable_machines):
self.client.list_controllers()
self.client.list_models()

# Only show status for models the backend is tracking.
# This prevents errors attempting to retrieve status for
# models that have been issued a destroy command.
for m_client in self.client._backend.added_models:
m_client.show_status()
# Never let emission of model status constitute an error.
# Controllers in various stages of teardown can cause a
# race here.
for m_client in self.client.iter_model_clients():
try:
m_client.show_status()
except Exception as e:
logging.info("Exception calling status on tracked model: {}".format(e))

finally:
with self.client.ignore_soft_deadline():
with self.tear_down_client.ignore_soft_deadline():
Expand Down
9 changes: 5 additions & 4 deletions acceptancetests/jujupy/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1638,17 +1638,18 @@ def iter_model_clients(self):
for model in models:
# 2.2-rc1 introduced new model listing output name/short-name.
model_name = model.get('short-name', model['name'])
yield self._acquire_model_client(model_name, model.get('owner'))
yield self.acquire_model_client(model_name, model.get('owner'))

def get_controller_model_name(self):
@staticmethod
def get_controller_model_name():
"""Return the name of the 'controller' model.
Return the name of the environment when an 'controller' model does
not exist.
"""
return 'controller'

def _acquire_model_client(self, name, owner=None):
def acquire_model_client(self, name, owner=None):
"""Get a client for a model with the supplied name.
If the name matches self, self is used. Otherwise, a clone is used.
Expand Down Expand Up @@ -1696,7 +1697,7 @@ def get_controller_client(self):
This may be inaccurate for models created using add_model
rather than bootstrap.
"""
return self._acquire_model_client(self.get_controller_model_name())
return self.acquire_model_client(self.get_controller_model_name())

def list_controllers(self):
"""List the controllers."""
Expand Down
10 changes: 5 additions & 5 deletions acceptancetests/jujupy/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1729,20 +1729,20 @@ def test_iter_model_clients(self):
def test__acquire_model_client_returns_self_when_match(self):
client = ModelClient(JujuData('foo', {}), None, None)

self.assertEqual(client._acquire_model_client('foo'), client)
self.assertEqual(client._acquire_model_client('foo', None), client)
self.assertEqual(client.acquire_model_client('foo'), client)
self.assertEqual(client.acquire_model_client('foo', None), client)

def test__acquire_model_client_adds_username_component(self):
client = ModelClient(JujuData('foo', {}), None, None)

new_client = client._acquire_model_client('bar', None)
new_client = client.acquire_model_client('bar', None)
self.assertEqual(new_client.model_name, 'bar')

new_client = client._acquire_model_client('bar', 'user1')
new_client = client.acquire_model_client('bar', 'user1')
self.assertEqual(new_client.model_name, 'user1/bar')

client.env.user_name = 'admin'
new_client = client._acquire_model_client('baz', 'admin')
new_client = client.acquire_model_client('baz', 'admin')
self.assertEqual(new_client.model_name, 'baz')

def test_get_controller_model_name(self):
Expand Down
2 changes: 2 additions & 0 deletions agent/agentbootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/juju/juju/core/instance"
"github.com/juju/juju/core/model"
corenetwork "github.com/juju/juju/core/network"
"github.com/juju/juju/core/raft/queue"
"github.com/juju/juju/environs"
environscloudspec "github.com/juju/juju/environs/cloudspec"
"github.com/juju/juju/environs/config"
Expand Down Expand Up @@ -403,6 +404,7 @@ func initRaft(agentConfig agent.Config) error {
StorageDir: raftDir,
Logger: logger,
LocalID: coreraft.ServerID(agentConfig.Tag().Id()),
Queue: queue.NewBlockingOpQueue(clock.WallClock),
})
}

Expand Down
3 changes: 2 additions & 1 deletion api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package api

import (
"archive/zip"
"context"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -680,7 +681,7 @@ func (s *DeadlineStream) WriteJSON(v interface{}) error {
// WatchDebugLog returns a channel of structured Log Messages. Only log entries
// that match the filtering specified in the DebugLogParams are returned.
func (c *Client) WatchDebugLog(args common.DebugLogParams) (<-chan common.LogMessage, error) {
return common.StreamDebugLog(c.st, args)
return common.StreamDebugLog(context.TODO(), c.st, args)
}

// lxdCharmProfiler massages a charm.Charm into a LXDProfiler inside of the
Expand Down
16 changes: 8 additions & 8 deletions api/common/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package common

import (
"context"
"fmt"
"net/url"
"time"
Expand Down Expand Up @@ -104,14 +105,7 @@ type LogMessage struct {

// StreamDebugLog requests the specified debug log records from the
// server and returns a channel of the messages that come back.
func StreamDebugLog(source base.StreamConnector, args DebugLogParams) (<-chan LogMessage, error) {
// TODO(babbageclunk): this isn't cancellable - if the caller stops
// reading from the channel (because it has an error, for example),
// the goroutine will be leaked. This is OK when used from the command
// line, but is a problem if it happens in jujud. Change it to accept
// a stop channel and use a read deadline so that the client can stop
// it. https://pad.lv/1644084

func StreamDebugLog(ctx context.Context, source base.StreamConnector, args DebugLogParams) (<-chan LogMessage, error) {
// Prepare URL query attributes.
attrs := args.URLQuery()

Expand All @@ -125,6 +119,12 @@ func StreamDebugLog(source base.StreamConnector, args DebugLogParams) (<-chan Lo
defer close(messages)

for {
// If the context is done or cancelled, then we can check to ensure
// that the goroutine is cleaned up.
if ctx.Err() != nil {
return
}

var msg params.LogMessage
err := connection.ReadJSON(&msg)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions api/facadeversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ var facadeVersions = map[string]int{
"Pinger": 1,
"Provisioner": 11,
"ProxyUpdater": 2,
"RaftLease": 1,
"Reboot": 2,
"RelationStatusWatcher": 1,
"RelationUnitsWatcher": 1,
Expand Down
5 changes: 3 additions & 2 deletions api/migrationmaster/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package migrationmaster

import (
"context"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -302,8 +303,8 @@ func (c *Client) MinionReportTimeout() (time.Duration, error) {
// will yield the logs on or after that time - these are the logs that
// need to be transferred to the target after the migration is
// successful.
func (c *Client) StreamModelLog(start time.Time) (<-chan common.LogMessage, error) {
return common.StreamDebugLog(c.caller.RawAPICaller(), common.DebugLogParams{
func (c *Client) StreamModelLog(ctx context.Context, start time.Time) (<-chan common.LogMessage, error) {
return common.StreamDebugLog(ctx, c.caller.RawAPICaller(), common.DebugLogParams{
Replay: true,
NoTail: true,
StartTime: start,
Expand Down
2 changes: 1 addition & 1 deletion api/migrationmaster/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ func (s *ClientSuite) TestMinionReportTimeout(c *gc.C) {
func (s *ClientSuite) TestStreamModelLogs(c *gc.C) {
caller := fakeConnector{path: new(string), attrs: &url.Values{}}
client := migrationmaster.NewClient(caller, nil)
stream, err := client.StreamModelLog(time.Date(2016, 12, 2, 10, 24, 1, 1000000, time.UTC))
stream, err := client.StreamModelLog(context.TODO(), time.Date(2016, 12, 2, 10, 24, 1, 1000000, time.UTC))
c.Assert(stream, gc.IsNil)
c.Assert(err, gc.ErrorMatches, "colonel abrams")

Expand Down
56 changes: 49 additions & 7 deletions api/secretsmanager/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
package secretsmanager

import (
"strings"
"time"

"github.com/juju/errors"

"github.com/juju/juju/api/base"
Expand Down Expand Up @@ -71,7 +74,11 @@ func (c *Client) Create(cfg *secrets.SecretConfig, secretType secrets.SecretType
}

// Update updates an existing secret value and/or config like rotate interval.
func (c *Client) Update(URL *secrets.URL, cfg *secrets.SecretConfig, value secrets.SecretValue) (string, error) {
func (c *Client) Update(url string, cfg *secrets.SecretConfig, value secrets.SecretValue) (string, error) {
secretUrl, err := secrets.ParseURL(url)
if err != nil {
return "", errors.Trace(err)
}
if err := cfg.Validate(); err != nil {
return "", errors.Trace(err)
}
Expand All @@ -87,7 +94,7 @@ func (c *Client) Update(URL *secrets.URL, cfg *secrets.SecretConfig, value secre
var results params.StringResults

arg := params.UpdateSecretArg{
URL: URL.ID(),
URL: secretUrl.ID(),
RotateInterval: cfg.RotateInterval,
Description: cfg.Description,
Tags: cfg.Tags,
Expand All @@ -113,15 +120,22 @@ func (c *Client) Update(URL *secrets.URL, cfg *secrets.SecretConfig, value secre
}

// GetValue returns the value of a secret.
func (c *Client) GetValue(ID string) (secrets.SecretValue, error) {
//TODO(wallyworld) - validate ID format
func (c *Client) GetValue(urlOrId string) (secrets.SecretValue, error) {
arg := params.GetSecretArg{}
if strings.HasPrefix(urlOrId, secrets.SecretScheme+"://") {
secretUrl, err := secrets.ParseURL(urlOrId)
if err != nil {
return nil, errors.Trace(err)
}
arg.URL = secretUrl.ID()
} else {
arg.ID = urlOrId
}

var results params.SecretValueResults

if err := c.facade.FacadeCall("GetSecretValues", params.GetSecretArgs{
Args: []params.GetSecretArg{{
ID: ID,
}},
Args: []params.GetSecretArg{arg},
}, &results); err != nil {
return nil, errors.Trace(err)
}
Expand Down Expand Up @@ -156,3 +170,31 @@ func (c *Client) WatchSecretsRotationChanges(ownerTag string) (watcher.SecretRot
w := apiwatcher.NewSecretsRotationWatcher(c.facade.RawAPICaller(), result)
return w, nil
}

// SecretRotated records when a secret was last rotated.
func (c *Client) SecretRotated(url string, when time.Time) error {
secretUrl, err := secrets.ParseURL(url)
if err != nil {
return errors.Trace(err)
}

var results params.ErrorResults
args := params.SecretRotatedArgs{
Args: []params.SecretRotatedArg{{
URL: secretUrl.ID(),
When: when,
}},
}
err = c.facade.FacadeCall("SecretsRotated", args, &results)
if err != nil {
return errors.Trace(err)
}
if len(results.Results) != 1 {
return errors.Errorf("expected 1 result, got %d", len(results.Results))
}
result := results.Results[0]
if result.Error != nil {
return result.Error
}
return nil
}
Loading

0 comments on commit 96412f6

Please sign in to comment.