Skip to content

Commit 371c584

Browse files
committed
Support controller charm dir and do checks early
1 parent 39f2156 commit 371c584

File tree

10 files changed

+132
-25
lines changed

10 files changed

+132
-25
lines changed

apiserver/facades/client/application/application.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,7 +1646,7 @@ func (api *APIBase) AddUnits(args params.AddApplicationUnits) (params.AddApplica
16461646
return params.AddApplicationUnitsResults{}, errors.Trace(err)
16471647
}
16481648
if ch.Meta().Name == bootstrap.ControllerCharmName {
1649-
return params.AddApplicationUnitsResults{}, errors.NotSupportedf("add units to the controller application")
1649+
return params.AddApplicationUnitsResults{}, errors.NotSupportedf("adding units to the controller application")
16501650
}
16511651

16521652
if err := api.checkCanWrite(); err != nil {
@@ -1813,7 +1813,7 @@ func (api *APIBase) DestroyUnit(args params.DestroyUnitsParams) (params.DestroyU
18131813
appCharms[appName] = ch
18141814
}
18151815
if ch.Meta().Name == bootstrap.ControllerCharmName {
1816-
return nil, errors.NotSupportedf("remove units from the controller application")
1816+
return nil, errors.NotSupportedf("removing units from the controller application")
18171817
}
18181818

18191819
var info params.DestroyUnitInfo

cloudconfig/userdatacfg_test.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package cloudconfig_test
66

77
import (
8+
"bytes"
89
"encoding/base64"
910
"encoding/json"
1011
"fmt"
@@ -777,8 +778,26 @@ func checkCloudInitWithContent(c *gc.C, cfg *testInstanceConfig, expectedScripts
777778
assertScriptMatch(c, scripts, expectedScripts, false)
778779
}
779780

780-
func (*cloudinitSuite) TestCloudInitWithLocalControllerCharm(c *gc.C) {
781-
ch := testcharms.RepoForSeries("quantal").CharmDir("juju-controller")
781+
func (*cloudinitSuite) TestCloudInitWithLocalControllerCharmDir(c *gc.C) {
782+
controllerCharmPath := testcharms.Repo.CharmDir("juju-controller").Path
783+
ch, err := charm.ReadCharmDir(controllerCharmPath)
784+
c.Assert(err, jc.ErrorIsNil)
785+
buf := bytes.NewBuffer(nil)
786+
err = ch.ArchiveTo(buf)
787+
c.Assert(err, jc.ErrorIsNil)
788+
content := buf.Bytes()
789+
790+
cfg := makeBootstrapConfig("precise", 0).setControllerCharm(controllerCharmPath)
791+
base64Content := base64.StdEncoding.EncodeToString(content)
792+
expectedScripts := regexp.QuoteMeta(fmt.Sprintf(`chmod 0600 '/var/lib/juju/agents/machine-0/agent.conf'
793+
install -D -m 644 /dev/null '/var/lib/juju/charms/controller.charm'
794+
printf %%s %s | base64 -d > '/var/lib/juju/charms/controller.charm'
795+
`, base64Content))
796+
checkCloudInitWithContent(c, cfg, expectedScripts, "")
797+
}
798+
799+
func (*cloudinitSuite) TestCloudInitWithLocalControllerCharmArchive(c *gc.C) {
800+
ch := testcharms.Repo.CharmDir("juju-controller")
782801
dir, err := charm.ReadCharmDir(ch.Path)
783802
c.Assert(err, jc.ErrorIsNil)
784803

cloudconfig/userdatacfg_unix.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"strings"
1616
"text/template"
1717

18+
"github.com/juju/charm/v9"
1819
"github.com/juju/errors"
1920
"github.com/juju/featureflag"
2021
"github.com/juju/loggo"
@@ -542,10 +543,28 @@ func (w *unixConfigure) addLocalControllerCharmsUpload() error {
542543
}
543544

544545
logger.Infof("preparing to upload controller charm from %v", charmPath)
545-
charmData, err := ioutil.ReadFile(charmPath)
546+
_, err := charm.ReadCharm(charmPath)
546547
if err != nil {
547548
return errors.Trace(err)
548549
}
550+
var charmData []byte
551+
if charm.IsCharmDir(charmPath) {
552+
ch, err := charm.ReadCharmDir(charmPath)
553+
if err != nil {
554+
return errors.Trace(err)
555+
}
556+
buf := bytes.NewBuffer(nil)
557+
err = ch.ArchiveTo(buf)
558+
if err != nil {
559+
return errors.Trace(err)
560+
}
561+
charmData = buf.Bytes()
562+
} else {
563+
charmData, err = ioutil.ReadFile(charmPath)
564+
if err != nil {
565+
return errors.Trace(err)
566+
}
567+
}
549568
w.conf.AddRunBinaryFile(path.Join(w.icfg.CharmDir(), bootstrap.ControllerCharmArchive), charmData, 0644)
550569

551570
return nil

cmd/juju/commands/bootstrap.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ func (c *bootstrapCommand) SetFlags(f *gnuflag.FlagSet) {
328328
f.BoolVar(&c.noSwitch, "no-switch", false, "Do not switch to the newly created controller")
329329
f.BoolVar(&c.Force, "force", false, "Allow the bypassing of checks such as supported series")
330330
f.BoolVar(&c.noHostedModel, "no-default-model", false, "Do not create a default model")
331-
f.StringVar(&c.ControllerCharmPath, "controller-charm", "", "Path to a locally built controller.charm")
331+
f.StringVar(&c.ControllerCharmPath, "controller-charm", "", "Path to a locally built controller charm")
332332
}
333333

334334
func (c *bootstrapCommand) Init(args []string) (err error) {
@@ -362,6 +362,13 @@ func (c *bootstrapCommand) Init(args []string) (err error) {
362362
if err != nil {
363363
return errors.Annotatef(err, "problem with --controller-charm")
364364
}
365+
ch, err := charm.ReadCharm(c.ControllerCharmPath)
366+
if err != nil {
367+
return errors.Errorf("--controller-charm %q is not a valid charm", c.ControllerCharmPath)
368+
}
369+
if ch.Meta().Name != bootstrap.ControllerCharmName {
370+
return errors.Errorf("--controller-charm %q is not a %q charm", c.ControllerCharmPath, bootstrap.ControllerCharmName)
371+
}
365372
}
366373

367374
if c.showClouds && c.showRegionsForCloud != "" {

cmd/juju/commands/bootstrap_test.go

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import (
6060
_ "github.com/juju/juju/provider/ec2"
6161
"github.com/juju/juju/provider/openstack"
6262
"github.com/juju/juju/storage"
63+
"github.com/juju/juju/testcharms"
6364
coretesting "github.com/juju/juju/testing"
6465
coretools "github.com/juju/juju/tools"
6566
jujuversion "github.com/juju/juju/version"
@@ -2135,24 +2136,43 @@ func (s *BootstrapSuite) TestBootstrapTestingOptions(c *gc.C) {
21352136
}
21362137

21372138
func (s *BootstrapSuite) TestBootstrapWithControllerCharm(c *gc.C) {
2138-
var gotArgs bootstrap.BootstrapParams
2139-
bootstrapFuncs := &fakeBootstrapFuncs{
2140-
bootstrapF: func(_ environs.BootstrapContext, _ environs.BootstrapEnviron, callCtx context.ProviderCallContext, args bootstrap.BootstrapParams) error {
2141-
gotArgs = args
2142-
return errors.New("test error")
2139+
for _, test := range []struct {
2140+
charmPath string
2141+
err string
2142+
}{
2143+
{
2144+
charmPath: testcharms.Repo.CharmDir("juju-controller").Path,
2145+
}, {
2146+
charmPath: testcharms.Repo.CharmDir("mysql").Path,
2147+
err: `--controller-charm ".*mysql" is not a "juju-controller" charm`,
2148+
}, {
2149+
charmPath: c.MkDir(),
2150+
err: `--controller-charm ".*" is not a valid charm`,
2151+
}, {
2152+
charmPath: "/invalid/path",
2153+
err: `problem with --controller-charm: stat /invalid/path: no such file or directory`,
21432154
},
2155+
} {
2156+
var gotArgs bootstrap.BootstrapParams
2157+
bootstrapFuncs := &fakeBootstrapFuncs{
2158+
bootstrapF: func(_ environs.BootstrapContext, _ environs.BootstrapEnviron, callCtx context.ProviderCallContext, args bootstrap.BootstrapParams) error {
2159+
gotArgs = args
2160+
return errors.New("test error")
2161+
},
2162+
}
2163+
s.PatchValue(&getBootstrapFuncs, func() BootstrapInterface {
2164+
return bootstrapFuncs
2165+
})
2166+
_, err := cmdtesting.RunCommand(c, s.newBootstrapCommand(),
2167+
"dummy", "devcontroller", "--controller-charm", test.charmPath,
2168+
)
2169+
if test.err == "" {
2170+
c.Assert(err, gc.Equals, cmd.ErrSilent)
2171+
c.Assert(gotArgs.ControllerCharmPath, gc.DeepEquals, test.charmPath)
2172+
} else {
2173+
c.Assert(err, gc.ErrorMatches, test.err)
2174+
}
21442175
}
2145-
s.PatchValue(&getBootstrapFuncs, func() BootstrapInterface {
2146-
return bootstrapFuncs
2147-
})
2148-
controllerCharm := filepath.Join(c.MkDir(), "controller.charm")
2149-
err := ioutil.WriteFile(controllerCharm, nil, 0644)
2150-
c.Assert(err, jc.ErrorIsNil)
2151-
_, err = cmdtesting.RunCommand(c, s.newBootstrapCommand(),
2152-
"dummy", "devcontroller", "--controller-charm", controllerCharm,
2153-
)
2154-
c.Assert(err, gc.Equals, cmd.ErrSilent)
2155-
c.Assert(gotArgs.ControllerCharmPath, gc.DeepEquals, controllerCharm)
21562176
}
21572177

21582178
func (s *BootstrapSuite) TestBootstrapSetsControllerOnBase(c *gc.C) {

cmd/jujud/agent/bootstrap.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,25 @@ func addControllerApplication(st *state.State, curl *charm.URL, m *state.Machine
467467
if err != nil {
468468
return errors.Trace(err)
469469
}
470+
cfg := charm.Settings{
471+
"is-juju": true,
472+
}
473+
controllerCfg, err := st.ControllerConfig()
474+
if err != nil {
475+
return errors.Trace(err)
476+
}
477+
cfg["identity-provider-url"] = controllerCfg.IdentityURL()
478+
addr := controllerCfg.PublicDNSAddress()
479+
if addr == "" {
480+
pa, err := m.PublicAddress()
481+
if err != nil && !network.IsNoAddressError(err) {
482+
return errors.Trace(err)
483+
}
484+
if err == nil {
485+
addr = pa.Value
486+
}
487+
}
488+
cfg["controller-url"] = fmt.Sprintf("https://%s", addr)
470489
app, err := st.AddApplication(state.AddApplicationArgs{
471490
Name: bootstrap.ControllerApplicationName,
472491
Series: curl.Series,
@@ -475,6 +494,7 @@ func addControllerApplication(st *state.State, curl *charm.URL, m *state.Machine
475494
Source: curl.Schema,
476495
Type: "charm",
477496
},
497+
CharmConfig: cfg,
478498
})
479499
if err != nil {
480500
return errors.Trace(err)

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ require (
4040
github.com/imdario/mergo v0.3.10 // indirect
4141
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a
4242
github.com/juju/bundlechanges/v5 v5.0.0-20210105101225-fc10c61af1f3
43-
github.com/juju/charm/v9 v9.0.0-20210105084816-5204c3802611
44-
github.com/juju/charmrepo/v7 v7.0.0-20210105092546-af3d6b52f7de
43+
github.com/juju/charm/v9 v9.0.0-20210107011734-a80982922c69
44+
github.com/juju/charmrepo/v7 v7.0.0-20210107021745-6d3b0475f2e4
4545
github.com/juju/clock v0.0.0-20190205081909-9c5c9712527c
4646
github.com/juju/cmd v0.0.0-20200108104440-8e43f3faa5c9
4747
github.com/juju/collections v0.0.0-20200605021417-0d0ec82b7271

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,12 @@ github.com/juju/bundlechanges/v5 v5.0.0-20210105101225-fc10c61af1f3 h1:0bDD/ukLO
395395
github.com/juju/bundlechanges/v5 v5.0.0-20210105101225-fc10c61af1f3/go.mod h1:0Us8R+t7wi4ZORNGznWWB07hkDOQFGVznTHOwY2XXfQ=
396396
github.com/juju/charm/v9 v9.0.0-20210105084816-5204c3802611 h1:LQEQJvPHjeFNNAMgQpjthtF0SRzNz2+H/YCK0HmJxs4=
397397
github.com/juju/charm/v9 v9.0.0-20210105084816-5204c3802611/go.mod h1:ffLfwuA4E426HlTtqgMvKZdBAWXOwbgeeHye/1ITTLc=
398+
github.com/juju/charm/v9 v9.0.0-20210107011734-a80982922c69 h1:VzRv22mb6gJNoAEgkZWQRW1EfUAt8Krw68C1Jw8n3sQ=
399+
github.com/juju/charm/v9 v9.0.0-20210107011734-a80982922c69/go.mod h1:ffLfwuA4E426HlTtqgMvKZdBAWXOwbgeeHye/1ITTLc=
398400
github.com/juju/charmrepo/v7 v7.0.0-20210105092546-af3d6b52f7de h1:95Or6HY8Lfpv007aWUNMKzw2AnDXPOyqQjlO/N3UfjU=
399401
github.com/juju/charmrepo/v7 v7.0.0-20210105092546-af3d6b52f7de/go.mod h1:hnCmP2zszIv2WqLZpHyM+4/bkEvDZi5MLHRsvi58Lhs=
402+
github.com/juju/charmrepo/v7 v7.0.0-20210107021745-6d3b0475f2e4 h1:s51mNG4ES7lUzMMLzDU8Vb7r0+/LIv4FUSMPwVHMBsQ=
403+
github.com/juju/charmrepo/v7 v7.0.0-20210107021745-6d3b0475f2e4/go.mod h1:dZDpX+a046U+tWpVqv9dUK62PQKyVjuR8lEhJVLvRpg=
400404
github.com/juju/clock v0.0.0-20180524022203-d293bb356ca4/go.mod h1:nD0vlnrUjcjJhqN5WuCWZyzfd5AHZAC9/ajvbSx69xA=
401405
github.com/juju/clock v0.0.0-20180808021310-bab88fc67299/go.mod h1:nD0vlnrUjcjJhqN5WuCWZyzfd5AHZAC9/ajvbSx69xA=
402406
github.com/juju/clock v0.0.0-20190205081909-9c5c9712527c h1:3UvYABOQRhJAApj9MdCN+Ydv841ETSoy6xLzdmmr/9A=

state/charm_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ actions:
777777
`
778778

779779
func (s *CharmTestHelperSuite) TestActionsCharm(c *gc.C) {
780-
actions, err := charm.ReadActionsYaml(bytes.NewBuffer([]byte(actionsYaml)))
780+
actions, err := charm.ReadActionsYaml("somecharm", bytes.NewBuffer([]byte(actionsYaml)))
781781
c.Assert(err, jc.ErrorIsNil)
782782

783783
forEachStandardCharm(c, func(name string) {

state/machine.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99
"time"
1010

11+
"github.com/juju/charm/v9"
1112
"github.com/juju/collections/set"
1213
"github.com/juju/errors"
1314
"github.com/juju/names/v4"
@@ -26,6 +27,7 @@ import (
2627
"github.com/juju/juju/core/model"
2728
"github.com/juju/juju/core/network"
2829
"github.com/juju/juju/core/status"
30+
"github.com/juju/juju/environs/bootstrap"
2931
"github.com/juju/juju/mongo"
3032
stateerrors "github.com/juju/juju/state/errors"
3133
"github.com/juju/juju/tools"
@@ -1750,10 +1752,26 @@ func (m *Machine) setAddresses(machineAddresses, providerAddresses *[]network.Sp
17501752
"machine %q preferred public address changed from %q to %q",
17511753
m.Id(), oldPublic, newPublic.networkAddress(),
17521754
)
1755+
if err := m.st.maybeUpdateControllerCharm(m.doc.PreferredPublicAddress.Value); err != nil {
1756+
return errors.Trace(err)
1757+
}
17531758
}
17541759
return nil
17551760
}
17561761

1762+
func (st *State) maybeUpdateControllerCharm(publicAddr string) error {
1763+
controllerApp, err := st.Application(bootstrap.ControllerApplicationName)
1764+
if errors.IsNotFound(err) {
1765+
return nil
1766+
}
1767+
if err != nil {
1768+
return errors.Trace(err)
1769+
}
1770+
return controllerApp.UpdateCharmConfig(model.GenerationMaster, charm.Settings{
1771+
"controller-url": fmt.Sprintf("https://%s", publicAddr),
1772+
})
1773+
}
1774+
17571775
func (m *Machine) setAddressesOps(
17581776
machineAddresses, providerAddresses *[]network.SpaceAddress,
17591777
) (_ []txn.Op, machineStateAddresses, providerStateAddresses []address, newPrivate, newPublic *address, _ error) {

0 commit comments

Comments
 (0)