API for Upgrader

John Arbash Meinel john at arbash-meinel.com
Thu Jun 20 12:47:15 UTC 2013


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Just a rough outline of what William and I just discussed as the API
needed for Upgrader.

I'm writing this down partially so I don't forget it, and partially to
get pre-implementation feedback.

Essentially the whole Upgrader API becomes a single function, which is
"start a watcher to tell me about the desired Agent version for this
list of agents, and the watcher signals by sending a state.Tools
struct describing the desired version and a URL to download the
associated tools".

In rough prototypes:

type WatchAgentToolsParams struct {
  Id string
  Arch string
  Series string
}

Upgrader().WatchAgentTools(params []WatchAgentToolsParams) []WatcherResult


type AgentToolsChange struct {
  Id string
  Tools state.Tools
}


var change AgentToolsChange
change, err := <-watcher.Changes()



The Id being passed can be either for a Machine agent or a Unit agent.
And both types of agents will use the same API.

The initial implementation on the APIServer side will just use
state.WatchEnvironConfig(). With these steps:

1) Initially we can just fire a watch response on any change to
EnvironConfig. This will trigger a few too many probes, but the
Upgrader code already has a:
  if proposed == version.Current.Number {
    noDelay()
    break
  }

So it doesn't create much extra load on the system.

2) Stage 2 can have the API server track what the current API version
is, and only fire the watcher when API version changes. That mostly
just changes the load on the API server, because it doesn't have to
search for updated tools.

3) Stage 3 can only tell Machine or Unit agents that there is a new
API version once it finds there are binaries for it to download. (we
might do this before 2). This handles the heterogenous series and Arch
environments when someone doesn't upload all possible tools case.

4) Stage 4 we can get extra fancy by only telling the Machine that
there is a new API version to download, and only once the Machine
reports a new Machine API, do we tell the Unit agents to upgrade.

This helps with the "thundering herds" case. Where someone requests an
upgrade, and then every agent ever wakes up and tries to download new
tools. (So if you have a Machine with a Unit and a subordinate Unit,
you would download the tools 3 times, only to have 2 of them get
thrown away)

5) While it doesn't make a lot of sense today to have a Watcher across
multiple agents, it is possible we will change responsibilities (say
one upgrader per container).


We pass the Arch and Series to the API Server for this, so we can
lookup the Tools URL for the agents directly in the API. Eventually
when Ian's patch lands that sort of information may already be stored
in the state database, but it isn't there today, and requiring it in
the API means you can upgrade to 1.11 and still have the upgrader
function normally.

Should the change itself be an array: eg:
type AgentTools struct {
  Id string
  Tools *state.Tools
}

type AgentToolsChange []AgentTools

Or should watcher.Changes fire multiple times for multiple units?

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.13 (Cygwin)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iEYEARECAAYFAlHC+dMACgkQJdeBCYSNAAPGhwCggwnGmpUHKzRNWVEmPdpgNwD1
jWoAn0tuyKn0c4W4ZHDFrYsVZI3cgeXe
=KRyE
-----END PGP SIGNATURE-----



More information about the Juju-dev mailing list