Merge lp:~thumper/juju-core/consolidate-bootstrap-initial-check into lp:~go-bot/juju-core/trunk

Proposed by Tim Penhey
Status: Merged
Approved by: Tim Penhey
Approved revision: no longer in the source branch.
Merged at revision: 1389
Proposed branch: lp:~thumper/juju-core/consolidate-bootstrap-initial-check
Merge into: lp:~go-bot/juju-core/trunk
Prerequisite: lp:~thumper/juju-core/consolidate-bootstrap-state
Diff against target: 170 lines (+48/-42)
5 files modified
environs/bootstrap.go (+26/-0)
environs/dummy/environs.go (+6/-1)
environs/ec2/ec2.go (+1/-18)
environs/maas/environ.go (+13/-4)
environs/openstack/provider.go (+2/-19)
To merge this branch: bzr merge lp:~thumper/juju-core/consolidate-bootstrap-initial-check
Reviewer Review Type Date Requested Status
John A Meinel Approve
Review via email: mp+172715@code.launchpad.net

Commit message

Make a common verification function for bootstrap

https://codereview.appspot.com/10888044/

Description of the change

Make a common verification function for bootstrap

All the providers did the same pre-bootstrap verification
(or should have in the case of maas). As discussed in Oakland,
I pulled the common code out into a shared function.

https://codereview.appspot.com/10888044/

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) wrote :
Download full text (6.9 KiB)

Reviewers: mp+172715_code.launchpad.net,

Message:
Please take a look.

Description:
Make a common verification function for bootstrap

All the providers did the same pre-bootstrap verification
(or should have in the case of maas). As discussed in Oakland,
I pulled the common code out into a shared function.

https://code.launchpad.net/~thumper/juju-core/consolidate-bootstrap-initial-check/+merge/172715

Requires:
https://code.launchpad.net/~thumper/juju-core/consolidate-bootstrap-state/+merge/172701

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/10888044/

Affected files:
   A [revision details]
   M environs/bootstrap.go
   M environs/dummy/environs.go
   M environs/ec2/ec2.go
   M environs/maas/environ.go
   M environs/openstack/provider.go

Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: <email address hidden>
+New revision: <email address hidden>

Index: environs/bootstrap.go
=== modified file 'environs/bootstrap.go'
--- environs/bootstrap.go 2013-07-02 23:28:43 +0000
+++ environs/bootstrap.go 2013-07-03 01:16:51 +0000
@@ -7,6 +7,8 @@
   "fmt"

   "launchpad.net/juju-core/constraints"
+ "launchpad.net/juju-core/errors"
+ "launchpad.net/juju-core/utils"
  )

  // Bootstrap bootstraps the given environment. The supplied constraints are
@@ -33,3 +35,32 @@
   }
   return environ.Bootstrap(cons)
  }
+
+// VerifyBootstrapInit does the common initial check inside bootstrap to
+// confirm that the environment isn't already running, and that the storage
+// works.
+func VerifyBootstrapInit(env Environ, shortAttempt utils.AttemptStrategy)
error {
+ var err error
+
+ // If the state file exists, it might actually have just been
+ // removed by Destroy, and eventual consistency has not caught
+ // up yet, so we retry to verify if that is happening.
+ for a := shortAttempt.Start(); a.Next(); {
+ _, err = LoadProviderState(env.Storage())
+ if err != nil {
+ break
+ }
+ }
+ if err == nil {
+ return fmt.Errorf("environment is already bootstrapped")
+ }
+ if !errors.IsNotFoundError(err) {
+ return fmt.Errorf("cannot query old bootstrap state: %v", err)
+ }
+
+ err = VerifyStorage(env.Storage())
+ if err != nil {
+ return err
+ }
+ return nil
+}

Index: environs/dummy/environs.go
=== modified file 'environs/dummy/environs.go'
--- environs/dummy/environs.go 2013-06-30 23:37:23 +0000
+++ environs/dummy/environs.go 2013-07-03 01:23:46 +0000
@@ -433,7 +433,12 @@
   if _, ok := e.Config().CACert(); !ok {
    return fmt.Errorf("no CA certificate in environment configuration")
   }
- if err := environs.VerifyStorage(e.Storage()); err != nil {
+
+ var shortAttempt = utils.AttemptStrategy{
+ Total: 200 * time.Millisecond,
+ Delay: 10 * time.Millisecond,
+ }
+ if err := environs.VerifyBootstrapInit(e, shortAttempt); err != nil {
    return err
   }

Index: environs/ec2/ec2.go
=== modified file 'environs/ec2/ec2.go'
--- environs/ec2/ec2.go 2013-07-02 23:15:14 +0000
+++ environs/ec2/ec2....

Read more...

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

An historical note on why MAAS skips the verification step. When we were implementing Bootstrap() in the MAAS provider, we were told that this verification step was needed specifically to deal with lazily-consistent storage — and since MAAS storage is immediately consistent, it wasn't needed in that case.

So that's why we did not duplicate this bit of code in the MAAS provider. Replacing the duplicated code with a generic function that applies to all cases makes it a whole different ballgame, of course.

Revision history for this message
John A Meinel (jameinel) wrote :

If we are not 'lazily consistent' then we can probably drop shortAttemptStrategy down to a max of 1s or something like that.

This code LGTM, though it depends on your earlier work which means sorting out the syntax for that.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'environs/bootstrap.go'
--- environs/bootstrap.go 2013-07-04 23:08:28 +0000
+++ environs/bootstrap.go 2013-07-04 23:08:28 +0000
@@ -7,6 +7,8 @@
7 "fmt"7 "fmt"
88
9 "launchpad.net/juju-core/constraints"9 "launchpad.net/juju-core/constraints"
10 "launchpad.net/juju-core/errors"
11 "launchpad.net/juju-core/utils"
10)12)
1113
12// Bootstrap bootstraps the given environment. The supplied constraints are14// Bootstrap bootstraps the given environment. The supplied constraints are
@@ -33,3 +35,27 @@
33 }35 }
34 return environ.Bootstrap(cons)36 return environ.Bootstrap(cons)
35}37}
38
39// VerifyBootstrapInit does the common initial check inside bootstrap to
40// confirm that the environment isn't already running, and that the storage
41// works.
42func VerifyBootstrapInit(env Environ, shortAttempt utils.AttemptStrategy) error {
43 var err error
44
45 // If the state file exists, it might actually have just been
46 // removed by Destroy, and eventual consistency has not caught
47 // up yet, so we retry to verify if that is happening.
48 for a := shortAttempt.Start(); a.Next(); {
49 if _, err = LoadState(env.Storage()); err != nil {
50 break
51 }
52 }
53 if err == nil {
54 return fmt.Errorf("environment is already bootstrapped")
55 }
56 if !errors.IsNotFoundError(err) {
57 return fmt.Errorf("cannot query old bootstrap state: %v", err)
58 }
59
60 return VerifyStorage(env.Storage())
61}
3662
=== modified file 'environs/dummy/environs.go'
--- environs/dummy/environs.go 2013-07-02 21:52:48 +0000
+++ environs/dummy/environs.go 2013-07-04 23:08:28 +0000
@@ -433,7 +433,12 @@
433 if _, ok := e.Config().CACert(); !ok {433 if _, ok := e.Config().CACert(); !ok {
434 return fmt.Errorf("no CA certificate in environment configuration")434 return fmt.Errorf("no CA certificate in environment configuration")
435 }435 }
436 if err := environs.VerifyStorage(e.Storage()); err != nil {436
437 var shortAttempt = utils.AttemptStrategy{
438 Total: 200 * time.Millisecond,
439 Delay: 10 * time.Millisecond,
440 }
441 if err := environs.VerifyBootstrapInit(e, shortAttempt); err != nil {
437 return err442 return err
438 }443 }
439444
440445
=== modified file 'environs/ec2/ec2.go'
--- environs/ec2/ec2.go 2013-07-02 21:52:48 +0000
+++ environs/ec2/ec2.go 2013-07-04 23:08:28 +0000
@@ -16,7 +16,6 @@
16 "launchpad.net/juju-core/environs/imagemetadata"16 "launchpad.net/juju-core/environs/imagemetadata"
17 "launchpad.net/juju-core/environs/instances"17 "launchpad.net/juju-core/environs/instances"
18 "launchpad.net/juju-core/environs/tools"18 "launchpad.net/juju-core/environs/tools"
19 "launchpad.net/juju-core/errors"
20 "launchpad.net/juju-core/instance"19 "launchpad.net/juju-core/instance"
21 "launchpad.net/juju-core/log"20 "launchpad.net/juju-core/log"
22 "launchpad.net/juju-core/state"21 "launchpad.net/juju-core/state"
@@ -240,25 +239,9 @@
240 // If the state file exists, it might actually have just been239 // If the state file exists, it might actually have just been
241 // removed by Destroy, and eventual consistency has not caught240 // removed by Destroy, and eventual consistency has not caught
242 // up yet, so we retry to verify if that is happening.241 // up yet, so we retry to verify if that is happening.
243 var err error242 if err := environs.VerifyBootstrapInit(e, shortAttempt); err != nil {
244 for a := shortAttempt.Start(); a.Next(); {
245 _, err = environs.LoadState(e.Storage())
246 if err != nil {
247 break
248 }
249 }
250 if err == nil {
251 return fmt.Errorf("environment is already bootstrapped")
252 }
253 if !errors.IsNotFoundError(err) {
254 return fmt.Errorf("cannot query old bootstrap state: %v", err)
255 }
256
257 err = environs.VerifyStorage(e.Storage())
258 if err != nil {
259 return err243 return err
260 }244 }
261
262 possibleTools, err := environs.FindBootstrapTools(e, cons)245 possibleTools, err := environs.FindBootstrapTools(e, cons)
263 if err != nil {246 if err != nil {
264 return err247 return err
265248
=== modified file 'environs/maas/environ.go'
--- environs/maas/environ.go 2013-07-02 21:52:48 +0000
+++ environs/maas/environ.go 2013-07-04 23:08:28 +0000
@@ -28,6 +28,16 @@
28 apiVersion = "1.0"28 apiVersion = "1.0"
29)29)
3030
31// A request may fail to due "eventual consistency" semantics, which
32// should resolve fairly quickly. A request may also fail due to a slow
33// state transition (for instance an instance taking a while to release
34// a security group after termination). The former failure mode is
35// dealt with by shortAttempt, the latter by longAttempt.
36var shortAttempt = utils.AttemptStrategy{
37 Total: 5 * time.Second,
38 Delay: 200 * time.Millisecond,
39}
40
31var longAttempt = utils.AttemptStrategy{41var longAttempt = utils.AttemptStrategy{
32 Total: 3 * time.Minute,42 Total: 3 * time.Minute,
33 Delay: 1 * time.Second,43 Delay: 1 * time.Second,
@@ -100,10 +110,9 @@
100110
101// Bootstrap is specified in the Environ interface.111// Bootstrap is specified in the Environ interface.
102func (env *maasEnviron) Bootstrap(cons constraints.Value) error {112func (env *maasEnviron) Bootstrap(cons constraints.Value) error {
103 // TODO(fwereade): this should check for an existing environment before113
104 // starting a new one -- even given raciness, it's better than nothing.114 if err := environs.VerifyBootstrapInit(env, shortAttempt); err != nil {
105 if err := environs.VerifyStorage(env.Storage()); err != nil {115 return err
106 return fmt.Errorf("provider storage is not writeable")
107 }116 }
108117
109 inst, err := env.startBootstrapNode(cons)118 inst, err := env.startBootstrapNode(cons)
110119
=== modified file 'environs/openstack/provider.go'
--- environs/openstack/provider.go 2013-07-02 21:52:48 +0000
+++ environs/openstack/provider.go 2013-07-04 23:08:28 +0000
@@ -22,7 +22,6 @@
22 "launchpad.net/juju-core/environs/imagemetadata"22 "launchpad.net/juju-core/environs/imagemetadata"
23 "launchpad.net/juju-core/environs/instances"23 "launchpad.net/juju-core/environs/instances"
24 "launchpad.net/juju-core/environs/tools"24 "launchpad.net/juju-core/environs/tools"
25 coreerrors "launchpad.net/juju-core/errors"
26 "launchpad.net/juju-core/instance"25 "launchpad.net/juju-core/instance"
27 "launchpad.net/juju-core/log"26 "launchpad.net/juju-core/log"
28 "launchpad.net/juju-core/state"27 "launchpad.net/juju-core/state"
@@ -466,24 +465,8 @@
466465
467func (e *environ) Bootstrap(cons constraints.Value) error {466func (e *environ) Bootstrap(cons constraints.Value) error {
468 log.Infof("environs/openstack: bootstrapping environment %q", e.name)467 log.Infof("environs/openstack: bootstrapping environment %q", e.name)
469 // If the state file exists, it might actually have just been468
470 // removed by Destroy, and eventual consistency has not caught469 if err := environs.VerifyBootstrapInit(e, shortAttempt); err != nil {
471 // up yet, so we retry to verify if that is happening.
472 var err error
473 for a := shortAttempt.Start(); a.Next(); {
474 _, err = environs.LoadState(e.Storage())
475 if err != nil {
476 break
477 }
478 }
479 if err == nil {
480 return fmt.Errorf("environment is already bootstrapped")
481 }
482 if !coreerrors.IsNotFoundError(err) {
483 return fmt.Errorf("cannot query old bootstrap state: %v", err)
484 }
485 err = environs.VerifyStorage(e.Storage())
486 if err != nil {
487 return err470 return err
488 }471 }
489472

Subscribers

People subscribed via source and target branches

to status/vote changes: