def update_db_config(): mysql = RelationBase.from_state('database.available') db_type = 'mysql' if mysql else 'sqlite' hookenv.log('Updating database config, using: %s' % db_type) render(source='%s.js.template' % db_type, target=path.join(node_dist_dir(), 'dbconfig.js'), context={ 'db': mysql, 'dist_dir': node_dist_dir(), })
def configure(): dist_dir = node_dist_dir() user = get_user() if is_systemd(): conf_path = SYSTEMD_PATH template_type = 'systemd' else: conf_path = UPSTART_PATH template_type = 'upstart' with maintenance_status('Generating {} configuration'.format( template_type), 'upstart configuration generated'): config_ctx = hookenv.config() config_ctx['working_dir'] = dist_dir config_ctx['user'] = user config_ctx['npm_cache_path'] = get_cache(dist_dir, user) config_ctx['bin_path'] = get_bin_path(dist_dir) config_ctx['enable_failover'] = str( config_ctx['enable_failover']).lower() config_ctx['local_registry_or_host_uri'] = get_local_registry_or_host( uri=True) render(source='npm-offline-registry_{}.j2'.format(template_type), target=conf_path, owner='root', perms=0o744, context=config_ctx) set_state('npm-offline-registry.available')
def check_app_config(): """ Check the Ghost application config and possibly update and restart it. """ cfg_changed = is_state('config.changed') db_changed = ghost.check_db_changed() if cfg_changed or db_changed: hookenv.status_set('maintenance', 'updating configuration') # Update application ghost.update_ghost() # Update general config if cfg_changed: ghost.update_general_config() # Update database config if db_changed: ghost.update_db_config() ghost.restart_ghost() set_state('ghost.running') host.service_restart('nginx') with open(path.join(node_dist_dir(), 'package.json'), 'r') as fp: package_json = json.loads(fp.read()) # Set Ghost application version hookenv.application_version_set(package_json['version']) hookenv.status_set('active', 'ready')
def download_archive(): check_call(['apt-get', 'install', '-qy', 'unzip']) config = hookenv.config() call(['rm', '/tmp/ghost.zip']) cmd = ('wget', '-q', '-O', '/tmp/ghost.zip', 'https://ghost.org/zip/ghost-{}.zip'.format(config['release'])) hookenv.log("Downloading Ghost from: {}".format(' '.join(cmd))) check_call(cmd) if host.file_hash('/tmp/ghost.zip', 'sha256') != config['checksum']: hookenv.status_set( 'blocked', 'downloaded ghost checksums do not match, ' 'possible corrupt file!') sys.exit(0) # delete the app dir contents (but not the dir itself) dist_dir = node_dist_dir() for entry in listdir(dist_dir): if path.isfile(entry): unlink(entry) elif path.isdir(entry): rmtree(entry) cmd = ('unzip', '-uo', '/tmp/ghost.zip', '-d', dist_dir) hookenv.log("Extracting Ghost: {}".format(' '.join(cmd))) check_call(cmd)
def configure_nginx(): with maintenance_status('Generating NGinX configuration', 'NGinX configuration generated'): config_ctx = { 'server_name': get_local_registry_or_host(), 'cache_dir': get_cache(node_dist_dir(), get_user()), } configure_site('npm-offline-rgistry', 'vhost.conf.j2', **config_ctx) hookenv.open_port(hookenv.config('port'))
def update_general_config(): config = hookenv.config() target = path.join(node_dist_dir(), 'config.js') render(source='config.js.template', target=target, context=config) if config.changed('port'): hookenv.log('Changing ports: {} -> {}'.format( config.previous('port'), config['port'] )) if config.previous('port'): hookenv.close_port(config.previous('port')) hookenv.open_port(config['port'])
def install_from_repo(repo, version): pkg = 'npm-offline-registry@{}'.format(version) dist_dir = node_dist_dir() apt_pkg_map = { 'git': 'git-core', 'hg': 'mercurial', 'svn': 'subversion', } repo_types = ('git', 'hg', 'svn') with maintenance_status('Installing {} from {}'.format(pkg, repo), '{} installed'.format(pkg)): repo_type = hookenv.config('repo_type').lower() if repo_type in repo_types: # Ensure we have the required underlying SCM installed firtst fetch.apt_install( fetch.filter_installed_packages([apt_pkg_map[repo_type]])) # We use the excellent peru to pull in builds from SCM repos # but it requires a pregenerated YAML file on disk with NamedTemporaryFile() as f: render(source='npm-offline-registry_peru.yaml.j2', target=f.name, context={ 'url': repo, 'module': repo_type, 'revision': version, }) check_call(['sudo', 'su', '-s', '/bin/sh', '-', get_user(), '-c', ' '.join(('peru', '--file={}'.format(f.name), '--sync-dir={}'.format(dist_dir), 'sync'))]) # If the repo did not bundle the Node.js dependencies for # npm-offline-registry, then let's try to install them with NPM if not exists(join(dist_dir, 'node_modules')): npm('install') service_restart('npm-offline-registry') set_state('npm-offline-registry.installed') else: raise ValueError('Unknown repo_type "{}",not one of {}'.format( repo_type, repo_types))
def install_from_charm_dir(src_path): pkg = 'npm-offline-registry' dist_dir = node_dist_dir() wildcard_src = join(src_path, '*') wildcard_dest = join(dist_dir.rstrip('.'), '*') with maintenance_status('Installing {} from charm directory'.format(pkg), '{} installed'.format(pkg)): check_call(['rm', '-rf', wildcard_dest]) check_call('cp -R {} {}'.format(wildcard_src, dist_dir), shell=True) # If the vendored payload did not bundle the Node.js dependencies for # npm-offline-registry, then let's try to install them with NPM if not exists(join(dist_dir, 'node_modules')): npm('install') service_restart('npm-offline-registry') set_state('npm-offline-registry.installed')
def download_archive(): check_call(['apt-get', 'install', '-qy', 'unzip']) config = hookenv.config() ghost_source = hookenv.resource_get('ghost-stable') ghost_source_checksum = host.file_hash(ghost_source, 'sha256') if config.get('checksum', 0) == ghost_source_checksum: hookenv.log("Checksums match no need to extract source archive.") return kv.set('checksum', ghost_source_checksum) # delete the app dir contents (but not the dir itself) dist_dir = node_dist_dir() for entry in listdir(dist_dir): if path.isfile(entry): unlink(entry) elif path.isdir(entry): rmtree(entry) cmd = ('unzip', '-uo', ghost_source, '-d', dist_dir) hookenv.log("Extracting Ghost: {}".format(' '.join(cmd))) check_call(cmd)
def check_app_config(): """ Check the Ghost application config and possibly update and restart it. """ cfg_changed = is_state('config.changed') db_changed = ghost.check_db_changed() if cfg_changed or db_changed or not is_state('ghost.running'): hookenv.status_set('maintenance', 'updating configuration') try: # Update application ghost.update_ghost() except ghost.ResourceFailure: hookenv.status_set('blocked', 'unable to get ghost-stable resource') return # Update general config if cfg_changed: ghost.update_general_config() # Update database config if db_changed: ghost.update_db_config() ghost.restart_ghost() set_state('ghost.running') host.service_restart('nginx') with open(path.join(node_dist_dir(), 'package.json'), 'r') as fp: package_json = json.loads(fp.read()) # Set Ghost application version hookenv.application_version_set(package_json['version']) hookenv.status_set('active', 'ready')
def start_ghost(): if not ghost_running(): with host.chdir(node_dist_dir()): check_call(['env', 'NODE_ENV=production', 'forever', '-l', '/var/log/ghost.log', '-a', 'start', 'index.js'])
def ghost_running(): with host.chdir(node_dist_dir()): output = check_output(['env', 'NODE_ENV=production', 'forever', 'list']) return 'index.js' in output.decode('utf8')
def restart_ghost(): cmd = 'restart' if ghost_running() else 'start' with host.chdir(node_dist_dir()): check_call(['env', 'NODE_ENV=production', 'forever', '-l', '/var/log/ghost.log', '-a', cmd, 'index.js'])
def stop_ghost(): if ghost_running(): with host.chdir(node_dist_dir()): check_call(['env', 'NODE_ENV=production', 'forever', 'stop', 'index.js'])