def backup(): """Creates a backup of all logs under a single archive and saves it on the manager machine. """ logger = get_logger() archive_path_on_manager = _archive_logs() logger.info('Backing up manager logs to /var/log/{0}'.format( os.path.basename(archive_path_on_manager))) ssh.run_command_on_manager('mv {0} {1}'.format( archive_path_on_manager, '/var/log/'), use_sudo=True)
def download(output): """Retrieves an archive containing manager logs to `output` on the local machine. """ logger = get_logger() archive_path_on_manager = _archive_logs() logger.info('Downloading archive to: {0}'.format(output)) ssh.get_file_from_manager(archive_path_on_manager, output) logger.info('Removing archive from manager...') ssh.run_command_on_manager( 'rm {0}'.format(archive_path_on_manager), use_sudo=True)
def _verify_tmux_exists_on_manager(host_string): try: run_command_on_manager('which tmux', host_string=host_string) except: raise CloudifyCliError( 'tmux executable not found on manager {0}.\n' 'Please verify that tmux is installed and in PATH before ' 'attempting to use shared SSH sessions.\n' 'You can run `cfy ssh -c "sudo yum install tmux -y"` to try and ' 'install tmux on the manager.'.format( host_string.split('@')[1]))
def _get_all_sessions(logger, host_string): logger.info('Retrieving list of existing sessions...') try: # TODO: apply tmux formatting output = run_command_on_manager('tmux list-sessions', host_string=host_string) except: return None return output
def purge(force, backup_first): """Truncates all logs files under /var/log/cloudify. This aims to allow a user to take extreme measures to clean up data from the manager. For instance, when the disk is full due to some bug causing the logs to bloat up. The `--force` flag must be provided to provide a safety measure. """ logger = get_logger() if backup_first: backup() logger.info('Purging manager logs...') # well, we could've just `find /var/log/cloudify -name "*" -type f -delete` # thing is, it will delete all files and nothing will be written into them # until the relevant service is restarted. ssh.run_command_on_manager( 'for f in $(sudo find /var/log/cloudify -name "*" -type f); ' 'do sudo truncate -s 0 $f; ' 'done', use_sudo=True)
def _archive_logs(): """Creates an archive of all logs found under /var/log/cloudify plus journalctl. """ logger = get_logger() archive_filename = 'cloudify-manager-logs_{0}_{1}.tar.gz'.format( ssh.get_manager_date(), utils.get_management_server_ip()) archive_path = os.path.join('/tmp', archive_filename) journalctl_destination_path = '/var/log/cloudify/journalctl.log' ssh.run_command_on_manager( 'journalctl > /tmp/jctl && ' 'mv /tmp/jctl {0}'.format(journalctl_destination_path), use_sudo=True) logger.info('Creating logs archive in manager: {0}'.format(archive_path)) # We skip checking if the tar executable can be found on the machine # knowingly. We don't want to run another ssh command just to verify # something that will almost never happen. ssh.run_command_on_manager('tar -czf {0} -C /var/log cloudify'.format( archive_path), use_sudo=True) ssh.run_command_on_manager( 'rm {0}'.format(journalctl_destination_path), use_sudo=True) return archive_path
def _send_keys(logger, command, sid, host_string): logger.debug('Sending "{0}" to session...'.format(command)) run_command_on_manager( 'tmux send-keys -t {0} \'{1}\' C-m'.format(sid, command), host_string=host_string)
def ssh(ssh_command, host_session, sid, list_sessions): """Connects to a running manager via SSH. `host_session` starts a tmux session (e.g. tmux new -s "ssh_session_vi120m") after which a command for a client is printed in the tmux session for the host to send to the client (i.e. cfy ssh --sid ssh_session_vi120m). When starting a new session, the host creates an alias for "exit" so that when a client connects and exits, it will run "tmux detach" instead and not kill the session. When the host exits the tmux session, a command will be executed to kill the session. Passing an `ssh_command` will simply execute it on the manager while omitting a command will connect to an interactive shell. """ _validate_env(ssh_command, host_session, sid, list_sessions) host_string = utils.build_manager_host_string() if host_session or sid or list_sessions: _verify_tmux_exists_on_manager(host_string) logger = get_logger() logger.info('Connecting to {0}...'.format(host_string)) if host_session: sid = 'ssh_session_' + utils.generate_random_string() logger.info('Creating session {0}...'.format(sid)) try: run_command_on_manager('tmux new -d -A -s {0}'.format(sid), host_string=host_string) logger.info('Preparing environment...') _send_keys(logger, 'alias exit="tmux detach"; clear', sid, host_string=host_string) _send_keys(logger, '#Clients should run cfy ssh --sid {0} ' 'to join the session.'.format(sid), sid, host_string=host_string) _join_session(logger, sid, host_string) except Exception as ex: logger.error('Failed to create session ({0})'.format(ex)) logger.info('Killing session {0}...'.format(sid)) try: run_command_on_manager( 'tmux kill-session -t {0}'.format(sid), host_string=host_string) except Exception as ex: logger.warn('Failed to kill session ({0})'.format(ex)) elif sid: _join_session(logger, sid, host_string) elif list_sessions: sessions = _get_all_sessions(logger, host_string) if sessions: logger.info('Available Sessions are:\n{0}'.format(sessions.stdout)) else: logger.info('No sessions are available') else: if ssh_command: logger.info('Executing command {0}...'.format(ssh_command)) run_command_on_manager( ssh_command, host_string=host_string, force_output=True) else: _open_interactive_shell(host_string=host_string)