def refresh(snapname, **kw): '''Update a snap. Snap will be pulled from the coresponding resource if available and reinstalled if it has changed. Otherwise a 'snap refresh' is run updating the snap from the Snap Store, potentially switching channel and changing confinement options. ''' # Note that once you upload a resource, you can't remove it. # This means we don't need to cope with an operator switching # from a resource provided to a store provided snap, because there # is no way for them to do that. Well, actually the operator could # upload a zero byte resource, but then we would need to uninstall # the snap before reinstalling from the store and that has the # potential for data loss. local_flag = get_local_flag(snapname) if hookenv.has_juju_version('2.0'): res_path = _resource_get(snapname) if res_path is False: _refresh_store(snapname, **kw) reactive.clear_flag(local_flag) else: _install_local(res_path, **kw) reactive.set_flag(local_flag) else: _refresh_store(snapname, **kw) reactive.clear_flag(local_flag)
def initialize(self): if self.requests is not None: return # Already initialized. assert hookenv.has_juju_version('1.23'), 'Needs Juju 1.23+' if self.relname is None: self.relname = _implicit_peer_relation_name() relids = hookenv.relation_ids(self.relname) if relids: self.relid = sorted(relids)[0] # Load our state, from leadership, the peer relationship, and maybe # local state as a fallback. Populates self.requests and self.grants. self._load_state() self._emit_state() # Save our state if the hook completes successfully. hookenv.atexit(self._save_state) # Schedule release of granted locks for the end of the hook. # This needs to be the last of our atexit callbacks to ensure # it will be run first when the hook is complete, because there # is no point mutating our state after it has been saved. hookenv.atexit(self._release_granted)
def install(snapname, **kw): '''Install a snap. Snap will be installed from the coresponding resource if available, otherwise from the Snap Store. Sets the snap.installed.{snapname} flag. If the snap.installed.{snapname} flag is already set then the refresh() function is called. ''' installed_flag = get_installed_flag(snapname) local_flag = get_local_flag(snapname) if reactive.is_flag_set(installed_flag): refresh(snapname, **kw) else: if hookenv.has_juju_version('2.0'): res_path = _resource_get(snapname) if res_path is False: _install_store(snapname, **kw) else: _install_local(res_path, **kw) reactive.set_flag(local_flag) else: _install_store(snapname, **kw) reactive.set_flag(installed_flag) # Installing any snap will first ensure that 'core' is installed. Set an # appropriate flag for consumers that want to get/set core options. core_installed = get_installed_flag('core') if not reactive.is_flag_set(core_installed): reactive.set_flag(core_installed)
def install(snapname, **kw): '''Install a snap. Snap will be installed from the coresponding resource if available, otherwise from the Snap Store. Sets the snap.installed.{snapname} state. If the snap.installed.{snapname} state is already set and the snap options have been changed, then the refresh() function is called. ''' installed_state = 'snap.installed.{}'.format(snapname) if reactive.is_state(installed_state): if data_changed('snap.opts.{}'.format(snapname), kw): refresh(snapname, **kw) else: if hookenv.has_juju_version('2.0'): res_path = _resource_get(snapname) if res_path is False: _install_store(snapname, **kw) else: _install_local(res_path, **kw) else: _install_store(snapname, **kw) reactive.set_state(installed_state)
def initialize(self): if self.requests is not None: return # Already initialized. assert hookenv.has_juju_version('1.23'), 'Needs Juju 1.23+' if self.relname is None: self.relname = _implicit_peer_relation_name() relids = hookenv.relation_ids(self.relname) if relids: self.relid = sorted(relids)[0] # Load our state, from leadership, the peer relationship, and maybe # local state as a fallback. Populates self.requests and self.grants. self._load_state() self._emit_state() # Save our state if the hook completes successfully. hookenv.atexit(self._save_state) # Schedule release of granted locks for the end of the hook. # This needs to be the last of our atexit callbacks to ensure # it will be run first when the hook is complete, because there # is no point mutating our state after it has been saved. hookenv.atexit(self._release_granted)
def listen_ip_address(): c = config() # Pre-juju2, listen_interface was used to control the interface used for # communication & replication between Cassandra units. if c['listen_interface'] or not hookenv.has_juju_version('2.3'): return (interface_to_ip(c['listen_interface']) or hookenv.unit_private_ip()) # Post-juju2, addresses for relation endpoints can be specified at deploy time # in a standard way, so listen_interface in config should be unnecessary. ip = hookenv.network_get('cluster')['bind-addresses'][0]['addresses'][0]['address'] hookenv.log('listen_ip_address == {!r}'.format(ip), DEBUG) return ip
def ingress_address(endpoint, relid): # Work around https://github.com/juju/charm-helpers/issues/112 if not hookenv.has_juju_version("2.3"): return hookenv.unit_private_ip() try: d = hookenv.network_get(endpoint, relid) return d["ingress-addresses"][0] except NotImplementedError: # Warn, although this is normal with older Juju. hookenv.log( "Unable to determine ingress address, " "falling back to private ip", hookenv.WARNING, ) return hookenv.unit_private_ip()
def rpc_broadcast_ip_address(): c = config() # Pre-juju2, rpc_interface was used to control the interface used for # client communication. if c['rpc_interface'] or not hookenv.has_juju_version('2.3'): return (interface_to_ip(c['rpc_interface']) or hookenv.unit_public_ip()) # Post-juju2, addresses for relation endpoints can be specified at deploy time # in a standard way, so listen_interface in config should be unnecessary. # Only the database endpoint is used, as Cassandra only supports a single # IP address to broadcast as the connection address. ip = hookenv.network_get('database')['ingress-addresses'][0] hookenv.log('rpc_broadcast_ip_address == {!r}'.format(ip), DEBUG) return ip
def default_hook(): if not hookenv.has_juju_version('1.24'): hookenv.status_set('blocked', 'Requires Juju 1.24 or higher') # Error state, since we don't have 1.24 to give a nice blocked state. raise SystemExit(1) # These need to be imported after bootstrap() or required Python # packages may not have been installed. import definitions # Only useful for debugging, or perhaps have this enabled with a config # option? ## from loglog import loglog ## loglog('/var/log/cassandra/system.log', prefix='C*: ') hookenv.log('*** {} Hook Start'.format(hookenv.hook_name())) sm = definitions.get_service_manager() sm.manage() hookenv.log('*** {} Hook Done'.format(hookenv.hook_name()))
def refresh(snapname, **kw): '''Update a snap. Snap will be pulled from the coresponding resource if available and reinstalled if it has changed. Otherwise a 'snap refresh' is run updating the snap from the Snap Store, potentially switching channel and changing confinement options. ''' # Note that once you upload a resource, you can't remove it. # This means we don't need to cope with an operator switching # from a resource provided to a store provided snap, because there # is no way for them to do that. if hookenv.has_juju_version('2.0'): res_path = _resource_get(snapname) if res_path is False: _refresh_store(snapname, **kw) else: _install_local(res_path, **kw) else: _refresh_store(snapname, **kw)
def block_on_bad_juju(): if not hookenv.has_juju_version('1.24'): status_set('blocked', 'Requires Juju 1.24 or higher') # Error state, since we don't have 1.24 to give a nice blocked state. raise SystemExit(1)