def determine_packages(source=None): # currently all packages match service names packages = [] + BASE_PACKAGES for v in resource_map().values(): packages.extend(v['services']) if manage_plugin(): pkgs = neutron_plugin_attribute(config('neutron-plugin'), 'server_packages', 'neutron') packages.extend(pkgs) if get_os_codename_install_source(source) >= 'kilo': packages.extend(KILO_PACKAGES) if config('neutron-plugin') == 'vsp': nuage_pkgs = config('nuage-packages').split() packages += nuage_pkgs if git_install_requested(): packages.extend(BASE_GIT_PACKAGES) # don't include packages that will be installed from git packages = list(set(packages)) for p in GIT_PACKAGE_BLACKLIST: if p in packages: packages.remove(p) if get_os_codename_install_source(source) >= 'kilo': for p in GIT_PACKAGE_BLACKLIST_KILO: packages.remove(p) return list(set(packages))
def check_for_upgrade(): if not os.path.exists(ceph._upgrade_keyring): log("Ceph upgrade keyring not detected, skipping upgrade checks.") return c = hookenv.config() old_version = ceph.resolve_ceph_version(c.previous('source') or 'distro') log('old_version: {}'.format(old_version)) new_version = ceph.resolve_ceph_version(hookenv.config('source') or 'distro') log('new_version: {}'.format(new_version)) old_version_os = get_os_codename_install_source(c.previous('source') or 'distro') new_version_os = get_os_codename_install_source(hookenv.config('source')) # May be in a previous upgrade that was failed if the directories # still need an ownership update. Check this condition. resuming_upgrade = ceph.dirs_need_ownership_update('osd') if (ceph.UPGRADE_PATHS.get(old_version) == new_version) or\ resuming_upgrade: if old_version == new_version: log('Attempting to resume possibly failed upgrade.', INFO) else: log("{} to {} is a valid upgrade path. Proceeding.".format( old_version, new_version)) emit_cephconf(upgrading=True) ceph.roll_osd_cluster(new_version=new_version, upgrade_key='osd-upgrade') emit_cephconf(upgrading=False) elif (old_version == new_version and old_version_os < new_version_os): # See LP: #1778823 add_source(hookenv.config('source'), hookenv.config('key')) log(("The installation source has changed yet there is no new major " "version of Ceph in this new source. As a result no package " "upgrade will take effect. Please upgrade manually if you need " "to."), level=INFO) else: # Log a helpful error message log("Invalid upgrade path from {} to {}. " "Valid paths are: {}".format(old_version, new_version, ceph.pretty_print_upgrade_paths()), level=ERROR)
def get_packages(): """Return a list of packages for install based on the configured plugin""" plugin = remap_plugin(config("plugin")) packages = deepcopy(GATEWAY_PKGS[networking_name()][plugin]) source = get_os_codename_install_source(config("openstack-origin")) if plugin == "ovs": if source >= "icehouse" and lsb_release()["DISTRIB_CODENAME"] < "utopic": # NOTE(jamespage) neutron-vpn-agent supercedes l3-agent for # icehouse but openswan was removed in utopic. packages.remove("neutron-l3-agent") packages.append("neutron-vpn-agent") packages.append("openswan") if source >= "kilo": packages.append("python-neutron-fwaas") if source >= "liberty": # Switch out mysql driver packages.remove("python-mysqldb") packages.append("python-pymysql") # Switch out to actual metering agent package packages.remove("neutron-plugin-metering-agent") packages.append("neutron-metering-agent") packages.extend(determine_l3ha_packages()) if git_install_requested(): packages = list(set(packages)) packages.extend(BASE_GIT_PACKAGES) # don't include packages that will be installed from git for p in GIT_PACKAGE_BLACKLIST: if p in packages: packages.remove(p) return packages
def do_openstack_pkg_upgrade(self): """Upgrade OpenStack packages :returns: None """ new_src = self.config['openstack-origin'] new_os_rel = os_utils.get_os_codename_install_source(new_src) hookenv.log('Performing OpenStack upgrade to %s.' % (new_os_rel)) os_utils.configure_installation_source(new_src) charmhelpers.fetch.apt_update() dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] charmhelpers.fetch.apt_upgrade( options=dpkg_opts, fatal=True, dist=True) charmhelpers.fetch.apt_install( packages=self.all_packages, options=dpkg_opts, fatal=True) self.release = new_os_rel
def do_openstack_upgrade(configs): """ Perform an upgrade. Takes care of upgrading packages, rewriting configs, database migrations and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ cur_os_rel = os_release('neutron-common') new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update(fatal=True) apt_upgrade(options=dpkg_opts, fatal=True, dist=True) pkgs = determine_packages(new_os_rel) # Sort packages just to make unit tests easier pkgs.sort() apt_install(packages=pkgs, options=dpkg_opts, fatal=True) # set CONFIGS to load templates from new release configs.set_release(openstack_release=new_os_rel) # Before kilo it's nova-cloud-controllers job if is_elected_leader(CLUSTER_RES): #stamp_neutron_database(cur_os_rel) migrate_neutron_database()
def do_openstack_upgrade(configs): """ Perform an uprade of cinder. Takes care of upgrading packages, rewriting configs + database migration and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) juju_log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update() apt_install(packages=determine_packages(), options=dpkg_opts, fatal=True) # set CONFIGS to load templates from new release and regenerate config configs.set_release(openstack_release=new_os_rel) configs.write_all() if eligible_leader(CLUSTER_RES): migrate_database()
def get_packages(): '''Return a list of packages for install based on the configured plugin''' plugin = remap_plugin(config('plugin')) packages = deepcopy(GATEWAY_PKGS[networking_name()][plugin]) source = get_os_codename_install_source(config('openstack-origin')) if plugin == 'ovs': if (source >= 'icehouse' and lsb_release()['DISTRIB_CODENAME'] < 'utopic'): # NOTE(jamespage) neutron-vpn-agent supercedes l3-agent for # icehouse but openswan was removed in utopic. packages.remove('neutron-l3-agent') packages.append('neutron-vpn-agent') packages.append('openswan') if source >= 'kilo': packages.append('python-neutron-fwaas') if source >= 'liberty': # Switch out mysql driver packages.remove('python-mysqldb') packages.append('python-pymysql') # Switch out to actual metering agent package packages.remove('neutron-plugin-metering-agent') packages.append('neutron-metering-agent') packages.extend(determine_l3ha_packages()) if git_install_requested(): packages = list(set(packages)) packages.extend(BASE_GIT_PACKAGES) # don't include packages that will be installed from git for p in GIT_PACKAGE_BLACKLIST: if p in packages: packages.remove(p) return packages
def register_configs(): ''' Register config files with their respective contexts. ''' release = get_os_codename_install_source(config('openstack-origin')) configs = templating.OSConfigRenderer(templates_dir=TEMPLATES, openstack_release=release) plugin = remap_plugin(config('plugin')) name = networking_name() if plugin == 'ovs': # NOTE: deal with switch to ML2 plugin for >= icehouse drop_config = NEUTRON_ML2_PLUGIN_CONF if release >= 'icehouse': drop_config = NEUTRON_OVS_PLUGIN_CONF if drop_config in CONFIG_FILES[name][plugin]: CONFIG_FILES[name][plugin].pop(drop_config) if is_relation_made('amqp-nova'): amqp_nova_ctxt = context.AMQPContext( ssl_dir=NOVA_CONF_DIR, rel_name='amqp-nova', relation_prefix='nova') else: amqp_nova_ctxt = context.AMQPContext( ssl_dir=NOVA_CONF_DIR, rel_name='amqp') CONFIG_FILES[name][plugin][NOVA_CONF][ 'hook_contexts'].append(amqp_nova_ctxt) for conf in CONFIG_FILES[name][plugin]: configs.register(conf, CONFIG_FILES[name][plugin][conf]['hook_contexts']) return configs
def do_openstack_upgrade(configs): """ Perform an upgrade. Takes care of upgrading packages, rewriting configs, database migrations and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update(fatal=True) apt_upgrade(options=dpkg_opts, fatal=True, dist=True) reset_os_release() apt_install(packages=CEILOMETER_AGENT_PACKAGES, options=dpkg_opts, fatal=True) # Call apt_install a 2nd time to allow packages which are enabled # for specific OpenStack version to be installed . This is because # Openstack version for a subordinate should be derived from the # version of an installed package rather than relying on # openstack-origin which would not be present in a subordinate. apt_install(get_packages(), fatal=True) remove_old_packages() # set CONFIGS to load templates from new release configs.set_release(openstack_release=new_os_rel)
def install(): execd_preinstall() src = config('openstack-origin') if src != 'distro': openstack.configure_installation_source(src) apt_update(fatal=True) rel = openstack.get_os_codename_install_source(src) pkgs = determine_packages(rel) apt_install(pkgs, fatal=True) apt_install(extra_pkgs, fatal=True) ensure_swift_dir() # initialize new storage rings. for ring in SWIFT_RINGS.iteritems(): initialize_ring(ring[1], config('partition-power'), config('replicas'), config('min-hours')) # configure a directory on webserver for distributing rings. if not os.path.isdir(WWW_DIR): os.mkdir(WWW_DIR, 0755) uid, gid = swift_user() os.chown(WWW_DIR, uid, gid)
def do_openstack_upgrade(configs): """Perform an upgrade of glance. Takes care of upgrading packages, rewriting configs + database migration and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update() apt_upgrade(options=dpkg_opts, fatal=True, dist=True) apt_install(determine_packages(), fatal=True) # set CONFIGS to load templates from new release and regenerate config configs.set_release(openstack_release=new_os_rel) configs.write_all() [service_stop(s) for s in services()] if is_elected_leader(CLUSTER_RES): migrate_database() # Don't start services if the unit is supposed to be paused. if not is_unit_paused_set(): [service_start(s) for s in services()]
def do_openstack_upgrade(configs): """Perform an uprade of heat. Takes care of upgrading packages, rewriting configs and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update() apt_upgrade(options=dpkg_opts, fatal=True, dist=True) packages = BASE_PACKAGES + BASE_SERVICES apt_install(packages=packages, options=dpkg_opts, fatal=True) # set CONFIGS to load templates from new release and regenerate config configs.set_release(openstack_release=new_os_rel) configs.write_all() migrate_database()
def ceilometer_upgrade_helper(CONFIGS): """Helper function to run ceilomter-upgrde, and then call assess_status(...) in effect, so that the status is correctly updated. Uses ceilomter_upgrde to do the work. @param configs: a templating.OSConfigRenderer() object @returns None - this function is executed for its side-effect """ cmp_codename = CompareOpenStackReleases( get_os_codename_install_source(config('openstack-origin'))) if cmp_codename < 'queens': identity_relation = 'identity-service' else: identity_relation = 'identity-credentials' # NOTE(jamespage): ceilometer@ocata requires both gnocchi # and mongodb to be configured to successfully # upgrade the underlying data stores. if ('metric-service' not in CONFIGS.complete_contexts() or identity_relation not in CONFIGS.complete_contexts()): raise FailedAction('The {} and or metric-service relations are not ' 'complete. ceilometer-upgrade cannot be run until ' 'they are ready.'.format(identity_relation)) # NOTE(jamespage): however at queens, this limitation has gone! if (cmp_codename < 'pike' and 'mongodb' not in CONFIGS.complete_contexts()): raise FailedAction('This version of ceilometer requires both gnocchi ' 'and mongodb. Mongodb relation incomplete.') try: ceilometer_upgrade(action=True) except subprocess.CalledProcessError as e: raise FailedAction('ceilometer-upgrade resulted in an ' 'unexpected error: {}'.format(e.message), outcome='ceilometer-upgrade failed, see traceback.', trace=traceback.format_exc())
def do_openstack_upgrade(configs): """Perform an uprade of cinder. Takes care of upgrading packages, rewriting configs + database migration and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ new_src = config("openstack-origin") new_os_rel = get_os_codename_install_source(new_src) log("Performing OpenStack upgrade to %s." % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = ["--option", "Dpkg::Options::=--force-confnew", "--option", "Dpkg::Options::=--force-confdef"] apt_update() apt_upgrade(options=dpkg_opts, fatal=True, dist=True) apt_install(determine_packages(), fatal=True) # set CONFIGS to load templates from new release and regenerate config configs.set_release(openstack_release=new_os_rel) configs.write_all() [service_stop(s) for s in services()] if is_elected_leader(CLUSTER_RES): migrate_database() [service_start(s) for s in services()]
def do_openstack_upgrade(configs): """ Perform an upgrade. Takes care of upgrading packages, rewriting configs, database migrations and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update(fatal=True) apt_upgrade(options=dpkg_opts, fatal=True, dist=True) reset_os_release() apt_install(determine_packages(), fatal=True) remove_old_packages() # set CONFIGS to load templates from new release configs.set_release(openstack_release=new_os_rel)
def get_uri(self, prefix=None): driver = 'mysql' release = ch_utils.get_os_codename_install_source( self.config['openstack-origin']) if (ch_utils.OPENSTACK_RELEASES.index(release) >= ch_utils.OPENSTACK_RELEASES.index('stein')): driver = 'mysql+pymysql' if prefix: uri = '{}://{}:{}@{}/{}'.format( driver, self.relation.username(prefix=prefix), self.relation.password(prefix=prefix), self.host, self.relation.database(prefix=prefix), ) else: uri = '{}://{}:{}@{}/{}'.format( driver, self.username, self.password, self.host, self.database, ) try: if self.ssl_ca: uri = '{}?ssl_ca={}'.format(uri, self.ssl_ca) if self.ssl_cert: uri = ('{}&ssl_cert={}&ssl_key={}' .format(uri, self.ssl_cert, self.ssl_key)) except AttributeError: # ignore ssl_ca or ssl_cert if not available pass return uri
def core_plugin(): plugin = remap_plugin(config('plugin')) if (get_os_codename_install_source(config('openstack-origin')) >= 'icehouse' and plugin == OVS): return NEUTRON_ML2_PLUGIN else: return CORE_PLUGIN[networking_name()][plugin]
def ceilometer_release_packages(): codename = get_os_codename_install_source(config('openstack-origin')) if codename >= 'mitaka': return MITAKA_PACKAGES elif codename >= 'icehouse': return ICEHOUSE_PACKAGES else: return []
def remap_plugin(plugin): ''' Remaps plugin name for renames/switches in packaging ''' release = get_os_codename_install_source(config('openstack-origin')) if plugin == 'nvp' and release >= 'icehouse': plugin = 'nsx' elif plugin == 'nsx' and release < 'icehouse': plugin = 'nvp' return plugin
def resolve_services(): _services = deepcopy(BASE_SERVICES) os_rel = get_os_codename_install_source(config('openstack-origin')) for release in SERVICE_BLACKLIST: if os_rel >= release: [_services.remove(service) for service in SERVICE_BLACKLIST[release]] return _services
def config_changed(): # If neutron is ready to be queried then check for incompatability between # existing neutron objects and charm settings codename = get_os_codename_install_source(config('openstack-origin')) if codename >= 'kilo': branch = "stable/%s" % codename pip_install("git+https://github.com/openstack/networking-hyperv.git@%s" % branch) if neutron_ready(): if l3ha_router_present() and not get_l3ha(): e = ('Cannot disable Router HA while ha enabled routers exist.' ' Please remove any ha routers') status_set('blocked', e) raise Exception(e) if dvr_router_present() and not get_dvr(): e = ('Cannot disable dvr while dvr enabled routers exist. Please' ' remove any distributed routers') log(e, level=ERROR) status_set('blocked', e) raise Exception(e) if config('prefer-ipv6'): status_set('maintenance', 'configuring ipv6') setup_ipv6() sync_db_with_multi_ipv6_addresses(config('database'), config('database-user')) global CONFIGS if git_install_requested(): if config_value_changed('openstack-origin-git'): status_set('maintenance', 'Running Git install') git_install(config('openstack-origin-git')) elif not config('action-managed-upgrade'): if openstack_upgrade_available('neutron-common'): status_set('maintenance', 'Running openstack upgrade') do_openstack_upgrade(CONFIGS) additional_install_locations( config('neutron-plugin'), config('openstack-origin') ) status_set('maintenance', 'Installing apt packages') apt_install(filter_installed_packages( determine_packages(config('openstack-origin'))), fatal=True) configure_https() update_nrpe_config() CONFIGS.write_all() for r_id in relation_ids('neutron-api'): neutron_api_relation_joined(rid=r_id) for r_id in relation_ids('neutron-plugin-api'): neutron_plugin_api_relation_joined(rid=r_id) for r_id in relation_ids('amqp'): amqp_joined(relation_id=r_id) for r_id in relation_ids('identity-service'): identity_joined(rid=r_id) for rid in relation_ids('zeromq-configuration'): zeromq_configuration_relation_joined(rid) [cluster_joined(rid) for rid in relation_ids('cluster')]
def ceilometer_release_packages(): cmp_codename = CompareOpenStackReleases( get_os_codename_install_source(config('openstack-origin'))) if cmp_codename >= 'mitaka' and cmp_codename < 'queens': return MITAKA_PACKAGES elif cmp_codename >= 'icehouse': return ICEHOUSE_PACKAGES else: return []
def _do_openstack_upgrade(new_src): enable_policy_rcd() cur_os_rel = os_release('nova-common') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] # NOTE(jamespage) pre-stamp neutron database before upgrade from grizzly if cur_os_rel == 'grizzly': neutron_db_manage(['stamp', 'grizzly']) apt_update(fatal=True) apt_upgrade(options=dpkg_opts, fatal=True, dist=True) apt_install(determine_packages(), fatal=True) disable_policy_rcd() if cur_os_rel == 'grizzly': # NOTE(jamespage) when upgrading from grizzly->havana, config # files need to be generated prior to performing the db upgrade reset_os_release() configs = register_configs(release=new_os_rel) configs.write_all() neutron_db_manage(['upgrade', 'head']) else: if new_os_rel < 'kilo': neutron_db_manage(['stamp', cur_os_rel]) migrate_neutron_database() # NOTE(jamespage) upgrade with existing config files as the # havana->icehouse migration enables new service_plugins which # create issues with db upgrades reset_os_release() configs = register_configs(release=new_os_rel) configs.write_all() if new_os_rel >= 'mitaka' and not database_setup(prefix='novaapi'): # NOTE: Defer service restarts and database migrations for now # as nova_api database is not yet created if (relation_ids('cluster') and is_elected_leader(CLUSTER_RES)): # NOTE: reset dbsync state so that migration will complete # when the nova_api database is setup. peer_store('dbsync_state', None) return configs if is_elected_leader(CLUSTER_RES): status_set('maintenance', 'Running nova db migration') migrate_nova_database() if not is_unit_paused_set(): [service_start(s) for s in services()] return configs
def additional_install_locations(plugin, source): ''' Add any required additional package locations for the charm, based on the Neutron plugin being used. This will also force an immediate package upgrade. ''' release = get_os_codename_install_source(source) if plugin == 'Calico': if config('calico-origin'): calico_source = config('calico-origin') elif release in ('icehouse', 'juno', 'kilo'): # Prior to the Liberty release, Calico's Nova and Neutron changes # were not fully upstreamed, so we need to point to a # release-specific PPA that includes Calico-specific Nova and # Neutron packages. calico_source = 'ppa:project-calico/%s' % release else: # From Liberty onwards, we can point to a PPA that does not include # any patched OpenStack packages, and hence is independent of the # OpenStack release. calico_source = 'ppa:project-calico/stable' add_source(calico_source) elif plugin == 'midonet': midonet_origin = config('midonet-origin') release_num = midonet_origin.split('-')[1] if midonet_origin.startswith('mem'): with open(os.path.join(charm_dir(), 'files/midokura.key')) as midokura_gpg_key: priv_gpg_key = midokura_gpg_key.read() mem_username = config('mem-username') mem_password = config('mem-password') if release in ('juno', 'kilo', 'liberty'): add_source( 'deb http://%s:%[email protected]/openstack/%s/stable ' 'trusty main' % (mem_username, mem_password, release), key=priv_gpg_key) add_source('http://%s:%[email protected]/midonet/v%s/stable ' 'main' % (mem_username, mem_password, release_num), key=priv_gpg_key) else: with open(os.path.join(charm_dir(), 'files/midonet.key')) as midonet_gpg_key: pub_gpg_key = midonet_gpg_key.read() if release in ('juno', 'kilo', 'liberty'): add_source( 'deb http://repo.midonet.org/openstack-%s stable main' % release, key=pub_gpg_key) add_source('deb http://repo.midonet.org/midonet/v%s stable main' % release_num, key=pub_gpg_key) apt_update(fatal=True) apt_upgrade(fatal=True)
def stop_services(): release = get_os_codename_install_source(config('openstack-origin')) plugin = config('plugin') config_files = resolve_config_files(plugin, release) svcs = set() for ctxt in config_files[config('plugin')].itervalues(): for svc in ctxt['services']: svcs.add(remap_service(svc)) for svc in svcs: service_stop(svc)
def register_configs(): ''' Register config files with their respective contexts. ''' release = get_os_codename_install_source(config('openstack-origin')) plugin = config('plugin') config_files = resolve_config_files(plugin, release) configs = templating.OSConfigRenderer(templates_dir=TEMPLATES, openstack_release=release) for conf in config_files[plugin]: configs.register(conf, config_files[plugin][conf]['hook_contexts']) return configs
def get_ceilometer_context(): """ Retrieve a map of all current relation data for agent configuration """ cmp_codename = CompareOpenStackReleases( get_os_codename_install_source(config('openstack-origin'))) if cmp_codename >= 'queens': _config_files = QUEENS_CONFIG_FILES else: _config_files = CONFIG_FILES ctxt = {} for hcontext in _config_files[CEILOMETER_CONF]['hook_contexts']: ctxt.update(hcontext()) return ctxt
def enable_memcache(self, release=None): """Determine if memcache should be enabled on the local unit @param release: release of OpenStack currently deployed @returns boolean Whether memcache should be enabled """ if not release: release = os_utils.get_os_codename_install_source( self.config[self.source_config_key]) if release not in os_utils.OPENSTACK_RELEASES: return ValueError("Unkown release {}".format(release)) return (os_utils.OPENSTACK_RELEASES.index(release) >= os_utils.OPENSTACK_RELEASES.index('mitaka'))
def determine_packages(): """Determine packages to install""" packages = BASE_PACKAGES release = get_os_codename_install_source(config('openstack-origin')) # Really should be handled as a dep in the openstack-dashboard package if CompareOpenStackReleases(release) >= 'mitaka': packages.append('python-pymysql') if CompareOpenStackReleases(release) >= 'ocata': packages.append('python-neutron-lbaas-dashboard') if CompareOpenStackReleases(release) >= 'queens': packages.append('python-designate-dashboard') packages.append('python-heat-dashboard') return list(set(packages))
def register_configs(): ''' Register config files with their respective contexts. ''' release = get_os_codename_install_source(config('openstack-origin')) configs = templating.OSConfigRenderer(templates_dir=TEMPLATES, openstack_release=release) plugin = config('plugin') name = networking_name() for conf in CONFIG_FILES[name][plugin]: configs.register(conf, CONFIG_FILES[name][plugin][conf]['hook_contexts']) return configs
def install(): status_set('maintenance', 'Executing pre-install') execd_preinstall() src = config('openstack-origin') if src != 'distro': openstack.configure_installation_source(src) status_set('maintenance', 'Installing apt packages') apt_update(fatal=True) rel = openstack.get_os_codename_install_source(src) pkgs = determine_packages(rel) apt_install(pkgs, fatal=True) apt_install(extra_pkgs, fatal=True) ensure_swift_dir() # configure a directory on webserver for distributing rings. ensure_www_dir_permissions(get_www_dir()) # call the policy overrides handler which will install any policy overrides policyd.maybe_do_policyd_overrides(openstack.os_release('swift-proxy'), 'swift')
def do_openstack_upgrade(configs=None): """Perform an uprade of cinder. Takes care of upgrading packages, rewriting configs + database migration and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) juju_log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update() apt_upgrade(options=dpkg_opts, fatal=True, dist=True) reset_os_release() apt_install(determine_packages(), fatal=True) # NOTE(hopem): must do this after packages have been upgraded so that # we ensure that correct configs are selected for the target release. # See LP 1726527. configs = register_configs() # set CONFIGS to load templates from new release and regenerate config configs.set_release(openstack_release=new_os_rel) configs.write_all() if run_in_apache(): disable_package_apache_site() # Stop/start services and migrate DB if leader [service_stop(s) for s in services()] if is_elected_leader(CLUSTER_RES): migrate_database(upgrade=True) if not is_unit_paused_set(): [service_start(s) for s in services()]
def do_openstack_upgrade(configs): new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update() apt_upgrade(options=dpkg_opts, fatal=True, dist=True) reset_os_release() apt_install(packages=determine_packages(new_os_rel), options=dpkg_opts, fatal=True) remove_old_packages() configs.set_release(openstack_release=new_os_rel) configs.write_all() if not is_paused(): for service in SWIFT_SVCS: service_restart(service)
def render_stuff(*args): """Render the configuration for Nova cell controller when all the interfaces are available. """ hookenv.log("about to call the render_configs with {}".format(args)) with charm.provide_charm_instance() as nova_cell_controller_charm: source_config_key = nova_cell_controller_charm.source_config_key release = os_utils.get_os_codename_install_source( nova_cell_controller_charm.config[source_config_key]) auth_endpoint = ( endpoint_from_flag('identity-credentials.available.auth')) if ((os_utils.OPENSTACK_RELEASES.index(release) < os_utils.OPENSTACK_RELEASES.index('train')) or auth_endpoint): interfaces = args if auth_endpoint: interfaces = (*args, auth_endpoint) nova_cell_controller_charm.render_with_interfaces(interfaces) nova_cell_controller_charm.assess_status() set_flag('config.rendered')
def ha_joined(relation_id=None): ceil_ha_settings = { 'resources': { 'res_ceilometer_agent_central': 'lsb:ceilometer-agent-central'}, 'resource_params': { 'res_ceilometer_agent_central': 'op monitor interval="30s"'}, 'delete_resources': ['res_ceilometer_polling'], } haproxy_enabled = True cmp_codename = CompareOpenStackReleases( get_os_codename_install_source(config('openstack-origin'))) if cmp_codename >= 'ocata': haproxy_enabled = False ceil_ha_settings['delete_resources'].append('res_ceilometer_haproxy') settings = generate_ha_relation_data( 'ceilometer', haproxy_enabled=haproxy_enabled, extra_settings=ceil_ha_settings) relation_set(relation_id=relation_id, **settings)
def do_openstack_upgrade(configs): """ Perform an upgrade. Takes care of upgrading packages, rewriting configs, database migrations and potentially any other post-upgrade actions. """ new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) # NOTE(jamespage): # Write-out new openstack release configuration files prior to upgrading # to avoid having to restart services immediately after upgrade. configs = register_configs(new_os_rel) configs.write_all() dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update(fatal=True) apt_upgrade(options=dpkg_opts, fatal=True, dist=True) # The cached version of os_release will now be invalid as the pkg version # should have changed during the upgrade. reset_os_release() apt_install(get_early_packages(), fatal=True) apt_install(get_packages(), fatal=True) remove_old_packages() # Bug #1802365 neutron-metadata-agent needs restarting after upgrade to # rocky. if CompareOpenStackReleases(os_release('neutron-common')) == 'rocky': log('Restart neutron-metadata-agent for upgrade to rocky', level=DEBUG) service_restart('neutron-metadata-agent')
def do_openstack_upgrade(configs): """ Perform an upgrade. Takes care of upgrading packages, rewriting configs, database migrations and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ cur_os_rel = os_release('neutron-common') new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update(fatal=True) apt_upgrade(options=dpkg_opts, fatal=True, dist=True) reset_os_release() pkgs = determine_packages(new_src) # Sort packages just to make unit tests easier pkgs.sort() apt_install(packages=pkgs, options=dpkg_opts, fatal=True) remove_old_packages() # set CONFIGS to load templates from new release configs.set_release(openstack_release=new_os_rel) # Before kilo it's nova-cloud-controllers job if is_elected_leader(CLUSTER_RES): # Stamping seems broken and unnecessary in liberty (Bug #1536675) if CompareOpenStackReleases(os_release('neutron-common')) < 'liberty': stamp_neutron_database(cur_os_rel) migrate_neutron_database(upgrade=True)
def do_openstack_upgrade(configs): """ Perform an upgrade. Takes care of upgrading packages, rewriting configs, database migrations and potentially any other post-upgrade actions. """ new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update(fatal=True) apt_upgrade(options=dpkg_opts, fatal=True, dist=True) apt_install(get_early_packages(), fatal=True) apt_install(get_packages(), fatal=True) configs.set_release(openstack_release=new_os_rel) configs.write_all()
def restart_map(): """ Determine the correct resource map to be passed to charmhelpers.core.restart_on_change() based on the services configured. :returns: dict: A dictionary mapping config file to lists of services that should be restarted when file changes. """ cmp_codename = CompareOpenStackReleases( get_os_codename_install_source(config('openstack-origin'))) if cmp_codename >= 'queens': _config_files = QUEENS_CONFIG_FILES else: _config_files = CONFIG_FILES _map = {} for f, ctxt in _config_files.items(): svcs = [] for svc in ctxt['services']: svcs.append(svc) if f == CEILOMETER_CONF: for svc in ceilometer_release_services(): svcs.append(svc) if svcs: _map[f] = svcs if (cmp_codename < 'queens' and enable_memcache(source=config('openstack-origin'))): _map[MEMCACHED_CONF] = ['memcached'] if cmp_codename < 'queens' and run_in_apache(): for cfile in _map: svcs = _map[cfile] if 'ceilometer-api' in svcs: svcs.remove('ceilometer-api') if 'apache2' not in svcs: svcs.append('apache2') _map['WSGI_CEILOMETER_API_CONF'] = ['apache2'] return _map
def application_version(self): """Return the current version of the application being deployed by the charm, as indicated by the version_package or version_snap attribute """ if os_utils.snap_install_requested(): if not self.version_snap: self.version_snap = self.snaps[0] version = get_snap_version(self.version_snap, fatal=False) if not version: version = os_utils.get_os_codename_install_source( self.config[self.source_config_key] ) else: if not self.version_package: self.version_package = self.packages[0] version = fetch.get_upstream_version( self.version_package ) if not version: version = os_utils.os_release(self.version_package) return version
def do_openstack_upgrade(configs): """ Perform an upgrade. Takes care of upgrading packages, rewriting configs, database migrations and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update(fatal=True) apt_upgrade(options=dpkg_opts, fatal=True, dist=True) # set CONFIGS to load templates from new release configs.set_release(openstack_release=new_os_rel)
def configure_https(): """Enables SSL API Apache config if appropriate.""" # need to write all to ensure changes to the entire request pipeline # propagate (c-api, haprxy, apache) cmp_codename = CompareOpenStackReleases( get_os_codename_install_source(config('openstack-origin'))) if cmp_codename >= 'queens': return CONFIGS.write_all() if 'https' in CONFIGS.complete_contexts(): cmd = ['a2ensite', 'openstack_https_frontend'] subprocess.check_call(cmd) else: cmd = ['a2dissite', 'openstack_https_frontend'] subprocess.check_call(cmd) # TODO: improve this by checking if local CN certs are available # first then checking reload status (see LP #1433114). if not is_unit_paused_set(): try: subprocess.check_call(['service', 'apache2', 'reload']) except subprocess.CalledProcessError: subprocess.call(['service', 'apache2', 'restart'])
def do_openstack_upgrade(configs): """Perform an upgrade of glance. Takes care of upgrading packages, rewriting configs + database migration and potentially any other post-upgrade actions. :param configs: The charms main OSConfigRenderer object. """ new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update() apt_upgrade(options=dpkg_opts, fatal=True, dist=True) reset_os_release() apt_install(determine_packages(), fatal=True) remove_old_packages() # set CONFIGS to load templates from new release and regenerate config configs.set_release(openstack_release=new_os_rel) configs.write_all() [service_stop(s) for s in services()] if is_elected_leader(CLUSTER_RES): migrate_database() # Don't start services if the unit is supposed to be paused. if not is_unit_paused_set(): [service_start(s) for s in services()]
def get_packages(): '''Return a list of packages for install based on the configured plugin''' plugin = config('plugin') packages = deepcopy(GATEWAY_PKGS[plugin]) source = get_os_codename_install_source(config('openstack-origin')) if plugin == 'ovs': if (source >= 'icehouse' and lsb_release()['DISTRIB_CODENAME'] < 'utopic'): # NOTE(jamespage) neutron-vpn-agent supercedes l3-agent for # icehouse but openswan was removed in utopic. packages.remove('neutron-l3-agent') packages.append('neutron-vpn-agent') packages.append('openswan') if source >= 'kilo': packages.append('python-neutron-fwaas') if source >= 'liberty': # Switch out mysql driver packages.remove('python-mysqldb') packages.append('python-pymysql') # Switch out to actual metering agent package packages.remove('neutron-plugin-metering-agent') packages.append('neutron-metering-agent') if source >= 'mitaka': # Switch out to actual ovs agent package packages.remove('neutron-plugin-openvswitch-agent') packages.append('neutron-openvswitch-agent') packages.extend(determine_l3ha_packages()) if git_install_requested(): packages = list(set(packages)) packages.extend(BASE_GIT_PACKAGES) # don't include packages that will be installed from git for p in GIT_PACKAGE_BLACKLIST: if p in packages: packages.remove(p) return packages
def determine_packages(source=None): # currently all packages match service names packages = [] + BASE_PACKAGES for v in resource_map().values(): packages.extend(v['services']) if manage_plugin(): pkgs = neutron_plugin_attribute(config('neutron-plugin'), 'server_packages', 'neutron') packages.extend(pkgs) release = get_os_codename_install_source(source) if CompareOpenStackReleases(release) >= 'kilo': packages.extend(KILO_PACKAGES) if release == 'kilo' or CompareOpenStackReleases(release) >= 'mitaka': packages.append('python-networking-hyperv') if config('neutron-plugin') == 'vsp': nuage_pkgs = config('nuage-packages').split() packages += nuage_pkgs if git_install_requested(): packages.extend(BASE_GIT_PACKAGES) # don't include packages that will be installed from git packages = list(set(packages)) for p in GIT_PACKAGE_BLACKLIST: if p in packages: packages.remove(p) if CompareOpenStackReleases(release) >= 'kilo': for p in GIT_PACKAGE_BLACKLIST_KILO: packages.remove(p) packages.extend(token_cache_pkgs(release=release)) return list(set(packages))
def additional_install_locations(): ''' Add any required additional install locations of the charm. This will also force an immediate upgrade. ''' calico_source = 'ppa:project-calico/icehouse' if config('calico-origin') != 'default': calico_source = config('calico-origin') else: release = get_os_codename_install_source(config('openstack-origin')) if release in ('icehouse', 'juno', 'kilo'): # Prior to the Liberty release, Calico's Nova and Neutron changes # were not fully upstreamed, so we need to point to a # release-specific PPA that includes Calico-specific Nova and # Neutron packages. calico_source = 'ppa:project-calico/%s' % release else: # From Liberty onwards, we can point to a PPA that does not include # any patched OpenStack packages, and hence is independent of the # OpenStack release. calico_source = 'ppa:project-calico/calico-1.4' # Force UTF-8 to get the BIRD PPA to work. os.environ['LANG'] = 'en_US.UTF-8' add_source(calico_source) add_source('ppa:cz.nic-labs/bird') apt_update() apt_upgrade() # The new version of dnsmasq brings in new dependencies, so we need # to explicitly install it. apt_install(['dnsmasq-base']) return
def determine_packages(source=None): # currently all packages match service names release = get_os_codename_install_source(source) cmp_release = CompareOpenStackReleases(release) packages = deepcopy(BASE_PACKAGES) if cmp_release >= 'rocky': packages.extend(PY3_PACKAGES) for v in resource_map().values(): packages.extend(v['services']) if manage_plugin(): pkgs = neutron_plugin_attribute(config('neutron-plugin'), 'server_packages', 'neutron') packages.extend(pkgs) packages.extend(token_cache_pkgs(release=release)) if cmp_release < 'rocky': if cmp_release >= 'kilo': packages.extend(KILO_PACKAGES) if cmp_release >= 'ocata': packages.append('python-neutron-dynamic-routing') if cmp_release >= 'pike': packages.remove('python-neutron-vpnaas') if release == 'kilo' or cmp_release >= 'mitaka': packages.append('python-networking-hyperv') if config('neutron-plugin') == 'vsp' and cmp_release < 'newton': nuage_pkgs = config('nuage-packages').split() packages.extend(nuage_pkgs) if cmp_release >= 'rocky': packages = [p for p in packages if not p.startswith('python-')] return list(set(packages))
def do_openstack_upgrade(configs): # NOTE(jamespage) horrible hack to make utils forget a cached value import charmhelpers.contrib.openstack.utils as utils utils.os_rel = None new_src = config('openstack-origin') new_os_rel = get_os_codename_install_source(new_src) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) apt_update(fatal=True) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_upgrade(options=dpkg_opts, fatal=True, dist=True) apt_install(determine_packages(), fatal=True) configs.set_release(openstack_release=new_os_rel) configs.write_all() if not is_unit_paused_set(): for s in services(): service_restart(s)
def keystone_joined(relid=None): cmp_codename = CompareOpenStackReleases( get_os_codename_install_source(config('openstack-origin'))) if cmp_codename >= 'queens': log('Skipping endpoint registration for >= Queens', level=DEBUG) return if config('vip') and not is_clustered(): log('Defering registration until clustered', level=DEBUG) return public_url = "{}:{}".format(canonical_url(CONFIGS, PUBLIC), CEILOMETER_PORT) admin_url = "{}:{}".format(canonical_url(CONFIGS, ADMIN), CEILOMETER_PORT) internal_url = "{}:{}".format(canonical_url(CONFIGS, INTERNAL), CEILOMETER_PORT) region = config("region") relation_set(relation_id=relid, service=CEILOMETER_SERVICE, public_url=public_url, admin_url=admin_url, internal_url=internal_url, requested_roles=CEILOMETER_ROLE, region=region)
def get_step_upgrade_source(new_src): ''' Determine if upgrade skips a release and, if so, return source of skipped release. ''' sources = { # target_src: (cur_pocket, step_src) # NOTE: cur_pocket == * means all upgrades to target_src must step # through step_src if step_src is higher than # current release 'cloud:precise-icehouse': ('precise-updates/grizzly', 'cloud:precise-havana'), 'cloud:precise-icehouse/proposed': ('precise-proposed/grizzly', 'cloud:precise-havana/proposed'), 'cloud:trusty-liberty': ('*', 'cloud:trusty-kilo'), } try: cur_pocket, step_src = sources[new_src] current_src = os_release('nova-common') step_src_codename = get_os_codename_install_source(step_src) if cur_pocket == '*' and step_src_codename > current_src: return step_src except KeyError: pass configure_installation_source(new_src) with open('/etc/apt/sources.list.d/cloud-archive.list', 'r') as f: line = f.readline() for target_src, (cur_pocket, step_src) in sources.items(): if target_src != new_src: continue if cur_pocket in line: return step_src return None
def networking_name(): ''' Determine whether neutron or quantum should be used for name ''' if get_os_codename_install_source(config('openstack-origin')) >= 'havana': return NEUTRON else: return QUANTUM
def _do_openstack_upgrade(new_src): enable_policy_rcd() # All upgrades to Liberty are forced to step through Kilo. Liberty does # not have the migrate_flavor_data option (Bug #1511466) available so it # must be done pre-upgrade if (CompareOpenStackReleases(os_release('nova-common')) == 'kilo' and is_leader()): migrate_nova_flavors() # 'nova-manage db online_data_migrations' needs to be run before moving to # the next release for environments upgraded using old charms where this # step was not being executed (LP: #1711209). online_data_migrations_if_needed() new_os_rel = get_os_codename_install_source(new_src) cmp_new_os_rel = CompareOpenStackReleases(new_os_rel) log('Performing OpenStack upgrade to %s.' % (new_os_rel)) configure_installation_source(new_src) dpkg_opts = [ '--option', 'Dpkg::Options::=--force-confnew', '--option', 'Dpkg::Options::=--force-confdef', ] apt_update(fatal=True) apt_upgrade(options=dpkg_opts, fatal=True, dist=True) reset_os_release() apt_install(determine_packages(), fatal=True) disable_policy_rcd() # NOTE(jamespage) upgrade with existing config files as the # havana->icehouse migration enables new service_plugins which # create issues with db upgrades configs = register_configs(release=new_os_rel) configs.write_all() if cmp_new_os_rel >= 'mitaka' and not database_setup(prefix='novaapi'): # NOTE: Defer service restarts and database migrations for now # as nova_api database is not yet created if (relation_ids('cluster') and is_leader()): # NOTE: reset dbsync state so that migration will complete # when the nova_api database is setup. peer_store('dbsync_state', None) return configs if cmp_new_os_rel >= 'ocata' and not database_setup(prefix='novacell0'): # NOTE: Defer service restarts and database migrations for now # as nova_cell0 database is not yet created if (relation_ids('cluster') and is_leader()): # NOTE: reset dbsync state so that migration will complete # when the novacell0 database is setup. peer_store('dbsync_state', None) return configs if is_leader(): status_set('maintenance', 'Running nova db migration') migrate_nova_databases() if not is_unit_paused_set(): [service_start(s) for s in services()] return configs
import neutron_calico_context NOVA_CONF_DIR = "/etc/nova" NEUTRON_CONF_DIR = "/etc/neutron" NEUTRON_CONF = '%s/neutron.conf' % NEUTRON_CONF_DIR NEUTRON_DEFAULT = '/etc/default/neutron-server' ML2_CONF = '%s/plugins/ml2/ml2_conf.ini' % NEUTRON_CONF_DIR FELIX_CONF_DIR = '/etc/calico' FELIX_CONF = FELIX_CONF_DIR + '/felix.cfg' DHCP_CONF = "%s/dhcp_agent.ini" % NEUTRON_CONF_DIR BIRD_CONF_DIR = "/etc/bird" BIRD_CONF = "%s/bird.conf" % BIRD_CONF_DIR BIRD6_CONF = "%s/bird6.conf" % BIRD_CONF_DIR DHCP_AGENT = 'neutron-dhcp-agent' if get_os_codename_install_source(config('openstack-origin')) >= 'liberty': DHCP_AGENT = 'calico-dhcp-agent' BASE_RESOURCE_MAP = OrderedDict([ (NEUTRON_CONF, { 'services': ['calico-felix', DHCP_AGENT, 'nova-api-metadata'], 'contexts': [neutron_calico_context.CalicoPluginContext(), context.AMQPContext()], }), (DHCP_CONF, { 'services': [DHCP_AGENT], 'contexts': [neutron_calico_context.CalicoPluginContext()], }) ]) BIRD_RESOURCE_MAP = {