Exemple #1
0
def add_raw_rule(table, chain, rule, safe=False):
    """Adds rule to a fiven table/chain.

    :param ``str`` table:
        Name of the table where the chain resides.
    :param ``str`` chain:
        Name of the chain where to insert the rule.
    :param ``str`` rule:
        Raw iptables rule in the same format as "iptables -S"
    :param ``bool`` safe:
        Query iptables prior to adding to prevent duplicates
    """
    add_cmd = ['iptables', '-t', table, '-A', chain] + rule.split()
    _LOGGER.info('%s', add_cmd)
    if safe:
        # Check if the rule already exists, and if it is, do nothing.
        list_cmd = ['iptables', '-t', table, '-S', chain]
        _LOGGER.info('%s', list_cmd)
        lines = [
            line.strip()
            for line in subproc.check_output(list_cmd).splitlines()
        ]
        match = '-A %s %s' % (chain, rule)
        if match in lines:
            return

    subproc.check_call(add_cmd)
Exemple #2
0
def _unmount_cgroup(name, mounts):
    """Remove mount points of a cgroup."""
    _LOGGER.info('Unmounting cgroup %r(%r)', name, mounts)
    for mount in mounts:
        subproc.check_call(
            ['umount', '-vn', '-t', 'cgroup', mount]
        )
Exemple #3
0
def flush_pt_conntrack_table(passthrough_ip):
    """Clear any entry in the conntrack table for a given passthrough IP.

    This should be run after all the forwarding rules have been removed.

    :param ``str`` passthrough_ip:
        External IP to scrub from the conntrack table.
    """
    # This addresses the case for UDP session in particular.
    #
    # Since netfilter keeps connection state cache for 30 sec by default, udp
    # packets will not be routed if the same rule is recreated, rather they
    # will be routed to non previously associated container.
    #
    # Deleting connection state will ensure that netfilter connection tracking
    # works correctly.
    try:
        subproc.check_call(['conntrack', '-D', '-s', passthrough_ip])
    except subproc.CalledProcessError as exc:
        # return code is 0 if entries were deleted, 1 if no matching
        # entries were found.
        if exc.returncode in (0, 1):
            pass
        else:
            raise
Exemple #4
0
def validate_as_file(encoded_keytabs, basedir):
    """
    validate keytab by given encoded data

    return keytab files validated
    """
    temp_dir = tempfile.mkdtemp(dir=basedir)
    try:
        for encoded in encoded_keytabs:
            test_file = os.path.join(temp_dir, _NAME)
            keytabs2.write_keytab(
                test_file,
                encoded,
            )

            try:
                subproc.check_call(
                    ['kt_split', '--dir={}'.format(basedir), test_file])
            except subproc.CalledProcessError:
                raise keytabs2.KeytabLockerError(
                    'wrong keytab data: {}'.format(encoded))

        for kt_file in os.listdir(basedir):
            full_path = os.path.join(basedir, kt_file)
            # we ignore temp_dir in basedir
            if os.path.isdir(full_path):
                continue

            yield full_path

    finally:
        fs.rmtree_safe(temp_dir)
Exemple #5
0
def mount_filesystem(block_dev, target_dir):
    """Mount filesystem on target directory.

    :param block_dev:
        Block device to mount
    """
    subproc.check_call(['mount', '-n', block_dev, target_dir])
Exemple #6
0
def link_set_down(devname):
    """Bring a network device down.

    :param ``str`` devname:
        The name of the network device.
    """
    subproc.check_call([_IP_EXE, 'link', 'set', 'dev', devname, 'down'], )
Exemple #7
0
def make_keytab(zkclient, spool_dir, host_kt=None):
    """Request keytabs from the locker.
    """
    lockers = zkutils.with_retry(zkclient.get_children, z.KEYTAB_LOCKER)
    random.shuffle(lockers)

    for locker in lockers:
        host, port = locker.split(':')

        try:
            # put the tmp dir near the destination so they end up on
            # the same partition
            tmp_dir = tempfile.mkdtemp(dir=spool_dir)
            if _get_keytabs_from(host, port, tmp_dir):
                inputs = glob.glob(os.path.join(tmp_dir, '*'))
                if host_kt:
                    inputs.append(host_kt)

                kt_file = os.path.join(spool_dir, 'krb5.keytab')
                kt_temp = os.path.join(tmp_dir, 'krb5.keytab')
                subproc.check_call(['kt_add', kt_temp] + inputs)
                os.rename(kt_temp, kt_file)
                break

        finally:
            shutil.rmtree(tmp_dir)
Exemple #8
0
def control_svscan(scan_dir, actions):
    """Sends a control signal to a svscan instance."""
    action_str = '-'
    for action in utils.get_iterable(actions):
        action_str += action.value

    subproc.check_call([_get_cmd('svscanctl'), action_str, scan_dir])
Exemple #9
0
 def _refresh_supervisor(self, instance_names=()):
     """Notify the supervisor of new instances to run."""
     subproc.check_call(['s6_svscanctl', '-an', self.tm_env.running_dir])
     for instance_name in instance_names:
         with lc.LogContext(_LOGGER, instance_name):
             _LOGGER.info('Starting')
             instance_run_link = os.path.join(self.tm_env.running_dir,
                                              instance_name)
             # Wait for the supervisor to pick up the new instance.
             for _ in range(10):
                 res = subproc.call([
                     's6_svok',
                     instance_run_link,
                 ])
                 if res == 0:
                     break
                 else:
                     _LOGGER.warning('Supervisor has not picked it up yet')
                     time.sleep(0.5)
             # Bring the instance up.
             subproc.check_call([
                 's6_svc',
                 '-uO',
                 instance_run_link,
             ])
Exemple #10
0
def bridge_delete(devname):
    """Delete a new network bridge device.

    :param ``str`` devname:
        The name of the network device.
    """
    subproc.check_call([_BRCTL_EXE, 'delbr', devname], )
Exemple #11
0
def route_add(dest,
              rtype='unicast',
              via=None,
              devname=None,
              src=None,
              route_scope=None):
    """Define a new entry in the routing table.

    :param ``str`` devname:
        The name of the network device.
    """
    assert (rtype == 'unicast' and (devname or via)) or rtype == 'blackhole'
    route = [
        'ip',
        'route',
        'add',
        rtype,
        dest,
    ]
    if rtype == 'unicast':
        if via is not None:
            route += ['via', via]
        if devname is not None:
            route += ['dev', devname]
        if src is not None:
            route += ['src', src]

    if route_scope is not None:
        route += ['scope', route_scope]

    subproc.check_call(route)
        def _watch_version(_data, _stat, event):
            """Force exit if server node is deleted."""

            # If the node is deleted, we exit to pick up new version code.
            if event is not None and event.type == 'DELETED':
                # The version info not present, restart services and register
                # new checksum.
                _LOGGER.info('Upgrade requested, running: %s', cli_cmd)

                if cli_cmd:
                    try:
                        subproc.check_call(cli_cmd)
                        # Record successful upgrade.
                    except subprocess.CalledProcessError:
                        _LOGGER.exception('Upgrade failed.')
                        # Immediately trigger a watchdog timeout
                        watchdogs.create(
                            name='version_monitor',
                            timeout='0s',
                            content='Upgrade to '
                            '{code!r}({digest}) failed'.format(code=codepath,
                                                               digest=digest),
                        ).heartbeat()
                        del info['digest']

                _LOGGER.info('Upgrade complete.')
                utils.sys_exit(0)

            return True
Exemple #13
0
def addr_add(addr, devname, ptp_addr=None, addr_scope='link'):
    """Add an IP address to a network device.

    :param ``str`` addr:
        IP address.
    :param ``str`` devname:
        The name of the network device.
    :param ``str`` ptp_addr:
        Peer address on Point-to-Point links.
    """
    if ptp_addr is not None:
        ipaddr = [addr, 'peer', ptp_addr]
    else:
        ipaddr = [addr]

    subproc.check_call([
        'ip',
        'addr',
        'add',
    ] + ipaddr + [
        'dev',
        devname,
        'scope',
        addr_scope,
    ], )
Exemple #14
0
 def _scan(self, scan_dir):
     """Tells the svscan instance to rescan the given scan dir."""
     _LOGGER.debug('Scanning directory %r', scan_dir)
     try:
         subproc.check_call(['s6_svscanctl', '-a', scan_dir])
     except subprocess.CalledProcessError as ex:
         _LOGGER.warning(ex)
Exemple #15
0
def control_service(service_dir, actions, wait=None, timeout=0):
    """Sends a control signal to the supervised process.

    :returns:
        ``True`` - Command was successuful.
        ``False`` - Command timedout (only if `wait` was provided).
    :raises ``subproc.CalledProcessError``:
        With `returncode` set to `ERR_NO_SUP` if the service is not supervised.
        With `returncode` set to `ERR_COMMAND` if there is a problem
        communicating with the supervisor.
    """
    cmd = [_get_cmd('svc')]

    if wait:
        cmd.append('-w' + _get_wait_action(wait).value)
        if timeout > 0:
            cmd.extend(['-T{}'.format(timeout)])

    action_str = '-'
    for action in utils.get_iterable(actions):
        action_str += action.value

    cmd.append(action_str)
    cmd.append(service_dir)

    try:
        subproc.check_call(cmd)

    except subproc.CalledProcessError as err:
        if err.returncode == ERR_TIMEOUT:
            return False
        else:
            raise

    return True
 def _scan(self):
     """Tells the svscan instance to rescan the directory."""
     _LOGGER.debug('Scanning directory %r', self.init_dir)
     try:
         subproc.check_call(['s6-svscanctl', '-an', self.init_dir])
     except subprocess.CalledProcessError as ex:
         _LOGGER.warning(ex)
Exemple #17
0
def krbcc_ok(tkt_path):
    """Check if credential cache is valid (not expired)."""
    try:
        subproc.check_call(['klist', '-5', '-s', tkt_path])
        return True
    except subproc.CalledProcessError:
        _LOGGER.warning('Ticket cache invalid: %s', tkt_path)
        return False
Exemple #18
0
 def _get_admin_tickets(self):
     """get/refresh admin tickets."""
     adminktdir = tempfile.mkdtemp(prefix="ipakeytab-admin-")
     adminkt = "%s/krb5kt_%s" % (adminktdir, self.admin)
     subproc.check_call(
         ['kadmin.local', 'ktadd', '-k', adminkt, '-norandkey', admin])
     subproc.check_call(['kinit', '-k', '-t', adminkt, admin])
     shutil.rmtree(adminktdir)
def init_loopback_devices(loopdevice_numbers):
    """Create and initialize loopback devices."""
    for i in six.moves.range(0, loopdevice_numbers):
        if not os.path.exists('/dev/loop%s' % i):
            subproc.check_call(
                ['mknod', '-m660',
                 '/dev/loop%s' % i, 'b', '7',
                 str(i)])
            subproc.check_call(['chown', 'root.disk', '/dev/loop%s' % i])
Exemple #20
0
def mount_tmpfs(newroot, path, size):
    """Mounts directory on tmpfs."""
    while path.startswith('/'):
        path = path[1:]
    subproc.check_call([
        'mount', '-n', '-o',
        'size=%s' % size, '-t', 'tmpfs', 'tmpfs',
        os.path.join(newroot, path)
    ])
Exemple #21
0
def mount(subsystem):
    """Mounts cgroup subsystem."""
    _LOGGER.info('Mounting cgroup: %s', subsystem)
    path = os.path.join(CGROOT, subsystem)
    if not os.path.exists(path):
        os.mkdir(path)

    subproc.check_call(
        ['mount', '-t', 'cgroup', '-o', subsystem, subsystem, path])
Exemple #22
0
def make_keytab(kt_target, kt_components, owner=None):
    """Construct target keytab from individial components."""
    _LOGGER.info('Creating keytab: %s %r, owner=%s', kt_target, kt_components,
                 owner)
    cmd_line = ['kt_add', kt_target] + kt_components
    subproc.check_call(cmd_line)

    if owner:
        uid = pwd.getpwnam(owner).pw_uid
        os.chown(kt_target, uid, -1)
Exemple #23
0
def gre_delete(grename):
    """Delete a GRE interface.
    """
    subproc.check_call(
        [
            'ip', 'tunnel',
            'del', grename,
            'mode', 'gre',
        ],
    )
Exemple #24
0
def make_keytab(kt_target, kt_components, owner=None):
    """Construct target keytab from individial components."""
    _LOGGER.info('Creating keytab: %s %r, owner=%s', kt_target, kt_components,
                 owner)
    cmd_line = ['kt_add', kt_target] + kt_components
    subproc.check_call(cmd_line)

    if owner:
        (uid, _gid) = utils.get_uid_gid(owner)
        os.chown(kt_target, uid, -1)
Exemple #25
0
def is_down(svc_dir):
    """Check if service is running."""
    try:
        subproc.check_call(['s6_svwait', '-t', '100', '-D', svc_dir])
        return True
    except subprocess.CalledProcessError as err:
        # If wait timed out, the app is already running, do nothing.
        if err.returncode == 1:
            return False
        else:
            raise
Exemple #26
0
def _create_root_dir(tm_env, container_dir, root_dir, app):
    """Prepares chrooted environment and creates all mountpoints.

    :param tm_env:
        Treadmill application environment
    :type tm_env:
        `appenv.AppEnvironment`
    """
    # Generate a unique name for the app
    unique_name = appcfg.app_unique_name(app)

    # First wait for the block device to be ready
    localdisk_client = tm_env.svc_localdisk.make_client(
        os.path.join(container_dir, 'localdisk'))
    localdisk = localdisk_client.wait(unique_name)

    already_initialized = fs.test_filesystem(localdisk['block_dev'])
    if not already_initialized:
        # Format the block device
        fs.create_filesystem(localdisk['block_dev'])

    _LOGGER.info('Creating container root directory: %s', root_dir)
    fs.chroot_init(root_dir)
    fs.mount_filesystem(localdisk['block_dev'], root_dir)
    fs.make_rootfs(root_dir, app.proid)

    fs.configure_plugins(tm_env.root, root_dir, app)

    # Ensure .etc directory is clean in case of volume restore.
    try:
        shutil.rmtree(os.path.join(root_dir, '.etc'))
    except OSError as err:
        if err.errno != errno.ENOENT:
            raise

    shutil.copytree(os.path.join(tm_env.root, 'etc'),
                    os.path.join(root_dir, '.etc'))

    shutil.copyfile('/etc/hosts', os.path.join(root_dir, '.etc/hosts'))
    shutil.copyfile('/etc/hosts', os.path.join(root_dir,
                                               '.etc/hosts.original'))

    hosts_aliases = os.path.join(root_dir, '.etc', 'hosts-aliases')
    fs.mkdir_safe(hosts_aliases)

    pwnam = pwd.getpwnam(app.proid)
    os.chown(hosts_aliases, pwnam.pw_uid, pwnam.pw_gid)

    # Always use our own resolv.conf. Safe to rbind, as we are running in
    # private mount subsystem by now.
    resolv_conf_path = os.path.join(tm_env.root, 'etc/resolv.conf')
    if os.path.exists(resolv_conf_path):
        subproc.check_call(
            ['mount', '-n', '--bind', resolv_conf_path, '/etc/resolv.conf'])
Exemple #27
0
def is_supervised(service_dir):
    """Checks if the supervisor is running."""
    try:
        subproc.check_call([_get_cmd('svok'), service_dir])
        return True
    except subproc.CalledProcessError as err:
        # svok returns 1 when the service directory is not supervised.
        if err.returncode == 1:
            return False
        else:
            raise
Exemple #28
0
def kinit_renew(tkt_path, user):
    """Run kinit -R against the existing CCNAME to renew the ticket."""
    try:
        subproc.check_call(['kinit', '-R'],
                           environ={
                               'KRB5CCNAME': 'FILE:' + tkt_path,
                           },
                           runas=user)
        _LOGGER.info('Tickets renewed successfully.')
    except subproc.CalledProcessError as err:
        _LOGGER.info('Error while renewing tickets, kinit rc: %s',
                     err.returncode)
Exemple #29
0
def bridge_delif(devname, interface):
    """Remove an interface from a bridge device.

    :param ``str`` devname:
        The name of the network device.
    """
    subproc.check_call([
        _BRCTL_EXE,
        'delif',
        devname,
        interface,
    ], )
Exemple #30
0
def bridge_addif(devname, interface):
    """Add an interface to a bridge device.

    :param ``str`` devname:
        The name of the network device.
    """
    subproc.check_call([
        _BRCTL_EXE,
        'addif',
        devname,
        interface,
    ], )