示例#1
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})
示例#2
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})
示例#3
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})
示例#4
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})
示例#5
0
def bridge_exists(bridge_name):
    try:
        _ovs_vsctl(['br-exists', bridge_name])
    except RuntimeError as e:
        with excutils.save_and_reraise_exception() as ctxt:
            if 'Exit code: 2\n' in str(e):
                ctxt.reraise = False
                return False
    return True
示例#6
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)
示例#7
0
def bridge_exists(bridge_name):
    try:
        _ovs_vsctl(['br-exists', bridge_name])
    except RuntimeError as e:
        with excutils.save_and_reraise_exception() as ctxt:
            if 'Exit code: 2\n' in str(e):
                ctxt.reraise = False
                return False
    return True
示例#8
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)
示例#9
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)
示例#10
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)
示例#11
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})
示例#12
0
    def rollback_and_reraise(self, msg=None, **kwargs):
        """Rollback a series of actions then re-raise the exception.

        .. note:: (sirp) This should only be called within an
                  exception handler.
        """
        with excutils.save_and_reraise_exception():
            if msg:
                LOG.exception(msg, **kwargs)

            self._rollback()
示例#13
0
    def rollback_and_reraise(self, msg=None, **kwargs):
        """Rollback a series of actions then re-raise the exception.

        .. note:: (sirp) This should only be called within an
                  exception handler.
        """
        with excutils.save_and_reraise_exception():
            if msg:
                LOG.exception(msg, **kwargs)

            self._rollback()
示例#14
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})
示例#15
0
    def destroy(self, name, network_info):
        """Destroy the instance on the LXD host

        """
        try:
            utils.execute('lxc-destroy', '-f', '-n', name)
            LOG.info('Destroyed for %s' %name)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                LOG.error(_('Failed to remove container'
                              ' for %(name)s: %(ex)s'),
                          {'name': name, 'ex': ex.message})
示例#16
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})
示例#17
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})
示例#18
0
    def destroy(self, name, network_info):
        """Destroy the instance on the LXD host

        """
        try:
            utils.execute('lxc-destroy', '-f', '-n', name)
            LOG.info('Destroyed for %s' %name)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                LOG.error(_('Failed to remove container'
                              ' for %(name)s: %(ex)s'),
                          {'name': name, 'ex': ex.message})
示例#19
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})
示例#20
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})
示例#21
0
def robust_file_write(directory, filename, data):
    """Robust file write.

    Use "write to temp file and rename" model for writing the
    persistence file.

    :param directory: Target directory to create a file.
    :param filename: File name to store specified data.
    :param data: String data.
    """
    tempname = None
    dirfd = None
    try:
        dirfd = os.open(directory, os.O_DIRECTORY)

        # write data to temporary file
        with tempfile.NamedTemporaryFile(prefix=filename,
                                         dir=directory,
                                         delete=False) as tf:
            tempname = tf.name
            tf.write(data.encode('utf-8'))
            tf.flush()
            os.fdatasync(tf.fileno())
            tf.close()

            # Fsync the directory to ensure the fact of the existence of
            # the temp file hits the disk.
            os.fsync(dirfd)
            # If destination file exists, it will be replaced silently.
            os.rename(tempname, os.path.join(directory, filename))
            # Fsync the directory to ensure the rename hits the disk.
            os.fsync(dirfd)
    except OSError:
        with excutils.save_and_reraise_exception():
            LOG.error(_LE("Failed to write persistence file: %(path)s."),
                      {'path': os.path.join(directory, filename)})
            if os.path.isfile(tempname):
                os.unlink(tempname)
    finally:
        if dirfd:
            os.close(dirfd)
示例#22
0
    def start(self):
        """Start serving a WSGI application.

        :returns: None
        """
        # The server socket object will be closed after server exits,
        # but the underlying file descriptor will remain open, and will
        # give bad file descriptor error. So duplicating the socket object,
        # to keep file descriptor usable.

        dup_socket = self._socket.dup()
        if self._use_ssl:
            try:
                ca_file = CONF.ssl_ca_file
                cert_file = CONF.ssl_cert_file
                key_file = CONF.ssl_key_file

                if cert_file and not os.path.exists(cert_file):
                    raise RuntimeError(
                          _("Unable to find cert_file : %s") % cert_file)

                if ca_file and not os.path.exists(ca_file):
                    raise RuntimeError(
                          _("Unable to find ca_file : %s") % ca_file)

                if key_file and not os.path.exists(key_file):
                    raise RuntimeError(
                          _("Unable to find key_file : %s") % key_file)

                if self._use_ssl and (not cert_file or not key_file):
                    raise RuntimeError(
                          _("When running server in SSL mode, you must "
                            "specify both a cert_file and key_file "
                            "option value in your configuration file"))
                ssl_kwargs = {
                    'server_side': True,
                    'certfile': cert_file,
                    'keyfile': key_file,
                    'cert_reqs': ssl.CERT_NONE,
                }

                if CONF.ssl_ca_file:
                    ssl_kwargs['ca_certs'] = ca_file
                    ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED

                dup_socket = eventlet.wrap_ssl(dup_socket,
                                               **ssl_kwargs)

                dup_socket.setsockopt(socket.SOL_SOCKET,
                                      socket.SO_REUSEADDR, 1)
                # sockets can hang around forever without keepalive
                dup_socket.setsockopt(socket.SOL_SOCKET,
                                      socket.SO_KEEPALIVE, 1)

                # This option isn't available in the OS X version of eventlet
                if hasattr(socket, 'TCP_KEEPIDLE'):
                    dup_socket.setsockopt(socket.IPPROTO_TCP,
                                    socket.TCP_KEEPIDLE,
                                    CONF.tcp_keepidle)

            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.error(_("Failed to start %(name)s on %(host)s"
                                ":%(port)s with SSL support"),
                              {'name': self.name, 'host': self.host,
                               'port': self.port})

        wsgi_kwargs = {
            'func': eventlet.wsgi.server,
            'sock': dup_socket,
            'site': self.app,
            'protocol': self._protocol,
            'custom_pool': self._pool,
            'log': self._wsgi_logger,
            'log_format': CONF.wsgi_log_format,
            'debug': False,
            'keepalive': CONF.wsgi_keep_alive,
            'socket_timeout': self.client_socket_timeout
            }

        if self._max_url_len:
            wsgi_kwargs['url_length_limit'] = self._max_url_len

        self._server = eventlet.spawn(**wsgi_kwargs)