github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/doc/provisioning.txt (about)

     1  What We Run, and Why
     2  ====================
     3  
     4  Expressed as compactly as possible, the Provisioner is responsible for making
     5  sure that non-Dead machine entities in state have agents running on live
     6  instances; and for making sure that Dead machines, and stray instances, are
     7  removed and cleaned up.
     8  
     9  However, the choice of exactly what we deploy involves some subtleties. At the
    10  Provisioner level, it's simple: the series and the constraints we pass to the
    11  Environ.StartInstance come from the machine entity. But how did they get there?
    12  
    13  Series
    14  ------
    15  
    16  Individual charms are released for different possible target series; juju
    17  should guarantee that charms for series X are only ever run on series X.
    18  Every service, unit, and machine has a series that's set at creation time and
    19  subsequently immutable. Units take their series from their service, and can
    20  only be assigned to machines with matching series.
    21  
    22  Subordinate units cannot be assigned directly to machines; they are created
    23  by their principals, on the same machine, in response to the creation of
    24  subordinate relations. We therefore restrict subordinate relations such that
    25  they can only be created between services with matching series.
    26  
    27  Constraints
    28  -----------
    29  
    30  Constraints are stored for environments, services, units, and machines, but
    31  unit constraints are not currently exposed because they're not needed outside
    32  state, and are likely to just cause trouble and confusion if we expose them.
    33  
    34  From the point of a user, there are environment constraints and service
    35  constraints, and sensible manipulations of them lead to predictable unit
    36  deployment decisions. The mechanism is as follows:
    37  
    38    * when a unit is added, the current environment and service constraints
    39      are collapsed into a single value and stored for the unit. (To be clear:
    40      at the moment the unit is created, the current service and environment
    41      constraints will be combined such that every constraint not set on the
    42      service is taken from the environment (or left unset, if not specified
    43      at all).
    44    * when a machine is being added in order to host a given unit, it copies
    45      its constraints directly from the unit.
    46    * when a machine is being added without a unit associated -- for example,
    47      when adding additional state servers -- it copies its constraints directly
    48      from the environment.
    49  
    50  In this way the following sequence of operations becomes predictable:
    51  
    52    $ juju deploy --constraints mem=2G wordpress
    53    $ juju set-constraints --service wordpress mem=3G
    54    $ juju add-unit wordpress -n 2
    55  
    56  ...in that exactly one machine will be provisioned with the first set of
    57  constraints, and exactly two of them will be provisioned using the second
    58  set. This is much friendlier to the users than delaying the unit constraint
    59  capture and potentially suffering subtle and annoying races.
    60  
    61  Subordinate units cannot have constraints, because their deployment is
    62  controlled by their principal units. There's only ever one machine to which
    63  that subordinate could (and must) be deployed, and to restrict that further
    64  by means of constraints will only confuse people.
    65  
    66  Machine Status and Provisioning Errors (current)
    67  ------------------------------------------------
    68  
    69  In the light of time pressure, a unit assigned to a machine that has not been
    70  provisioned can be removed directly by calling `juju destroy-unit`. Any
    71  provisioning error can thus be "resolved" in an unsophisticated but moderately
    72  effective way:
    73  
    74    $ juju destroy-unit borken/0
    75  
    76  ...in that at least broken units don't clutter up the service and prevent its
    77  removal. However:
    78  
    79    $ juju destroy-machine 1
    80  
    81  ...does not yet cause an unprovisioned machine to be removed from state (whether
    82  directly, or indirectly via the provisioner; the best place to implement this
    83  functionality is not clear).
    84  
    85  Machine Status and Provisioning Errors (WIP)
    86  --------------------------------------------
    87  
    88  [TODO: figure this out; not yet implemented, somewhat speculative... in
    89  particular, use of "resolved" may be inappropriate. Consider adding a
    90  "retry" CLI tool...]
    91  
    92  When the provisioner fails to start a machine, it should ensure that (1) the
    93  machine has no instance id set and (2) the machine has an error status set
    94  that communicates the nature of the problem. This must be visible in the
    95  output of `juju status`; and we must supply suitable tools to the user so
    96  as to allow her to respond appropriately.
    97  
    98  If the user believes a machine's provisioning error to be transient, she can
    99  do a simple `juju resolved 14` which will set some state to make machine 14
   100  eligible for the provisioner's attention again.
   101  
   102  It may otherwise be that the unit ended up snapshotting a service/environ
   103  config pair that really isn't satsifiable. In that case, the user can try
   104  (say) `juju resolved 14 --constraints "mem=2G cpu-power=400"`, which allows
   105  her to completely replace the machine's constraints as well as marking the
   106  machine for reprovisioning attention.