def reboot(delay=10, interval=1, reboot_timeout=300): """ Reboot the server and wait for reconnection. + delay: number of seconds to wait before attempting reconnect + interval: interval (s) between reconnect attempts + reboot_timeout: total time before giving up reconnecting **Example:** .. code:: python server.reboot( name="Reboot the server and wait to reconnect", delay=60, reboot_timeout=600, ) """ # Remove this now, before we reboot the server - if the reboot fails (expected or # not) we'll error if we don't clean this up now. Will simply be re-uploaded if # needed later. def remove_any_askpass_file(state, host): remove_any_sudo_askpass_file(host) yield FunctionCommand(remove_any_askpass_file, (), {}) yield StringCommand("reboot", success_exit_codes=[0, -1]) # -1 being error/disconnected def wait_and_reconnect(state, host): # pragma: no cover sleep(delay) max_retries = round(reboot_timeout / interval) host.connection = None # remove the connection object retries = 0 while True: host.connect(show_errors=False) if host.connection: break if retries > max_retries: raise Exception( ("Server did not reboot in time (reboot_timeout={0}s)" ).format(reboot_timeout), ) sleep(interval) retries += 1 yield FunctionCommand(wait_and_reconnect, (), {})
def call(function, *args, **kwargs): ''' Execute a Python function within a deploy. + function: the function to execute + args: additional arguments to pass to the function + kwargs: additional keyword arguments to pass to the function Callback functions args passed the state, host, and any args/kwargs passed into the operation directly, eg: .. code:: python def my_callback(state, host, hello=None): command = 'echo hello' if hello: command = command + ' ' + hello status, stdout, stderr = host.run_shell_command(state, command=command, sudo=SUDO) assert status is True # ensure the command executed OK if 'hello ' not in str(stdout): raise Exception('`{}` problem with callback stdout:{} stderr:{}'.format( command, stdout, stderr)) python.call( name='Run my_callback function', function=my_callback, hello='world', ) ''' kwargs.pop('state', None) kwargs.pop('host', None) yield FunctionCommand(function, args, kwargs)
def raise_exception(exception, *args, **kwargs): def raise_exc(*args, **kwargs): # pragma: no cover raise exception(*args, **kwargs) kwargs.pop('state', None) kwargs.pop('host', None) yield FunctionCommand(raise_exc, args, kwargs)
def reboot(delay=10, interval=1, reboot_timeout=300, state=None, host=None): ''' Reboot the server and wait for reconnection. + delay: number of seconds to wait before attempting reconnect + interval: interval (s) between reconnect attempts + reboot_timeout: total time before giving up reconnecting Note: Probably want sudo enabled. Example: .. code:: python server.reboot( name='Reboot the server and wait to reconnect', delay=5, timeout=30, ) ''' logger.warning('The server.reboot operation is in beta!') yield StringCommand('reboot', success_exit_codes=[-1]) # -1 being error/disconnected def wait_and_reconnect(state, host): # pragma: no cover sleep(delay) max_retries = round(reboot_timeout / interval) host.connection = None # remove the connection object retries = 0 while True: host.connect(state, show_errors=False) if host.connection: break if retries > max_retries: raise Exception( ('Server did not reboot in time (reboot_timeout={0}s)' ).format(reboot_timeout)) sleep(interval) retries += 1 yield FunctionCommand(wait_and_reconnect, (), {})
def call(function, *args, **kwargs): """ Execute a Python function within a deploy. + function: the function to execute + args: additional arguments to pass to the function + kwargs: additional keyword arguments to pass to the function Callback functions args passed the state, host, and any args/kwargs passed into the operation directly, eg: .. code:: python def my_callback(state, host, hello=None): command = 'echo hello' if hello: command = command + ' ' + hello status, stdout, stderr = host.run_shell_command(command=command, sudo=SUDO) assert status is True # ensure the command executed OK if 'hello ' not in '\\n'.join(stdout): # stdout/stderr is a *list* of lines raise Exception( f'`{command}` problem with callback stdout:{stdout} stderr:{stderr}', ) python.call( name="Run my_callback function", function=my_callback, hello="world", ) """ argspec = getfullargspec(function) if "state" in argspec.args and "host" in argspec.args: logger.warning( "Callback functions used in `python.call` operations no " f"longer take `state` and `host` arguments: {get_call_location(frame_offset=3)}", ) kwargs.pop("state", None) kwargs.pop("host", None) yield FunctionCommand(function, args, kwargs)
def test_function_command_repr(self): def some_function(): pass cmd = FunctionCommand(some_function, (), {}) assert repr(cmd) == "FunctionCommand(some_function, (), {})"