github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/upgrades/operations.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package upgrades
     5  
     6  import (
     7  	"github.com/juju/version"
     8  
     9  	jujuversion "github.com/juju/juju/version"
    10  )
    11  
    12  // stateUpgradeOperations returns an ordered slice of sets of
    13  // state-based operations needed to upgrade Juju to particular
    14  // version. The slice is ordered by target version, so that the sets
    15  // of operations are executed in order from oldest version to most
    16  // recent.
    17  //
    18  // All state-based operations are run before API-based operations
    19  // (below).
    20  var stateUpgradeOperations = func() []Operation {
    21  	steps := []Operation{
    22  		upgradeToVersion{version.MustParse("2.0.0"), stateStepsFor20()},
    23  		upgradeToVersion{version.MustParse("2.1.0"), stateStepsFor21()},
    24  		upgradeToVersion{version.MustParse("2.2.0"), stateStepsFor22()},
    25  		upgradeToVersion{version.MustParse("2.2.1"), stateStepsFor221()},
    26  		upgradeToVersion{version.MustParse("2.2.2"), stateStepsFor222()},
    27  		upgradeToVersion{version.MustParse("2.2.3"), stateStepsFor223()},
    28  		upgradeToVersion{version.MustParse("2.3.0"), stateStepsFor23()},
    29  		upgradeToVersion{version.MustParse("2.3.1"), stateStepsFor231()},
    30  		upgradeToVersion{version.MustParse("2.3.2"), stateStepsFor232()},
    31  		upgradeToVersion{version.MustParse("2.3.4"), stateStepsFor234()},
    32  		upgradeToVersion{version.MustParse("2.3.6"), stateStepsFor236()},
    33  		upgradeToVersion{version.MustParse("2.3.7"), stateStepsFor237()},
    34  		upgradeToVersion{version.MustParse("2.4.0"), stateStepsFor24()},
    35  		upgradeToVersion{version.MustParse("2.5.0"), stateStepsFor25()},
    36  	}
    37  	return steps
    38  }
    39  
    40  // upgradeOperations returns an ordered slice of sets of API-based
    41  // operations needed to upgrade Juju to particular version. As per the
    42  // state-based operations above, ordering is important.
    43  var upgradeOperations = func() []Operation {
    44  	steps := []Operation{
    45  		upgradeToVersion{version.MustParse("2.0.0"), stepsFor20()},
    46  		upgradeToVersion{version.MustParse("2.2.0"), stepsFor22()},
    47  		upgradeToVersion{version.MustParse("2.4.0"), stepsFor24()},
    48  		upgradeToVersion{version.MustParse("2.4.5"), stepsFor245()},
    49  	}
    50  	return steps
    51  }
    52  
    53  type opsIterator struct {
    54  	from    version.Number
    55  	to      version.Number
    56  	allOps  []Operation
    57  	current int
    58  }
    59  
    60  func newStateUpgradeOpsIterator(from version.Number) *opsIterator {
    61  	return newOpsIterator(from, jujuversion.Current, stateUpgradeOperations())
    62  }
    63  
    64  func newUpgradeOpsIterator(from version.Number) *opsIterator {
    65  	return newOpsIterator(from, jujuversion.Current, upgradeOperations())
    66  }
    67  
    68  func newOpsIterator(from, to version.Number, ops []Operation) *opsIterator {
    69  	// If from is not known, it is 1.16.
    70  	if from == version.Zero {
    71  		from = version.MustParse("1.16.0")
    72  	}
    73  
    74  	// Clear the version tag of the target release to ensure that all
    75  	// upgrade steps for the release are run for alpha and beta
    76  	// releases.
    77  	// ...but only do this if the agent version has actually changed,
    78  	// lest we trigger upgrade mode unnecessarily for non-final
    79  	// versions.
    80  	if from.Compare(to) != 0 {
    81  		to.Tag = ""
    82  	}
    83  
    84  	return &opsIterator{
    85  		from:    from,
    86  		to:      to,
    87  		allOps:  ops,
    88  		current: -1,
    89  	}
    90  }
    91  
    92  func (it *opsIterator) Next() bool {
    93  	for {
    94  		it.current++
    95  		if it.current >= len(it.allOps) {
    96  			return false
    97  		}
    98  		targetVersion := it.allOps[it.current].TargetVersion()
    99  
   100  		// Do not run steps for versions of Juju earlier or same as we are upgrading from.
   101  		if targetVersion.Compare(it.from) <= 0 {
   102  			continue
   103  		}
   104  		// Do not run steps for versions of Juju later than we are upgrading to.
   105  		if targetVersion.Compare(it.to) > 0 {
   106  			continue
   107  		}
   108  		return true
   109  	}
   110  }
   111  
   112  func (it *opsIterator) Get() Operation {
   113  	return it.allOps[it.current]
   114  }