Beispiel #1
0
    def restart(self, request, network_info={}, block_device_info={}):
        """ Restart the container. """
        # return webob.Response(status_int=204)
        container_id = self.container['id']
        LOG.info(_("Restart container %s, network_info:%s, bdm:%s"),
                 container_id, network_info, block_device_info)
        self._stop(container_id)
        try:
            network.teardown_network(container_id)
            if network_info:
                self.unplug_vifs(network_info)
                netns_file = '/var/run/netns/{0}'.format(container_id)
                # if os.path.exists(netns_file):
                # os.remove(netns_file)
        except Exception as e:
            LOG.warning(_('Cannot destroy the container network'
                          ' during reboot {0}').format(e),
                        exc_info=True)
            return

        try:
            self.start(request, network_info=network_info)
        except Exception as e:
            LOG.warning(_('Cannot start on reboot: %s'), e, exc_info=True)
            return
Beispiel #2
0
                def _do_pull_image():
                    name = local_image_name

                    try:
                        import re
                        m = re.search(r'\d+\.\d+\.\d+\.\d+', repository)
                        if m:
                            utils.execute('ping', '-W', '3', '-c', '1',
                                          m.group())
                        LOG.debug(_("Starting pull image repository=%s:%s"),
                                  repository, image_id)
                        resp = self.manager.pull(repository,
                                                 tag=image_id,
                                                 insecure_registry=True)
                        LOG.debug(
                            _("Done pull image repository=%s:%s, resp %s"),
                            repository, image_id, resp)
                        if any(
                                resp.find(s) != -1 for s in
                            ['"error":', image_name + " not found"]):
                            LOG.warn(
                                _("Can't pull image, use the local image with "
                                  "name=%s"), image_name)
                            name = image_name
                    except Exception as e:
                        name = image_name
                        LOG.exception(e)
                    _do_create_after_download_image(name)
Beispiel #3
0
    def attach_volume(self, name, device, mount_device, static=True):
        try:
            s = os.stat(device)
            if not stat.S_ISBLK(s.st_mode):
                raise exception.InvalidInput(reason='"%s" is not block device'%device)
            maj, min = os.major(s.st_rdev), os.minor(s.st_rdev)
            if not static:
                # ignore mount_device now
                self._dynamic_attach_or_detach_volume(name, device, maj, min, attach=True)
            else:
                conf_path = lxc_device_conf_file(name, device)
                with open(conf_path, 'w') as f:
                    for i in range(16):
                        f.write('lxc.cgroup.devices.allow = '
                                 'b %(maj)s:%(min)s rwm\n'%{'maj':maj, 'min':min+i})

                LOG.info(_("new config path %(path)s for %(device)s"),
                        {'path': conf_path, 'device': device})
                # autodev hook:
                #  add the partitions of this device into the container when it starts
                with open(lxc_autodev_hook_script(name, device), 'w') as f, \
                      open('/proc/partitions', 'r') as p:
                    for line in p:
                        fields = line.split()
                        if fields and fields[-1].startswith(os.path.basename(device)):
                            f.write("mknod --mode=0660 $LXC_ROOTFS_MOUNT/dev/%(device)s "
                                    "b %(maj)s %(min)s\n" % {
                                    "device": fields[-1], "maj":fields[0], "min":fields[1]})


        except Exception as ex:
            with excutils.save_and_reraise_exception():
                LOG.error(_('Failed to attach device %(device)s '
                              ' for %(name)s: %(ex)s'),
                          {'name': name, 'ex': ex.message, 'device': device})
Beispiel #4
0
    def restart(self, request, network_info={}, block_device_info={}):
        """ Restart the container. """
        # return webob.Response(status_int=204)
        container_id = self.container['id']
        LOG.info(_("Restart container %s, network_info:%s, bdm:%s"),
                 container_id, network_info, block_device_info)
        self._stop(container_id)
        try:
            network.teardown_network(container_id)
            if network_info:
                self.unplug_vifs(network_info)
                netns_file = '/var/run/netns/{0}'.format(container_id)
                # if os.path.exists(netns_file):
                    # os.remove(netns_file)
        except Exception as e:
            LOG.warning(_('Cannot destroy the container network'
                          ' during reboot {0}').format(e),
                        exc_info=True)
            return

        try:
            self.start(request, network_info=network_info)
        except Exception as e:
            LOG.warning(_('Cannot start on reboot: %s'), e,
                        exc_info=True)
            return
Beispiel #5
0
    def start(self, request, network_info={}, block_device_info={}):
        """ Start the container. """
        container_id = self.container['id']
        LOG.info(_("Start container %s network_info %s block_device_info %s"),
                   container_id, network_info, block_device_info)
        if block_device_info:
            try:
                self._update_bdm(block_device_info)
            except Exception as e:
                LOG.exception(e)
                raise
            for bdm in block_device_info.get('block_device_mapping', []):
                LOG.debug(_("Attach block device mapping %s"), bdm)
                mount_device = bdm['mount_device']
                volume_id = bdm['connection_info']['data']['volume_id']
                real_device = bdm.get('real_device', self._volume_mapping[volume_id])
                self.manager.attach_volume(self.container['id'], real_device, mount_device, static=True)

        if network_info:
            try:
                self.plug_vifs(network_info)
            except Exception as e:
                msg = _('Cannot setup network for container {}: {}').format(
                    self.container['name'],
                    repr(traceback.format_exception(*sys.exc_info()))
                )
                LOG.debug(msg, exc_info=True)
                raise exception.ContainerStartFailed(msg)
        self.manager.start(container_id, network_info=network_info)
        self._create_ns()
        self._settings = {"network_info": network_info, "block_device_info": block_device_info}
        save_settings(self._settings)
Beispiel #6
0
    def create(self, request, image_name, image_id, root_volume_id=None, network_info={},
                      block_device_info={}, inject_files=[], admin_password=None):
        """ create the container. """
        if root_volume_id:
            # Create VM from volume, create a symbolic link for the device.
            LOG.info(_("Create new container from volume %s"), root_volume_id)
            self._add_root_mapping(root_volume_id)

        def _do_create():
            if admin_password is not None:
                self._inject_password(admin_password)
            if inject_files:
                self._inject_files(inject_files, plain=True)
            if block_device_info:
                try:
                    self._attach_bdm(block_device_info)
                except Exception as e:
                    LOG.exception(e)
        try:
            container = self.container
            LOG.warn(_("Already a container exists"))
            # Do the work anyway
            _do_create()
            return  FAKE_SUCCESS_TASK
        except exception.ContainerNotFound:
            repository = self._get_repository(image_name)
            #local_image_name = repository + ':' + image_id
            local_image_name = image_id

            def _do_create_after_download_image(name):
                LOG.debug(_("Create container from image %s"), name)
                self.manager.create_container(name, network_disabled=True)
                _do_create()

            if self.manager.images(name=local_image_name):
                LOG.debug(_("Repository = %s already exists"), local_image_name)
                _do_create_after_download_image(local_image_name)
                return FAKE_SUCCESS_TASK
            else:
                def _do_pull_image():
                    name = local_image_name

                    try:
                        import re
                        m = re.search(r'\d+\.\d+\.\d+\.\d+', repository)
                        if m:
                            utils.execute('ping', '-W', '3', '-c', '1', m.group())
                        LOG.debug(_("Starting pull image repository=%s:%s"), repository, image_id)
                        resp = self.manager.pull(repository, tag=image_id, insecure_registry=True)
                        LOG.debug(_("Done pull image repository=%s:%s, resp %s"), repository, image_id, resp)
                        if any(resp.find(s)!=-1 for s in ['"error":', image_name + " not found"]):
                            LOG.warn(_("Can't pull image, use the local image with name=%s"), image_name)
                            name = image_name
                    except Exception as e:
                        name = image_name
                        LOG.exception(e)
                    _do_create_after_download_image(name)
                task = addtask(_do_pull_image)
                LOG.debug(_("Pull image task %s"), task)
                return task
Beispiel #7
0
    def attach_volume(self, name, device, mount_device, static=True):
        try:
            s = os.stat(device)
            if not stat.S_ISBLK(s.st_mode):
                raise exception.InvalidInput(reason='"%s" is not block device'%device)
            maj, min = os.major(s.st_rdev), os.minor(s.st_rdev)
            if not static:
                # ignore mount_device now
                self._dynamic_attach_or_detach_volume(name, device, maj, min, attach=True)
            else:
                conf_path = lxc_device_conf_file(name, device)
                with open(conf_path, 'w') as f:
                    for i in range(16):
                        f.write('lxc.cgroup.devices.allow = '
                                 'b %(maj)s:%(min)s rwm\n'%{'maj':maj, 'min':min+i})

                LOG.info(_("new config path %(path)s for %(device)s"),
                        {'path': conf_path, 'device': device})
                # autodev hook:
                #  add the partitions of this device into the container when it starts
                with open(lxc_autodev_hook_script(name, device), 'w') as f, \
                      open('/proc/partitions', 'r') as p:
                    for line in p:
                        fields = line.split()
                        if fields and fields[-1].startswith(os.path.basename(device)):
                            f.write("mknod --mode=0660 $LXC_ROOTFS_MOUNT/dev/%(device)s "
                                    "b %(maj)s %(min)s\n" % {
                                    "device": fields[-1], "maj":fields[0], "min":fields[1]})


        except Exception as ex:
            with excutils.save_and_reraise_exception():
                LOG.error(_('Failed to attach device %(device)s '
                              ' for %(name)s: %(ex)s'),
                          {'name': name, 'ex': ex.message, 'device': device})
Beispiel #8
0
def set_passwd(username, admin_passwd, passwd_data, shadow_data):
    """set the password for username to admin_passwd

    The passwd_file is not modified.  The shadow_file is updated.
    if the username is not found in both files, an exception is raised.

    :param username: the username
    :param encrypted_passwd: the  encrypted password
    :param passwd_file: path to the passwd file
    :param shadow_file: path to the shadow password file
    :returns: nothing
    :raises: exception.WormholeException(), IOError()

    """

    # encryption algo - id pairs for crypt()
    algos = {'SHA-512': '$6$', 'SHA-256': '$5$', 'MD5': '$1$', 'DES': ''}

    salt = _generate_salt()

    # crypt() depends on the underlying libc, and may not support all
    # forms of hash. We try md5 first. If we get only 13 characters back,
    # then the underlying crypt() didn't understand the '$n$salt' magic,
    # so we fall back to DES.
    # md5 is the default because it's widely supported. Although the
    # local crypt() might support stronger SHA, the target instance
    # might not.
    encrypted_passwd = crypt.crypt(admin_passwd, algos['MD5'] + salt)
    if len(encrypted_passwd) == 13:
        encrypted_passwd = crypt.crypt(admin_passwd, algos['DES'] + salt)

    p_file = passwd_data.split("\n")
    s_file = shadow_data.split("\n")

    # username MUST exist in passwd file or it's an error
    for entry in p_file:
        split_entry = entry.split(':')
        if split_entry[0] == username:
            break
    else:
        msg = _('User %(username)s not found in password file.')
        raise exception.WormholeException(msg % username)

    # update password in the shadow file.It's an error if the
    # the user doesn't exist.
    new_shadow = list()
    found = False
    for entry in s_file:
        split_entry = entry.split(':')
        if split_entry[0] == username:
            split_entry[1] = encrypted_passwd
            found = True
        new_entry = ':'.join(split_entry)
        new_shadow.append(new_entry)

    if not found:
        msg = _('User %(username)s not found in shadow file.')
        raise exception.WormholeException(msg % username)

    return "\n".join(new_shadow)
Beispiel #9
0
    def restart(self, request, network_info={}, block_device_info={}):
        """ Restart the container. """
        # return webob.Response(status_int=204)
        container_id = self.container['id']
        LOG.info("restart container %s", container_id)
        self._stop(container_id)
        try:
            network.teardown_network(container_id)
            self._ns_created = False
            if network_info:
                self.unplug_vifs(network_info)
                netns_file = '/var/run/netns/{0}'.format(container_id)
                # if os.path.exists(netns_file):
                # os.remove(netns_file)
        except Exception as e:
            LOG.warning(_('Cannot destroy the container network'
                          ' during reboot {0}').format(e),
                        exc_info=True)
            return

        dns = self._extract_dns_entries(network_info)
        self.docker.start(container_id, dns=dns)
        try:
            if network_info:
                self.plug_vifs(network_info)
                self._attach_vifs(network_info)
        except Exception as e:
            LOG.warning(_('Cannot setup network on reboot: %s'),
                        e,
                        exc_info=True)
            return
Beispiel #10
0
 def _create_image_cb():
     LOG.debug(_("Pushing image %s"), repository)
     self.manager.commit(self.container['id'],
                         repository=repository,
                         tag=image_id)
     self.manager.push(repository, tag=image_id, insecure_registry=True)
     LOG.debug(_("Doing image %s"), repository)
Beispiel #11
0
    def __init__(self, name, app, host='0.0.0.0', port=0, pool_size=None,
                       protocol=eventlet.wsgi.HttpProtocol, backlog=128,
                       use_ssl=False, max_url_len=None):
        """Initialize, but do not start, a WSGI server.

        :param name: Pretty name for logging.
        :param app: The WSGI application to serve.
        :param host: IP address to serve the application.
        :param port: Port number to server the application.
        :param pool_size: Maximum number of eventlets to spawn concurrently.
        :param backlog: Maximum number of queued connections.
        :param max_url_len: Maximum length of permitted URLs.
        :returns: None
        :raises: wormhole.exception.InvalidInput
        """
        # Allow operators to customize http requests max header line size.
        eventlet.wsgi.MAX_HEADER_LINE = CONF.max_header_line
        self.name = name
        self.app = app
        self._server = None
        self._protocol = protocol
        self.pool_size = pool_size or self.default_pool_size
        self._pool = eventlet.GreenPool(self.pool_size)
        self._logger = logging.getLogger("wormhole.%s.wsgi.server" % self.name)
        self._wsgi_logger = logging.WritableLogger(self._logger)
        self._use_ssl = use_ssl
        self._max_url_len = max_url_len
        self.client_socket_timeout = CONF.client_socket_timeout or None

        if backlog < 1:
            raise exception.InvalidInput(
                    reason='The backlog must be more than 1')

        bind_addr = (host, port)
        # TODO(dims): eventlet's green dns/socket module does not actually
        # support IPv6 in getaddrinfo(). We need to get around this in the
        # future or monitor upstream for a fix
        try:
            info = socket.getaddrinfo(bind_addr[0],
                                      bind_addr[1],
                                      socket.AF_UNSPEC,
                                      socket.SOCK_STREAM)[0]
            family = info[0]
            bind_addr = info[-1]
        except Exception:
            family = socket.AF_INET

        try:
            self._socket = eventlet.listen(bind_addr, family, backlog=backlog)
        except EnvironmentError:
            LOG.error(_("Could not bind to %(host)s:%(port)s"),
                      {'host': host, 'port': port})
            raise

        (self.host, self.port) = self._socket.getsockname()[0:2]
        LOG.info(_("%(name)s listening on %(host)s:%(port)s"),
                 {'name': self.name, 'host': self.host, 'port': self.port})
Beispiel #12
0
def delete_net_dev(dev):
    """Delete a network device only if it exists."""
    if device_exists(dev):
        try:
            utils.execute('ip', 'link', 'delete', dev, run_as_root=True,
                          check_exit_code=[0, 2, 254])
            LOG.debug(_("Net device removed: '%s'"), dev)
        except processutils.ProcessExecutionError:
            with excutils.save_and_reraise_exception():
                LOG.error(_("Failed removing net device: '%s'"), dev)
Beispiel #13
0
def delete_net_dev(dev):
    """Delete a network device only if it exists."""
    if device_exists(dev):
        try:
            utils.execute('ip', 'link', 'delete', dev, run_as_root=True,
                          check_exit_code=[0, 2, 254])
            LOG.debug(_("Net device removed: '%s'"), dev)
        except processutils.ProcessExecutionError:
            with excutils.save_and_reraise_exception():
                LOG.error(_("Failed removing net device: '%s'"), dev)
Beispiel #14
0
    def clone_volume(self, request, volume, src_vref):
        LOG.debug(_("Cloning volume %s, src_vref %s"), volume, src_vref)
        srcstr = self._get_device(src_vref["id"])
        dststr = self._get_device(volume["id"])
        size_in_g = min(int(src_vref['size']), int(volume['size']))

        clone_callback = functools.partial(utils.copy_volume, srcstr, dststr,
                                            size_in_g*units.Ki, CONF.volume_dd_blocksize)
        task = addtask(clone_callback)
        LOG.debug(_("Clone volume task %s"), task)

        return task
Beispiel #15
0
 def create_image(self, request, image_name, image_id):
     """ Create a image from the container. """
     repository = self._get_repository(image_name)
     LOG.debug(_("Creating image from repo = %s, tag = %s"), repository, image_id)
     def _create_image_cb():
         LOG.debug(_("Pushing image %s"), repository)
         self.manager.commit(self.container['id'], repository=repository,
             tag=image_id)
         self.manager.push(repository, tag=image_id, insecure_registry=True)
         LOG.debug(_("Doing image %s"), repository)
     task = addtask(_create_image_cb)
     LOG.debug(_("Created image task %s"), task)
     return task
Beispiel #16
0
    def clone_volume(self, request, volume, src_vref):
        LOG.debug(_("Cloning volume %s, src_vref %s"), volume, src_vref)
        srcstr = self._get_device(src_vref["id"])
        dststr = self._get_device(volume["id"])
        size_in_g = min(int(src_vref['size']), int(volume['size']))

        clone_callback = functools.partial(utils.copy_volume, srcstr, dststr,
                                           size_in_g * units.Ki,
                                           CONF.volume_dd_blocksize)
        task = addtask(clone_callback)
        LOG.debug(_("Clone volume task %s"), task)

        return task
Beispiel #17
0
 def _get_device(self, volume_id):
     device = self.volume_device_mapping.get(volume_id)
     if not device:
         LOG.warn(_("Can't found mapping for volume %s"), volume_id)
         link_path = volume_link_path(volume_id)
         if os.path.islink(link_path):
             realpath = os.path.realpath(link_path)
             if realpath.startswith("/dev/"):
                 self.volume_device_mapping[volume_id] = realpath
                 device = realpath
     if not device:
         raise exception.VolumeNotFound(id=volume_id)
     LOG.debug(_("Found volume mapping: %s ==> %s"), volume_id, device)
     return device
Beispiel #18
0
 def _get_device(self, volume_id):
     device = self.volume_device_mapping.get(volume_id)
     if not device:
         LOG.warn(_("Can't found mapping for volume %s"), volume_id)
         link_path = volume_link_path(volume_id)
         if os.path.islink(link_path):
             realpath = os.path.realpath(link_path)
             if realpath.startswith("/dev/"):
                 self.volume_device_mapping[volume_id] = realpath
                 device = realpath
     if not device:
         raise exception.VolumeNotFound(id=volume_id)
     LOG.debug(_("Found volume mapping: %s ==> %s"), volume_id, device)
     return device
Beispiel #19
0
def flush_device_io(device):
    """This is used to flush any remaining IO in the buffers."""
    try:
        LOG.debug("Flushing IO for device %s", device)
        execute('blockdev', '--flushbufs', device, run_as_root=True)
    except Exception as exc:
        LOG.warning(_("Failed to flush IO buffers prior to removing "))
Beispiel #20
0
    def __init__(self, name, loader=None, use_ssl=False, max_url_len=None):
        """Initialize, but do not start the WSGI server.

        :param name: The name of the WSGI server given to the loader.
        :param loader: Loads the WSGI application using the given name.
        :returns: None

        """
        self.name = name
        self.manager = self._get_manager()
        self.loader = loader or wsgi.Loader()
        self.app = self.loader.load_app(name)
        self.host = '0.0.0.0'
        self.port = CONF.get('port', 7127)
        self.workers = 1
        if self.workers and self.workers < 1:
            worker_name = '%s_workers' % name
            msg = (_("%(worker_name)s value of %(workers)s is invalid, "
                     "must be greater than 0") %
                   {'worker_name': worker_name,
                    'workers': str(self.workers)})
            raise exception.InvalidInput(msg)
        self.use_ssl = use_ssl
        self.server = wsgi.Server(name,
                                  self.app,
                                  host=self.host,
                                  port=self.port,
                                  use_ssl=self.use_ssl,
                                  max_url_len=max_url_len)
        # Pull back actual port used
        self.port = self.server.port
        self.backdoor_port = None
Beispiel #21
0
def find_fixed_ip(instance, network_info):
    for subnet in network_info['subnets']:
        netmask = subnet['cidr'].split('/')[1]
        for ip in subnet['ips']:
            if ip['type'] == 'fixed' and ip['address']:
                return ip['address'] + "/" + netmask
    raise exception.InstanceDeployFailure(_('Cannot find fixed ip for %s'), instance)
Beispiel #22
0
    def get_sg_client_status(self, request, sgclient_properties):
        target_ip = sgclient_properties["meta_server_ip"]
        config_file = "/etc/storage-gateway/config.ini"
        try:
            config_info = ConfigParser.ConfigParser()
            config_info.read(config_file)
            meta_server_ip = config_info.get("network", "meta_server_ip")

            # check meta_server_ip exsiting or not
            # check target_ip and meta_server_ip relationship
            if meta_server_ip.strip():
                if target_ip != meta_server_ip:
                    return {"status": "no"}
                else:
                    run_list = os.popen(
                        "ps -aux | grep sg_client | grep -v grep | cut -c 9-15"
                    )
                    status = run_list.read()
                    run_list.close()
                    if status.strip() != '':
                        return {"status": "yes"}
                    else:
                        return {"status": "no"}
            else:
                return {"status": "no"}
        except Exception:
            msg = _("get sg_client status failed")
            LOG.debug(msg)
            raise exception.WormholeException
Beispiel #23
0
 def _create_ns(self):
     if self._ns_created:
         return
     container_id = self.container['id']
     netns_path = '/var/run/netns'
     if not os.path.exists(netns_path):
         utils.execute('mkdir', '-p', netns_path, run_as_root=True)
     nspid = self._find_container_pid(container_id)
     if not nspid:
         msg = _('Cannot find any PID under container "{0}"')
         raise RuntimeError(msg.format(container_id))
     netns_path = os.path.join(netns_path, container_id)
     utils.execute('ln',
                   '-sf',
                   '/proc/{0}/ns/net'.format(nspid),
                   '/var/run/netns/{0}'.format(container_id),
                   run_as_root=True)
     utils.execute('ip',
                   'netns',
                   'exec',
                   container_id,
                   'ip',
                   'link',
                   'set',
                   'lo',
                   'up',
                   run_as_root=True)
     self._ns_created = True
Beispiel #24
0
 def unpause(self, name):
     try:
         utils.execute('lxc-unfreeze', '-n', name)
     except Exception as ex:
         with excutils.save_and_reraise_exception():
             LOG.error(_('Failed to unpause container for %(name)s: %(ex)s'),
                       {'name': name, 'ex': ex.message})
Beispiel #25
0
    def unplug_ovs_hybrid(self, instance, vif):
        """UnPlug using hybrid strategy

        Unhook port from OVS, unhook port from bridge, delete
        bridge, and delete both veth devices.
        """
        try:
            br_name = self.get_br_name(vif['id'])
            vm_port_name = self.get_vm_ovs_port_name(vif['id'])

            if_local_name = 'tap%s' % vif['id'][:11]
            if linux_net.device_exists(if_local_name):
                linux_net.delete_net_dev(if_local_name)

            if linux_net.device_exists(br_name):
                utils.execute('brctl',
                              'delif',
                              br_name,
                              vm_port_name,
                              run_as_root=True)
                utils.execute('ip',
                              'link',
                              'set',
                              br_name,
                              'down',
                              run_as_root=True)
                utils.execute('brctl', 'delbr', br_name, run_as_root=True)

            linux_net.delete_ovs_vif_port(self.get_bridge_name(vif),
                                          vm_port_name)
        except processutils.ProcessExecutionError:
            LOG.exception(_("Failed while unplugging vif for %s"), instance)
Beispiel #26
0
    def config_sg_client(self, request, sgclient_properties):
        meta_server_ip = sgclient_properties['meta_server_ip']
        config_file = "/etc/storage-gateway/config.ini"
        try:
            config_info = ConfigParser.ConfigParser()
            config_info.read(config_file)

            # modify meta_server_ip
            config_info.set("network", "meta_server_ip", meta_server_ip)
            config_info.write(open(config_file, "w"))

            # check the sg_client run status
            check_run = os.popen(
                "ps -aux | grep sg_client | grep -v grep | cut -c 9-15")
            sg_client_status = check_run.read()
            check_run.close()
            if sg_client_status.strip() != '':
                os.system(
                    "ps -aux | grep sg_client | grep -v grep | cut -c 9-15 | xargs kill -9"
                )

                # start sg_client
            os.popen("/usr/bin/storage-gateway/sg_client &")
            return {"result": "yes"}
        except Exception:
            msg = _("meta_server_ip set up error")
            LOG.debug(msg)
            raise exception.WormholeException
Beispiel #27
0
def _calculate_count(size_in_m, blocksize):

    # Check if volume_dd_blocksize is valid
    try:
        # Rule out zero-sized/negative/float dd blocksize which
        # cannot be caught by strutils
        if blocksize.startswith(('-', '0')) or '.' in blocksize:
            raise ValueError
        bs = strutils.string_to_bytes('%sB' % blocksize)
    except ValueError:
        msg = (_("Incorrect value error: %(blocksize)s, "
                 "it may indicate that \'volume_dd_blocksize\' "
                 "was configured incorrectly. Fall back to default.") % {
                     'blocksize': blocksize
                 })
        LOG.warn(msg)
        # Fall back to default blocksize
        CONF.clear_override('volume_dd_blocksize')
        blocksize = CONF.volume_dd_blocksize
        bs = strutils.string_to_bytes('%sB' % blocksize)

    print(size_in_m, units.Mi, bs)
    count = math.ceil(size_in_m * units.Mi / bs)

    return blocksize, int(count)
Beispiel #28
0
 def unpause(self, name):
     try:
         utils.execute('lxc-unfreeze', '-n', name)
     except Exception as ex:
         with excutils.save_and_reraise_exception():
             LOG.error(_('Failed to unpause container for %(name)s: %(ex)s'),
                       {'name': name, 'ex': ex.message})
Beispiel #29
0
 def _remove_mapping(self, volume_id, ensure=True, static=True):
     link_file = volume_link_path(volume_id)
     if os.path.islink(link_file):
         dev_path = os.path.realpath(link_file)
         # ignore the manager root volume
         if not dev_path.startswith(self.root_dev_path):
             LOG.debug(_("Detach volume %s"), volume_id)
             if ensure:
                 # ensure the device path is not visible in host/container
                 if check_dev_exist(dev_path):
                     LOG.warn(_("Try to delete device %s, but it seems exist."), dev_path)
                 utils.trycmd('bash', '-c', 'echo 1 > /sys/block/%s/device/delete' % dev_path.replace('/dev/',''))
             os.remove(link_file)
             self._volume_mapping.pop(volume_id)
             self.manager.detach_volume(self.container['id'], dev_path,
                                         self._mount_path.get(dev_path,''), static)
Beispiel #30
0
    def __init__(self, name, loader=None, use_ssl=False, max_url_len=None):
        """Initialize, but do not start the WSGI server.

        :param name: The name of the WSGI server given to the loader.
        :param loader: Loads the WSGI application using the given name.
        :returns: None

        """
        self.name = name
        self.manager = self._get_manager()
        self.loader = loader or wsgi.Loader()
        self.app = self.loader.load_app(name)
        self.host = '0.0.0.0'
        self.port = CONF.get('port', 7127)
        self.workers = 1
        if self.workers and self.workers < 1:
            worker_name = '%s_workers' % name
            msg = (_("%(worker_name)s value of %(workers)s is invalid, "
                     "must be greater than 0") %
                   {'worker_name': worker_name,
                    'workers': str(self.workers)})
            raise exception.InvalidInput(msg)
        self.use_ssl = use_ssl
        self.server = wsgi.Server(name,
                                  self.app,
                                  host=self.host,
                                  port=self.port,
                                  use_ssl=self.use_ssl,
                                  max_url_len=max_url_len)
        # Pull back actual port used
        self.port = self.server.port
        self.backdoor_port = None
Beispiel #31
0
    def _inject_files(self, inject_files, plain=False):
        container_id = self.container['id']

        try:
            for (path, content_base64) in inject_files:
                # Ensure the parent dir of injecting file exists
                dirname = os.path.dirname(path)
                if not dirname:
                    dirname = '/'

                filename = os.path.basename(path)

                content = content_base64 if plain else base64.b64decode(
                    content_base64)
                LOG.debug(_("Inject file %s, content: len = %d, partial = %s"),
                          path, len(content), content[:30])

                # TODO: file already exists in the container, need to backup?
                self.manager.inject_file(container_id, path, content)

        except TypeError as e:  # invalid base64 encode
            LOG.exception(e)
            raise exception.InjectFailed(path=path,
                                         reason="contents %s" % e.message)
        except Exception as e:
            LOG.exception(e)
            raise exception.InjectFailed(path='',
                                         reason=repr(e) + str(e.message))
Beispiel #32
0
    def __call__(self, environ, start_response):
        r"""Subclasses will probably want to implement __call__ like this:

        @webob.dec.wsgify(RequestClass=Request)
        def __call__(self, req):
          # Any of the following objects work as responses:

          # Option 1: simple string
          res = 'message\n'

          # Option 2: a nicely formatted HTTP exception page
          res = exc.HTTPForbidden(explanation='Nice try')

          # Option 3: a webob Response object (in case you need to play with
          # headers, or you want to be treated like an iterable, or or or)
          res = Response();
          res.app_iter = open('somefile')

          # Option 4: any wsgi app to be run next
          res = self.application

          # Option 5: you can get a Response object for a wsgi app, too, to
          # play with headers etc
          res = req.get_response(self.application)

          # You can then just return your response...
          return res
          # ... or set req.response and return None.
          req.response = res

        See the end of http://pythonpaste.org/webob/modules/dec.html
        for more info.

        """
        raise NotImplementedError(_('You must implement __call__'))
Beispiel #33
0
def _ovs_ofctl(args):
    full_args = ['ovs-ofctl', '--timeout=%s' % CONF.ovs_vsctl_timeout] + args
    try:
        return utils.execute(*full_args, run_as_root=True)
    except Exception as e:
        LOG.error(_("Unable to execute %(cmd)s. Exception: %(exception)s"),
                  {'cmd': full_args, 'exception': e})
        raise e
Beispiel #34
0
def find_fixed_ip(instance, network_info):
    for subnet in network_info['subnets']:
        netmask = subnet['cidr'].split('/')[1]
        for ip in subnet['ips']:
            if ip['type'] == 'fixed' and ip['address']:
                return ip['address'] + "/" + netmask
    raise exception.InstanceDeployFailure(_('Cannot find fixed ip for %s'),
                                          instance)
Beispiel #35
0
def _ovs_ofctl(args):
    full_args = ['ovs-ofctl', '--timeout=%s' % CONF.ovs_vsctl_timeout] + args
    try:
        return utils.execute(*full_args, run_as_root=True)
    except Exception as e:
        LOG.error(_("Unable to execute %(cmd)s. Exception: %(exception)s"),
                  {'cmd': full_args, 'exception': e})
        raise e
Beispiel #36
0
    def create_image(self, request, image_name, image_id):
        """ Create a image from the container. """
        repository = self._get_repository(image_name)
        LOG.debug(_("Creating image from repo = %s, tag = %s"), repository,
                  image_id)

        def _create_image_cb():
            LOG.debug(_("Pushing image %s"), repository)
            self.manager.commit(self.container['id'],
                                repository=repository,
                                tag=image_id)
            self.manager.push(repository, tag=image_id, insecure_registry=True)
            LOG.debug(_("Doing image %s"), repository)

        task = addtask(_create_image_cb)
        LOG.debug(_("Created image task %s"), task)
        return task
Beispiel #37
0
 def detach_interface(self, request, vif):
     if vif:
         LOG.debug(_("Detach network info %s"), vif)
         container_id = self.container['id']
         self.vif_driver.unplug(container_id, vif)
         self.manager.remove_interfaces(container_id, [vif])
         self._save_interface(vif, action='del')
     return webob.Response(status_int=200)
Beispiel #38
0
 def _sync(self):
     LOG.debug(_("Flush file system buffers"))
     if hasattr(os, 'sync'):
         os.sync()
     else:
         import ctypes
         libc = ctype.CDLL("libc.so.6")
         libc.sync()
Beispiel #39
0
    def _require_attribute(self, ref, attribute):
        """Ensures the reference contains the specified attribute.

        Raise a ValidationError if the given attribute is not present
        """
        if self._attribute_is_empty(ref, attribute):
            msg = _('%s field is required and cannot be empty') % attribute
            raise exception.ValidationError(message=msg)
Beispiel #40
0
 def _add_mapping(self, volume_id, mountpoint, device='', static=True):
     LOG.debug(_("Attach volume %s : device %s, mountpoint %s"), volume_id, device, mountpoint)
     if not device:
         link_file = volume_link_path(volume_id)
         if os.path.islink(link_file):
             device = os.path.realpath(link_file)
         else:
             LOG.warn(_("Can't find the device of volume %s when attaching volume"), volume_id)
             return
     else:
         if not device.startswith("/dev/"):
             device = "/dev/" + device
         self._volume_mapping[volume_id] = device
         utils.trycmd('ln', '-sf', device, volume_link_path(volume_id))
     self._mount_path[device] = mountpoint
     if mountpoint != 'none': 
         self.manager.attach_volume(self.container['id'], device, mountpoint, static)
Beispiel #41
0
 def disconnect_volume(self, request, connection_properties):
     try:
         self._connector.disconnect_volume(connection_properties, None)
     except Exception:
         msg = _("detach volume failed")
         LOG.debug(msg)
         raise exception.WormholeException
     return webob.Response(status_int=200)
Beispiel #42
0
 def detach_interface(self, request, vif):
     if vif:
         LOG.debug(_("Detach network info %s"), vif)
         container_id = self.container['id']
         self.vif_driver.unplug(container_id, vif)
         self.manager.remove_interfaces(container_id, [vif])
         self._save_interface(vif, action='del')
     return webob.Response(status_int=200)
Beispiel #43
0
 def _sync(self):
     LOG.debug(_("Flush file system buffers"))
     if hasattr(os, 'sync'):
         os.sync()
     else:
         import ctypes
         libc = ctype.CDLL("libc.so.6")
         libc.sync()
Beispiel #44
0
    def _update_bdm(self, block_device_info):
        """ Update mapping info. """
        if block_device_info:
            new_volume_mapping = {}
            for bdm in block_device_info.get('block_device_mapping', []):
                LOG.debug(_("Attach block device mapping %s"), bdm)
                mount_device = bdm['mount_device']
                size_in_g = bdm.get('size', "0")
                volume_id = bdm['connection_info']['data']['volume_id']
                new_volume_mapping[volume_id] = {"mount_device" : mount_device, "size": str(size_in_g) + "G"}

            all_devices = utils.list_device()
            to_remove_volumes = set(self._volume_mapping) - set(new_volume_mapping)

            for comm_volume in set(self._volume_mapping).intersection(new_volume_mapping):
                _path = self._volume_mapping[comm_volume]
                _size = new_volume_mapping[comm_volume]['size']
                # If the device not exist or size not match, then remove it.
                if not check_dev_exist(_path) or \
                        any([d['name'] == _path and d['size'] == _size for d in all_devices]):
                    LOG.info(_("Volume %s doesn't match, update it."), comm_volume)
                    to_remove_volumes.add(comm_volume)

            if to_remove_volumes:
                LOG.info(_("Possible detach volume when vm is stopped:%s"), to_remove_volumes)

                for remove in to_remove_volumes:
                    self._remove_mapping(remove, ensure=False)

            to_add_volumes = set(new_volume_mapping) - set(self._volume_mapping)

            if to_add_volumes:
                LOG.info(_("Possible attach volume when vm is stopped"))
                new_devices = [d for d in all_devices if d['name'] not in self._volume_mapping.values()]

                ## group by size
                for size in set([d['size'] for d in new_devices]):
                    _devices = sorted([d['name'] for d in new_devices if d['size'] == size])
                    _to_add_volumes = []
                    for _s in (size, '0G'):
                        _to_add_volumes.extend(sorted([v for v in to_add_volumes if new_volume_mapping[v]['size'] == _s]))
                    LOG.debug(_("Size: %s, new_devices:%s, added_volums:%s"),
                                size, _devices, _to_add_volumes)
                    for add, new_device in zip(_to_add_volumes, _devices):
                        self._add_mapping(add, new_volume_mapping[add]['mount_device'], new_device)
Beispiel #45
0
 def create_container(self, name, network_disabled=False):
     try:
         utils.execute('lxc-create', '-n', name, '-t', LXC_TEMPLATE_SCRIPT)
     except Exception as ex:
         with excutils.save_and_reraise_exception():
             LOG.error(_('Faild to start container '
                           '%(name)s: %(ex)s'),
                       {'name': name, 'ex': ex.message})
             self.destroy(name, network_info)
Beispiel #46
0
 def create_container(self, name, network_disabled=False):
     try:
         utils.execute('lxc-create', '-n', name, '-t', LXC_TEMPLATE_SCRIPT)
     except Exception as ex:
         with excutils.save_and_reraise_exception():
             LOG.error(_('Faild to start container '
                           '%(name)s: %(ex)s'),
                       {'name': name, 'ex': ex.message})
             self.destroy(name, network_info)
Beispiel #47
0
 def list(self, request, scan=True):
     """ List all host devices. """
     if scan:
         LOG.debug(_("Scaning host scsi devices"))
         utils.trycmd(
             "bash", "-c",
             "for f in /sys/class/scsi_host/host*/scan; do echo "
             "'- - -' > $f; done")
     return {"devices": [d['name'] for d in utils.list_device()]}
Beispiel #48
0
                def _do_pull_image():
                    name = local_image_name

                    try:
                        import re
                        m = re.search(r'\d+\.\d+\.\d+\.\d+', repository)
                        if m:
                            utils.execute('ping', '-W', '3', '-c', '1', m.group())
                        LOG.debug(_("Starting pull image repository=%s:%s"), repository, image_id)
                        resp = self.manager.pull(repository, tag=image_id, insecure_registry=True)
                        LOG.debug(_("Done pull image repository=%s:%s, resp %s"), repository, image_id, resp)
                        if any(resp.find(s)!=-1 for s in ['"error":', image_name + " not found"]):
                            LOG.warn(_("Can't pull image, use the local image with name=%s"), image_name)
                            name = image_name
                    except Exception as e:
                        name = image_name
                        LOG.exception(e)
                    _do_create_after_download_image(name)
Beispiel #49
0
 def _attach_bdm(self, block_device_info):
     """ Attach volume, setup symbolic for volume id mapping to device name.
     """
     if block_device_info:
         for bdm in block_device_info.get('block_device_mapping', []):
             LOG.debug(_("Attach block device mapping %s"), bdm)
             mount_device = bdm['mount_device']
             volume_id = bdm['connection_info']['data']['volume_id']
             self._add_mapping(volume_id, mount_device, bdm.get('real_device', ''))
Beispiel #50
0
 def detach_volume(self, name, device, mount_device, static=True):
     try:
         s = os.stat(device)
         if not stat.S_ISBLK(s.st_mode):
             raise exception.InvalidInput(reason='"%s" is not block device'%device)
         maj, min = os.major(s.st_rdev), os.minor(s.st_rdev)
         if not static:
             self._dynamic_attach_or_detach_volume(name, device, maj, min, attach=False)
         for cb in  [lxc_device_conf_file, lxc_autodev_hook_script]:
             path = cb(name, device)
             if path and os.isfile(path):
                 os.remove(path)
                 LOG.info(_("delete path %(path)s for %(device)s"),
                         {'path': path, 'device': device})
     except Exception as ex:
         with excutils.save_and_reraise_exception():
             LOG.error(_('Failed to detach device %(device)s '
                           ' for %(name)s: %(ex)s'),
                       {'name': name, 'ex': ex.message, 'device': device})
Beispiel #51
0
 def container(self):
     if self._container is None:
         containers = self.manager.list(all=True)
         if not containers:
             raise exception.ContainerNotFound()
         if len(containers) > 1:
             LOG.warn(_("Have multiple(%d) containers: %s !"), len(containers), containers)
         self._container = { "id" : containers[0]["id"],
                 "name" : containers[0]["name"]}
     return self._container
Beispiel #52
0
 def detach_volume(self, name, device, mount_device, static=True):
     try:
         s = os.stat(device)
         if not stat.S_ISBLK(s.st_mode):
             raise exception.InvalidInput(reason='"%s" is not block device'%device)
         maj, min = os.major(s.st_rdev), os.minor(s.st_rdev)
         if not static:
             self._dynamic_attach_or_detach_volume(name, device, maj, min, attach=False)
         for cb in  [lxc_device_conf_file, lxc_autodev_hook_script]:
             path = cb(name, device)
             if path and os.isfile(path):
                 os.remove(path)
                 LOG.info(_("delete path %(path)s for %(device)s"),
                         {'path': path, 'device': device})
     except Exception as ex:
         with excutils.save_and_reraise_exception():
             LOG.error(_('Failed to detach device %(device)s '
                           ' for %(name)s: %(ex)s'),
                       {'name': name, 'ex': ex.message, 'device': device})
Beispiel #53
0
 def _available_eth_name(self):
     net_prefix = 'eth'
     used_eths = self._discovery_use_eth()
     i = 0
     while 1:
         name = net_prefix + str(i)
         if name not in used_eths:
             LOG.debug(_("Available net name ==> %s"), name)
             return name
         i += 1
Beispiel #54
0
    def _require_attributes(self, ref, attrs):
        """Ensures the reference contains the specified attributes.

        Raise a ValidationError if any of the given attributes is not present
        """
        missing_attrs = [attribute for attribute in attrs
                         if self._attribute_is_empty(ref, attribute)]

        if missing_attrs:
            msg = _('%s field(s) cannot be empty') % ', '.join(missing_attrs)
            raise exception.ValidationError(message=msg)
Beispiel #55
0
def teardown_network(container_id):
    try:
        output, err = utils.execute('ip', '-o', 'netns', 'list')
        for line in output.split('\n'):
            if container_id == line.strip():
                utils.execute('ip', 'netns', 'delete', container_id,
                              run_as_root=True)
                break
    except processutils.ProcessExecutionError:
        LOG.warning(_('Cannot remove network namespace, netns id: %s'),
                    container_id)
Beispiel #56
0
 def start(self, name, network_info=None, block_device_info=None, timeout=10):
     # Start the container
     try:
         self.add_interfaces(name, network_info, append=False)
         utils.execute('lxc-start', '-n', name, '-d', '-l', 'DEBUG')
         utils.execute('lxc-wait', '-n', name, '-s', 'RUNNING', '-t', timeout)
     except Exception as ex:
         with excutils.save_and_reraise_exception():
             LOG.error(_('Failed to start container'
                           ' for %(name)s: %(ex)s'),
                       {'name': name, 'ex': ex.message})
Beispiel #57
0
 def stop(self, name, timeout):
     containers = self.list()
     status = [c['status'] for c in containers if c['name'] == name]or ['']
     if status and status[0] != 'RUNNING':
         return "Container {} is {}, can't stop it".format(name, status[0])
     try:
         utils.execute('lxc-stop', '-n', name, '-t', timeout)
     except Exception as ex:
         with excutils.save_and_reraise_exception():
             LOG.error(_('Failed to stop container'
                           ' for %(name)s: %(ex)s'),
                       {'name': name, 'ex': ex.message})