def configure_sources(): """Add user specified package sources from the service configuration. See charmhelpers.fetch.configure_sources for details. """ hookenv.log('Initializing Apt Layer') config = hookenv.config() # We don't have enums, so we need to validate this ourselves. package_status = config.get('package_status') if package_status not in ('hold', 'install'): charms.apt.status_set( 'blocked', 'Unknown package_status {}' ''.format(package_status)) # Die before further hooks are run. This isn't very nice, but # there is no other way to inform the operator that they have # invalid configuration. raise SystemExit(0) sources = config.get('install_sources') keys = config.get('install_keys') if reactive.helpers.data_changed('apt.configure_sources', (sources, keys)): fetch.configure_sources(update=False, sources_var='install_sources', keys_var='install_keys') reactive.set_state('apt.needs_update') extra_packages = sorted(config.get('extra_packages', '').split()) if extra_packages: queue_install(extra_packages)
def install_charmsvg(): apt.queue_install([ 'python-bottle', 'python-yaml', 'python-networkx', 'python-requests', ])
def install_puppet(): """ Installs latest Puppet & hiera packages Emits: puppet.available: Emitted once the runtime has been installed """ # install required puppet modules # BIGTOP-2003. A workaround to install newer hiera to get rid of hiera 1.3.0 bug. # TODO once Ubuntu trusty fixes version of hiera package, this could be replaced by # adding packages: ['puppet'] in layer.yaml options:basic try: # Ideally the sources should be taken from config.yaml but I can not make it work wget = 'wget -O /tmp/puppetlabs-release-trusty.deb https://apt.puppetlabs.com/puppetlabs-release-trusty.deb' dpkg = 'dpkg -i /tmp/puppetlabs-release-trusty.deb' apt_update = 'apt-get update' subprocess.call(wget.split()) subprocess.call(dpkg.split()) subprocess.call(apt_update.split()) except CalledProcessError: pass # All modules are set kv.set('puppet.url', config.get('install_sources')) kv.set('puppet.key', config.get('install_keys')) apt.queue_install(['puppet']) apt.install_queued()
def configure_sources(): """Add user specified package sources from the service configuration. See charmhelpers.fetch.configure_sources for details. """ hookenv.log('Initializing Apt Layer') config = hookenv.config() # We don't have enums, so we need to validate this ourselves. package_status = config.get('package_status') if package_status not in ('hold', 'install'): charms.apt.status_set('blocked', 'Unknown package_status {}' ''.format(package_status)) # Die before further hooks are run. This isn't very nice, but # there is no other way to inform the operator that they have # invalid configuration. raise SystemExit(0) sources = config.get('install_sources') keys = config.get('install_keys') if reactive.helpers.data_changed('apt.configure_sources', (sources, keys)): fetch.configure_sources(update=False, sources_var='install_sources', keys_var='install_keys') reactive.set_state('apt.needs_update') extra_packages = sorted(config.get('extra_packages', '').split()) if extra_packages: queue_install(extra_packages)
def install_custom_nodejs(): deb_path = join(dirname(dirname(__file__)), 'files', 'nodejs*.deb') paths = glob(deb_path) if paths: deb_path = paths[0] deb_pkg_version_output = check_output(['dpkg-deb', '-I', deb_path]) deb_pkg_version = search('Version: (.*)', deb_pkg_version_output.decode('ascii')) installed_version_output = check_output('dpkg -s nodejs || exit 0', shell=True) installed = search('Version: (.*)', installed_version_output.decode('ascii')) installed_version = installed.groups()[0] if installed else '' if installed_version.strip() != deb_pkg_version.groups()[0].strip(): hookenv.log('Installed NodeJS {} != {}, installing from custom deb' .format(installed_version, deb_pkg_version)) hookenv.status_set('maintenance', 'Installing {}'.format(deb_path)) check_call( ['apt', 'install', '-y', '--allow-downgrades', deb_path]) hookenv.status_set('active', 'Custom NodeJs package installed') else: # Although it would be nice to let the apt layer handle all this for # us, we can't due to the conditional nature of installing these # packages *only* if the .deb file isn't used queue_install(['npm', 'nodejs', 'nodejs-legacy'])
def install_packages(rel=None): hookenv.status_set('maintenance', 'Installing software') hookenv.log("Installing designate dashboard plugin") apt.queue_install(['python-designate-dashboard']) apt.install_queued() reactive.set_state('python-designate-dashboard.installed') rel.set_remote('plugin-ready') hookenv.status_set('active', 'Plugin Installed')
def check_version_and_install(): series = lsb_release()['DISTRIB_CODENAME'] if not series >= 'xenial': log('letsencrypt not supported on series >= %s' % (series)) status_set('blocked', "Unsupported series < Xenial") return else: apt.queue_install(['letsencrypt']) apt.install_queued()
def install_puppet_apt_pkg(self): '''Install puppet pkg/enable srvc ''' hookenv.status_set('maintenance', 'Installing %s' % self.puppet_apt_pkg) self.install_puppet_apt_src() # Queue the installation of appropriate puppet pkgs apt.queue_install(self.puppet_apt_pkg) apt.install_queued()
def setup_debconf(): # Tell debconf where to find answers fo the openattic questions charm_debconf = os.path.join(os.getenv('CHARM_DIR'), 'files', 'openattic-answers') check_output(['debconf-set-selections', charm_debconf]) # Install openattic in noninteractive mode apt.queue_install([ "openattic", "openattic-module-ceph", "linux-image-extra-{}".format(os.uname()[2]) ])
def install_elixir(): """ Installs elixir Emits: elixir.available: Emitted once the runtime has been installed """ kv.set('elixir.url', config.get('install_sources')) apt.queue_install(['elixir'])
def install_nodejs(): """ Installs defined node runtime Emits: nodejs.available: Emitted once the runtime has been installed """ kv.set('nodejs.url', config.get('install_sources')) kv.set('nodejs.key', config.get('install_keys')) apt.queue_install(['nodejs', 'npm', 'nodejs-legacy'])
def install_nodejs(): """ Installs defined node runtime Emits: nodejs.available: Emitted once the runtime has been installed """ kv.set("nodejs.url", config.get("install_sources")) kv.set("nodejs.key", config.get("install_keys")) apt.queue_install(["nodejs"])
def install_vaultlocker(): '''Install vaultlocker. On bionic and higher, vaultlocker is available in the default system sources. For xenial, we need to add the queens cloud archive. ''' dist = host.lsb_release() dist_series = dist['DISTRIB_CODENAME'].lower() if dist_series == 'xenial': apt.add_source('cloud:queens') apt.update() apt.queue_install(['vaultlocker'])
def check_version_and_install(): series = lsb_release()['DISTRIB_RELEASE'] if not series >= '16.04': log('letsencrypt not supported on series >= %s' % (series)) status_set('blocked', "Unsupported series < Xenial") return else: apt.queue_install(['letsencrypt']) apt.install_queued() # open ports during installation to prevent a scenario where # we need to wait for the update-status hook to request # certificates because Juju hasn't opened the ports yet and # no other hook is queued to run. open_port(80) open_port(443)
def attach(): # This happens either with a non existing nextcloud installation # -OR- # After a nextcloud installation has been performed # and the operator has decided to attach storage post installation. # in which case the /var/www/nextcloud directory is present. storageids = storage_list("data") if not storageids: status_set("blocked", "Cannot locate attached storage") return storageid = storageids[0] mount = storage_get("location", storageid) if not mount: hookenv.status_set( "blocked", "Cannot locate attached storage mount directory for data") return unitdata.kv().set(data_mount_key, mount) log("data storage attached at {}".format(mount)) # In case storage is attached post deploy, we might have accumulated # some data so we need to make sure the attached storage meets our requirements on available disk. if os.path.exists('/var/www/nextcloud'): required_space = shutil.disk_usage('/var/www/nextcloud/data').used free_space = shutil.disk_usage(mount).free if required_space > free_space: hookenv.status_set("blocked", "attached storage to small.") return apt.queue_install(["rsync"]) reactive.set_state("nextcloud.storage.data.attached")
def handle_storage_relation(dead_chicken): # Remove this once Juju storage is no longer experiemental and # everyone has had a chance to upgrade. data_rels = context.Relations()["data"] if len(data_rels) > 1: helpers.status_set("blocked", "Too many relations to the storage subordinate") return elif data_rels: relid, rel = list(data_rels.items())[0] rel.local["mountpoint"] = external_volume_mount if needs_remount(): reactive.set_state("postgresql.storage.needs_remount") apt.queue_install(["rsync"]) # Migrate any data when we can restart. coordinator.acquire("restart")
def handle_storage_relation(dead_chicken): # Remove this once Juju storage is no longer experiemental and # everyone has had a chance to upgrade. data_rels = context.Relations()['data'] if len(data_rels) > 1: helpers.status_set('blocked', 'Too many relations to the storage subordinate') return elif data_rels: relid, rel = list(data_rels.items())[0] rel.local['mountpoint'] = external_volume_mount if needs_remount(): reactive.set_state('postgresql.storage.needs_remount') apt.queue_install(['rsync']) # Migrate any data when we can restart. coordinator.acquire('restart')
def attach(): mount = storage_get()['location'] unitdata.kv().set(data_mount_key, mount) unitdata.kv().set(data_path_key, os.path.join(mount, 'var/lib/docker')) log('Docker registry storage attached: {}'.format(mount)) if os.path.exists('/var/lib/docker'): required_space = shutil.disk_usage('/var/lib/docker').used free_space = shutil.disk_usage(mount).free if required_space > free_space: status_set('blocked', 'Not enough free storage space.') return apt.queue_install(['rsync']) set_state('docker-registry.storage.docker-registry.attached')
def install_puppet(): """Install Puppet packages. If the user has configured repos, use them. If not (and we're on trusty), use the puppetlabs repo to avoid buggy archive packages. If neither of these, install packages using the default system repos. """ distname, version, series = platform.linux_distribution() if series == 'trusty' and is_state('config.default.install_sources'): # BIGTOP-2003. A workaround to install newer hiera to get rid of # hiera 1.3.0 bug. apt.add_source('deb http://apt.puppetlabs.com trusty main dependencies', '4BD6EC30') apt.update() apt.queue_install(['puppet']) apt.install_queued()
def install_packages(): pin_dse() apt.queue_install(cassandra.get_deb_packages()) if reactive.is_flag_set('apt.queued_installs'): with helpers.autostart_disabled(): if not apt.install_queued(): return # apt layer already left us in a blocked state if cassandra.get_edition() == 'apache-snap': snap.install('cassandra') elif cassandra.get_jre() == 'oracle': tb = fetch_oracle_jre() if tb is None: return install_oracle_jre_tarball(tb) elif cassandra.get_jre() == 'openjdk': subprocess.check_call(['update-java-alternatives', '--jre-headless', '--set', 'java-1.8.0-openjdk-amd64']) reactive.set_flag('cassandra.installed')
def attach(): mount = hookenv.storage_get()['location'] pgdata = os.path.join(mount, postgresql.version(), 'main') unitdata.kv().set(pgdata_mount_key, mount) unitdata.kv().set(pgdata_path_key, pgdata) hookenv.log('PGDATA storage attached at {}'.format(mount)) # Never happens with Juju 2.0 as we can't reuse an old mount. This # check is here for the future. existingdb = os.path.exists(pgdata) required_space = shutil.disk_usage(postgresql.data_dir()).used free_space = shutil.disk_usage(mount).free if required_space > free_space and not existingdb: hookenv.status_set('blocked', 'Not enough free space in pgdata storage') else: apt.queue_install(['rsync']) coordinator.acquire('restart') reactive.set_state('postgresql.storage.pgdata.attached')
def install_limeds(): apt.add_source('ppa:cwchien/gradle') apt.queue_install(['git', 'gradle-2.12']) apt.update() apt.install_queued() service_name = hookenv.local_unit().split('/')[0] subprocess.check_call(['hostnamectl', 'set-hostname', '']) # Make hostname resolvable with open('/etc/hosts', 'a') as hosts_file: hosts_file.write('127.0.0.1 {}\n'.format(service_name)) # Add bitbucket host key so git ssh doesn't request to confirm host key with open('/root/.ssh/known_hosts', 'a+') as known_hosts_file: known_hosts_file.write(KNOWN_HOSTS) if os.path.isdir('/opt/limeds'): shutil.rmtree('/opt/limeds') keypath = '{}/files/id_rsa'.format(hookenv.charm_dir()) # Fix bug where permissions of charm files are changed subprocess.check_call(['chmod', 'go-r', keypath]) repo = '[email protected]:ibcndevs/cot-demo.git' subprocess.check_call([ # use ssh-agent to use supplied privkey for git ssh connection 'ssh-agent', 'bash', '-c', # remote 'upstream' will point to supplied given repo 'ssh-add {}; git clone {} -o upstream /opt/limeds'.format( keypath, repo) ]) subprocess.check_call(['gradle', 'jar', 'export'], cwd='/opt/limeds') templating.render( source='upstart.conf', target='/etc/init/limeds.conf', context={ 'description': 'limeds', 'command': 'cd /opt/limeds/run/ \njava -jar -Dgosh.args=--nointeractive generated/distributions/executable/cot-demo.jar', })
def install_limeds(): apt.add_source('ppa:cwchien/gradle') apt.queue_install(['git', 'gradle-2.12']) apt.update() apt.install_queued() service_name = hookenv.local_unit().split('/')[0] subprocess.check_call(['hostnamectl', 'set-hostname', '']) # Make hostname resolvable with open('/etc/hosts', 'a') as hosts_file: hosts_file.write('127.0.0.1 {}\n'.format(service_name)) # Add bitbucket host key so git ssh doesn't request to confirm host key with open('/root/.ssh/known_hosts', 'a+') as known_hosts_file: known_hosts_file.write(KNOWN_HOSTS) if os.path.isdir('/opt/limeds'): shutil.rmtree('/opt/limeds') keypath = '{}/files/id_rsa'.format(hookenv.charm_dir()) # Fix bug where permissions of charm files are changed subprocess.check_call(['chmod', 'go-r', keypath]) repo = '[email protected]:ibcndevs/cot-demo.git' subprocess.check_call([ # use ssh-agent to use supplied privkey for git ssh connection 'ssh-agent', 'bash', '-c', # remote 'upstream' will point to supplied given repo 'ssh-add {}; git clone {} -o upstream /opt/limeds'.format(keypath, repo) ]) subprocess.check_call([ 'gradle', 'jar', 'export' ], cwd='/opt/limeds') templating.render( source='upstart.conf', target='/etc/init/limeds.conf', context={ 'description': 'limeds', 'command': 'cd /opt/limeds/run/ \njava -jar -Dgosh.args=-nointeractive generated/distributions/executable/cot-demo.jar', } )
def install_rest2kafka(): apt.add_source('ppa:cwchien/gradle') apt.queue_install(['python-pip', 'python-dev']) apt.update() apt.install_queued() subprocess.check_call(['pip2', 'install', 'pykafka', 'flask']) # Make hostname resolvable service_name = hookenv.local_unit().split('/')[0] with open('/etc/hosts', 'a') as hosts_file: hosts_file.write('127.0.0.1 {}\n'.format(service_name)) mergecopytree(charm_dir() + '/files/rest2kafka', "/opt/rest2kafka") chownr('/opt/rest2kafka', 'ubuntu', 'ubuntu') templating.render( source='upstart.conf', target='/etc/init/rest2kafka.conf', owner='ubuntu', group='ubuntu', context={ 'user': '******', 'description': 'rest2kafka', 'command': '/opt/rest2kafka/rest2kafka.py', 'debug': 'False', } )
def install_postgresql_packages(): apt.queue_install(postgresql.packages()) # Deprecated option. The apt layer handles 'extra_packages' with # an underscore. apt.queue_install(set(hookenv.config()["extra-packages"].split())) reactive.set_state("postgresql.packages.queued")
def install_postgresql_packages(): apt.queue_install(postgresql.packages())
def apt_install(): status_set('maintenance', 'Queuing dependencies for install') apt.queue_install(['elasticsearch'])
def install_zfsutils(): hookenv.status_set('maintenance', 'installing zfsutils-linux') apt.queue_install(['zfsutils-linux'])
def install_haproxy(): """Install haproxy and any other required software for this layer.""" queue_install(['haproxy'])
def install_cephfs(): queue_install(['ceph-mds'])
def install_layer_samba(): sys.path.append(os.path.realpath('..')) # Do your setup here. # # If your charm has other dependencies before it can install, # add those as @when() clauses above., or as additional @when() # decorated handlers below # # See the following for information about reactive charms: # # * https://jujucharms.com/docs/devel/developer-getting-started # * https://github.com/juju-solutions/layer-basic#overview # config = hookenv.config() password = config['password'] server_name = config['server_name'] online = config['online'] hookenv.status_set('maintenance', 'Updating apt') apt.update() hookenv.status_set('maintenance', 'Installing packages') apt.queue_install(['samba']) apt.install_queued() #os.system('git clone https://github.com/bdrung/ionit.git') #os.system('python3 ionit/setup.py install') hookenv.status_set('maintenance', 'Configuring') host.add_group('juju-samba-ubuntu') host.adduser('ubuntu', password) host.add_user_to_group('ubuntu', 'juju-samba-ubuntu') cmd = ("sudo echo -e \"" + password + "\n" + password + "\" | smbpasswd -s -a ubuntu") os.system(cmd) if not os.path.exists('/opt/samba/share'): os.makedirs('/opt/samba/share') host.chownr('/opt/samba/share', 'ubuntu', 'juju-samba-ubuntu', True, True) if not os.path.exists('/etc/samba/smb.conf'): os.makedirs('/etc/samba') shutil.copy('opt/smb.conf', '/etc/samba/smb.conf') render(source='smb', target='/etc/samba/smb.conf', context={ "cfg": config, }, owner='root', perms=0o740) restartSamba() set_flag('layer-samba.installed') if (not online): stopSamba() hookenv.status_set('active', 'Stopped') hookenv.status_set('active', 'Started')
def install_nodejs(): kv.set('nodejs.url', config.get('install_sources')) kv.set('nodejs.key', config.get('install_keys')) apt.queue_install(['nodejs'])
def install(): apt.queue_install(php.package())
def install(): # WAL-E is currently only available from a PPA, ppa:stub/pgcharm. # This charm and this PPA are maintained by the same person. # Ensure that this PPA or another containing the 'wal-e' package # is included as an install_source. apt.queue_install(['daemontools', 'wal-e'])
def install_packages(packages): hookenv.status_set('maintenance', 'Installing software') hookenv.log("Installing packages") apt.queue_install(packages) apt.install_queued()
def install_extra_packages(): '''Install packages declared by the deprecated 'extra-packages' config. The apt layer handles 'extra_packages', with the underscore. ''' apt.queue_install(set(hookenv.config()['extra-packages'].split()))
def install_ceph_base(): add_source(config('source'), key=config('key')) queue_install(PACKAGES)