def apply_shared(): """Apply docker-compose.shared.yml from data directory""" sh('cp -f {}/docker-compose.shared.yml ./'.format(const.CONFIG_DIR)) shared_cfg = utils.read_shared_compose() usr_cfg = utils.read_compose() usr_cfg['version'] = shared_cfg['version'] utils.write_compose(usr_cfg)
def apply_config(): """Apply system-defined configuration from config dir""" sh('cp -f {}/traefik-cert.yaml ./traefik/'.format(const.CONFIG_DIR)) sh('cp -f {}/docker-compose.shared.yml ./'.format(const.CONFIG_DIR)) shared_cfg = utils.read_shared_compose() usr_cfg = utils.read_compose() usr_cfg['version'] = shared_cfg['version'] utils.write_compose(usr_cfg)
def test_read_shared(): cfg = utils.read_shared_compose( 'brewblox_ctl_lib/data/config/docker-compose.shared.yml') assert 'history' in cfg['services']
def log(add_compose, add_system, upload): """Generate and share log file for bug reports. This command generates a comprehensive report on current system state and logs. When reporting bugs, a termbin blink to the output is often the first thing asked for. For best results, run when the services are still active. Service logs are discarded after `brewblox-ctl down`. Care is taken to prevent accidental leaks of confidential information. Only known variables are read from .env, and the `--no-add-compose` flag allows skipping compose configuration. The latter is useful if the configuration contains passwords or tokens. To review or edit the output, use the `--no-upload` flag. The output will include instructions on how to manually upload the file. \b Steps: - Create ./brewblox.log file. - Append Brewblox .env variables. - Append software version info. - Append service logs. - Append content of docker-compose.yml (optional). - Append content of docker-compose.shared.yml (optional). - Append blocks from Spark services. - Append system diagnostics. - Upload file to termbin.com for shareable link (optional). """ utils.check_config() utils.confirm_mode() sudo = utils.optsudo() # Create log utils.info(f"Log file: {path.abspath('./brewblox.log')}") create() append('date') # Add .env values utils.info('Writing Brewblox .env values...') header('.env') for key in ENV_KEYS: append(f'echo "{key}={utils.getenv(key)}"') # Add version info utils.info('Writing software version info...') header('Versions') append('uname -a') append(f'{const.PY} --version') append(f'{sudo}docker --version') append(f'{sudo}docker-compose --version') # Add active containers utils.info('Writing active containers...') header('Containers') append(f'{sudo}docker-compose ps -a') # Add service logs try: config_names = list(utils.read_compose()['services'].keys()) shared_names = list(utils.read_shared_compose()['services'].keys()) names = [n for n in config_names if n not in shared_names] + shared_names for name in names: utils.info(f'Writing {name} service logs...') header(f'Service: {name}') append(f'{sudo}docker-compose logs --timestamps --no-color --tail 200 {name}') except Exception as ex: append('echo ' + shlex.quote(type(ex).__name__ + ': ' + str(ex))) # Add compose config if add_compose: utils.info('Writing docker-compose configuration...') header('docker-compose.yml') append('cat docker-compose.yml') header('docker-compose.shared.yml') append('cat docker-compose.shared.yml') else: utils.info('Skipping docker-compose configuration...') # Add blocks host_url = utils.host_url() services = utils.list_services('brewblox/brewblox-devcon-spark') for svc in services: utils.info(f'Writing {svc} blocks...') header(f'Blocks: {svc}') append(f'{const.CLI} http post --pretty {host_url}/{svc}/blocks/all/read') # Add system diagnostics if add_system: utils.info('Writing system diagnostics...') header('docker info') append(f'{sudo}docker info') header('disk usage') append('df -hl') header('/proc/net/dev') append('column -t /proc/net/dev') header('/var/log/syslog') append('sudo tail -n 500 /var/log/syslog') header('dmesg') append('dmesg -T') else: utils.info('Skipping system diagnostics...') # Upload if upload: utils.info('Uploading brewblox.log to termbin.com...') sh('cat brewblox.log | nc termbin.com 9999') else: utils.info('Skipping upload. If you want to manually upload the log, run: ' + click.style('cat brewblox.log | nc termbin.com 9999', fg='green'))
def log(add_compose, upload): """Generate and share log file for bug reports. This command generates a comprehensive report on current system state and logs. When reporting bugs, a termbin blink to the output is often the first thing asked for. For best results, run when the services are still active. Service logs are discarded after `brewblox-ctl down`. Care is taken to prevent accidental leaks of confidential information. Only known variables are read from .env, and the `--no-add-compose` flag allows skipping compose configuration. The latter is useful if the configuration contains passwords or tokens. To review or edit the output, use the `--no-upload` flag. The output will include instructions on how to manually upload the file. \b Steps: - Create ./brewblox.log file. - Append Brewblox .env variables. - Append service logs. - Append content of docker-compose.yml (optional). - Append content of docker-compose.shared.yml (optional). - Append blocks from Spark services. - Upload file to termbin.com for shareable link (optional). """ utils.check_config() utils.confirm_mode() sudo = utils.optsudo() # Create log utils.info('Log file: {}'.format(path.abspath('./brewblox.log'))) sh('echo "BREWBLOX DIAGNOSTIC DUMP" > brewblox.log') sh('date >> brewblox.log') # Add .env values utils.info('Writing Brewblox .env values...') sh('echo "==============VARS==============" >> brewblox.log') sh('echo "$(uname -a)" >> brewblox.log') sh('echo "$({}docker --version)" >> brewblox.log'.format(sudo)) sh('echo "$({}docker-compose --version)" >> brewblox.log'.format(sudo)) sh('echo "{}={}" >> brewblox.log'.format(key, utils.getenv(key)) for key in ENV_KEYS) # Add service logs utils.info('Writing service logs...') sh('echo "==============LOGS==============" >> brewblox.log') try: config_names = list(utils.read_compose()['services'].keys()) shared_names = list(utils.read_shared_compose()['services'].keys()) names = [n for n in config_names if n not in shared_names] + shared_names raw_cmd = '{}docker-compose logs --timestamps --no-color --tail 200 {} >> brewblox.log; ' + \ "echo '\\n' >> brewblox.log" sh(raw_cmd.format(sudo, name) for name in names) except Exception as ex: sh('echo {} >> brewblox.log'.format(shlex.quote(type(ex).__name__ + ': ' + str(ex)))) # Add compose config if add_compose: utils.info('Writing docker-compose configuration...') sh('echo "==============COMPOSE==============" >> brewblox.log') sh('cat docker-compose.yml >> brewblox.log') sh('echo "==============SHARED===============" >> brewblox.log') sh('cat docker-compose.shared.yml >> brewblox.log') else: utils.info('Skipping docker-compose configuration...') # Add blocks utils.info('Writing Spark blocks...') sh('echo "==============BLOCKS==============" >> brewblox.log') host_url = utils.host_url() services = utils.list_services('brewblox/brewblox-devcon-spark') query = '{} http get --pretty {}/{}/objects >> brewblox.log || echo "{} not found" >> brewblox.log' sh(query.format(const.CLI, host_url, svc, svc) for svc in services) # Upload if upload: utils.info('Uploading brewblox.log to termbin.com...') sh('cat brewblox.log | nc termbin.com 9999') else: utils.info('Skipping upload. If you want to manually upload the log, run: ' + click.style('cat brewblox.log | nc termbin.com 9999', fg='green'))