Esempio n. 1
0
    def test_config_command_override(self, fake_read):
        """``config`` The 'get_config' function can override the defined command"""
        config_obj, _, _ = config.get_config(shell_command='some command')

        expected = 'some command'
        actual = config_obj['config']['command']

        self.assertEqual(actual, expected)
Esempio n. 2
0
    def test_return_type(self, fake_read):
        """``config`` The 'get_config' function returns a tuple"""
        fake_read.return_value = False

        output = config.get_config()
        expected = (config._default(), True, '/etc/container_shell/config.ini')

        self.assertEqual(output, expected)
Esempio n. 3
0
    def test_using_defaults(self, fake_read):
        """
        ``config`` The 'get_config' function informs the caller if default
        values are being used.
        """
        fake_read.return_value = True

        _, using_default_values, _ = config.get_config()

        self.assertFalse(using_default_values)
Esempio n. 4
0
    def test_config_location(self, fake_read):
        """
        ``config`` The 'get_config' function informst the caller of the location
        for the configuration file.
        """
        fake_read.return_value = True

        _, _, config_location = config.get_config()
        expected = config.CONFIG_LOCATION

        self.assertEqual(config_location, expected)
Esempio n. 5
0
def main(cli_args=sys.argv[1:]):
    """Entry point logic"""
    user_info = getpwnam(getuser())
    username = user_info.pw_name
    user_uid = user_info.pw_uid
    user_gid = user_info.pw_gid
    args = parse_cli(cli_args)

    config, using_defaults, location = get_config(shell_command=args.command)
    docker_client = docker.from_env(
        timeout=config['config'].getint('docker_timeout'))
    logger = utils.get_logger(name=__name__,
                              location=config['logging'].get('location'),
                              max_size=config['logging'].getint('max_size'),
                              max_count=config['logging'].getint('max_count'),
                              level=config['logging'].get('level').upper())
    logger.debug("CLI Args: %s", args)
    if using_defaults:
        logger.debug('No defined config file at %s. Using default values',
                     location)
    else:
        logger.debug('Custom config:\n%s', config)

    if utils.skip_container(username, config['config']['skip_users']):
        logger.info('User %s accessing host environment', username)
        original_cmd = os.getenv('SSH_ORIGINAL_COMMAND', args.command)
        if not original_cmd:
            original_cmd = os.getenv('SHELL')
        proc = subprocess.Popen(original_cmd.split(),
                                shell=sys.stdout.isatty())
        proc.communicate()
        sys.exit(proc.returncode)

    image = config['config'].get('image')
    if not config['config'].get('auto_refresh').lower() == 'false':
        try:
            docker_client.images.pull(image)
        except docker.errors.DockerException as doh:
            logger.exception(doh)
            utils.printerr('Unable to update login environment')
            sys.exit(1)

    try:
        create_kwargs = dockage.build_args(config, username, user_uid,
                                           user_gid, logger)
        logger.debug('Create kwargs:\n%s', create_kwargs)
        container, standalone = _get_container(docker_client, username, config,
                                               **create_kwargs)
    except docker.errors.DockerException as doh:
        logger.exception(doh)
        utils.printerr("Failed to create login environment")
        sys.exit(1)
    else:
        cleanup = functools.partial(kill_container, container,
                                    config['config']['term_signal'],
                                    config['config']['persist'],
                                    config['config']['persist_egrep'],
                                    config['binaries']['ps'], logger)
        atexit.register(cleanup)
    try:
        if standalone:
            logger.debug("Connecting to standalone container")
            # When OpenSSH detects that a client has disconnected, it'll send
            # SIGHUP to the process ran when that client connected.
            # If we don't handle this signal, then users who click the little "x"
            # on their SSH application (instead of pressing "CTL D" or typing "exit")
            # will cause ContainerShell to leak containers. In other words, the
            # SSH session will be gone, but the container will remain.
            set_container_signal_handlers(container, config, logger)
            dockerpty.start(docker_client.api, container.id)
        else:
            logger.debug("Connecting to shared container")
            exec_id = dockage.create_exec(docker_client, container, config,
                                          username, logger)
            set_exec_signal_handlers(docker_client, exec_id, logger)
            exec_op = dockerpty.pty.ExecOperation(docker_client.api, exec_id,
                                                  logger)
            dockerpty.pty.PseudoTerminal(docker_client.api, exec_op).start()
    except Exception as doh:  #pylint: disable=W0703
        logger.exception(doh)
        utils.printerr("Failed to connect to PTY")
        sys.exit(1)