Example #1
0
    def _started(self, what, notify=None):
        """
        This is the second step::
        Wait for the StartNotify thread to finish and then check for the
        status of pidfile/procname using pgrep

        Returns:
            True whether the service is alive, False otherwise
        """

        if what in self.SERVICE_DEFS:
            procname, pidfile = self.SERVICE_DEFS[what]
            if notify:
                notify.join()

            if pidfile:
                pgrep = "/bin/pgrep -F {}{}".format(
                    pidfile,
                    ' ' + procname if procname else '',
                )
            else:
                pgrep = "/bin/pgrep {}".format(procname)
            proc = Popen(pgrep, shell=True, stdout=PIPE, stderr=PIPE, close_fds=True)
            data = proc.communicate()[0]

            if proc.returncode == 0:
                return True, [
                    int(i)
                    for i in data.strip().split('\n') if i.isdigit()
                ]
        return False, []
Example #2
0
    def get_data(self, data):
        """
        Get data points from rrd files.
        """

        rrdfile = '{}/{}/{}.rrd'.format(RRD_PATH, data['source'], data['type'])
        proc = Popen(
            [
                'rrdtool',
                'xport',
                '--json',
                '--start',
                data['start'],
                '--end',
                data['end'],
            ] + (['--step', str(data['step'])] if data.get('step') else []) + [
                'DEF:xxx={}:{}:{}'.format(rrdfile, data['dataset'],
                                          data['cf']),
                'XPORT:xxx',
            ],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        data, err = proc.communicate()
        if proc.returncode != 0:
            raise ValueError('rrdtool failed: {}'.format(err))
        return json.loads(data)
Example #3
0
    def sync(self):
        domain = None
        nameservers = []

        if self.middleware.call('notifier.common', 'system', 'domaincontroller_enabled'):
            cifs = self.middlware.call('datastore.query', 'services.cifs', None, {'get': True})
            dc = self.middleware.call('datastore.query', 'services.DomainController', None, {'get': True})
            domain = dc['dc_realm']
            if cifs['cifs_srv_bindip']:
                for ip in cifs['cifs_srv_bindip']:
                    nameservers.append(ip)
            else:
                nameservers.append('127.0.0.1')
        else:
            gc = self.middleware.call('datastore.query', 'network.globalconfiguration', None, {'get': True})
            if gc['gc_domain']:
                domain = gc['gc_domain']
            if gc['gc_nameserver1']:
                nameservers.append(gc['gc_nameserver1'])
            if gc['gc_nameserver2']:
                nameservers.append(gc['gc_nameserver2'])
            if gc['gc_nameserver3']:
                nameservers.append(gc['gc_nameserver3'])

        resolvconf = ''
        if domain:
            resolvconf += 'search {}\n'.format(domain)
        for ns in nameservers:
            resolvconf += 'nameserver {}\n'.format(ns)

        proc = Popen([
            '/sbin/resolvconf', '-a', 'lo0'
        ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        proc.communicate(input=resolvconf)
Example #4
0
    def sync(self):
        domain = None
        nameservers = []

        if self.middleware.call('notifier.common', 'system', 'domaincontroller_enabled'):
            cifs = self.middleware.call('datastore.query', 'services.cifs', None, {'get': True})
            dc = self.middleware.call('datastore.query', 'services.DomainController', None, {'get': True})
            domain = dc['dc_realm']
            if cifs['cifs_srv_bindip']:
                for ip in cifs['cifs_srv_bindip']:
                    nameservers.append(ip)
            else:
                nameservers.append('127.0.0.1')
        else:
            gc = self.middleware.call('datastore.query', 'network.globalconfiguration', None, {'get': True})
            if gc['gc_domain']:
                domain = gc['gc_domain']
            if gc['gc_nameserver1']:
                nameservers.append(gc['gc_nameserver1'])
            if gc['gc_nameserver2']:
                nameservers.append(gc['gc_nameserver2'])
            if gc['gc_nameserver3']:
                nameservers.append(gc['gc_nameserver3'])

        resolvconf = ''
        if domain:
            resolvconf += 'search {}\n'.format(domain)
        for ns in nameservers:
            resolvconf += 'nameserver {}\n'.format(ns)

        proc = Popen([
            '/sbin/resolvconf', '-a', 'lo0'
        ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        proc.communicate(input=resolvconf)
Example #5
0
    def get_dataset_info(self, source, name):
        """
        Returns info about a given dataset from some source.
        """
        rrdfile = '{}/{}/{}.rrd'.format(RRD_PATH, source, name)
        proc = Popen(
            ['rrdtool', 'info', rrdfile],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        data, err = proc.communicate()
        if proc.returncode != 0:
            raise ValueError('rrdtool failed: {}'.format(err))

        info = {'data_sources': {}}
        for data_source, _type in RE_DSTYPE.findall(data):
            info['data_sources'][data_source] = {'type': _type}

        reg = RE_STEP.search(data)
        if reg:
            info['step'] = int(reg.group(1))
        reg = RE_LAST_UPDATE.search(data)
        if reg:
            info['last_update'] = int(reg.group(1))
        return info
Example #6
0
 def dhclient_start(self, interface):
     proc = Popen([
         '/sbin/dhclient', '-b', interface,
     ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
     output = proc.communicate()[0]
     if proc.returncode != 0:
         self.logger.error('Failed to run dhclient on {}: {}'.format(
             interface, output,
         ))
Example #7
0
 def dhclient_start(self, interface):
     proc = Popen([
         '/sbin/dhclient', '-b', interface,
     ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
     output = proc.communicate()[0]
     if proc.returncode != 0:
         self.logger.error('Failed to run dhclient on {}: {}'.format(
             interface, output,
         ))
Example #8
0
    def run(self, queue):
        """
        Run a Job and set state/result accordingly.
        This method is supposed to run in a greenlet.
        """

        try:
            self.set_state('RUNNING')
            """
            If job is flagged as process a new process is spawned
            with the job id which will in turn run the method
            and return the result as a json
            """
            if self.options.get('process'):
                proc = Popen([
                    '/usr/bin/env',
                    'python3',
                    os.path.join(
                        os.path.dirname(os.path.realpath(__file__)),
                        'job_process.py',
                    ),
                    str(self.id),
                ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True,
                    env={
                    'LOGNAME': 'root',
                    'USER': '******',
                    'GROUP': 'wheel',
                    'HOME': '/root',
                    'PATH': '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin',
                    'TERM': 'xterm',
                })
                output = proc.communicate()
                try:
                    data = json.loads(output[0])
                except ValueError:
                    self.set_state('FAILED')
                    self.error = 'Running job has failed.\nSTDOUT: {}\nSTDERR: {}'.format(output[0], output[1])
                else:
                    if proc.returncode != 0:
                        self.set_state('FAILED')
                        self.error = data['error']
                        self.exception = data['exception']
                    else:
                        self.set_result(data)
                        self.set_state('SUCCESS')
            else:
                self.set_result(self.method(*([self] + self.args)))
                self.set_state('SUCCESS')
        except:
            self.set_state('FAILED')
            self.set_exception(sys.exc_info())
            raise
        finally:
            queue.release_lock(self)
            self._finished.set()
            self.middleware.send_event('core.get_jobs', 'CHANGED', id=self.id, fields=self.__encode__())
Example #9
0
 def ssh_keyscan(self, host, port):
     proc = Popen(
         ["/usr/bin/ssh-keyscan", "-p", str(port), "-T", "2", str(host)],
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE,
     )
     key, errmsg = proc.communicate()
     if proc.returncode != 0 or not key:
         if not errmsg:
             errmsg = "ssh key scan failed for unknown reason"
         raise ValueError(errmsg)
     return key
Example #10
0
 def ssh_keyscan(self, host, port):
     proc = Popen([
         "/usr/bin/ssh-keyscan",
         "-p", str(port),
         "-T", "2",
         str(host),
     ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     key, errmsg = proc.communicate()
     if proc.returncode != 0 or not key:
         if not errmsg:
             errmsg = 'ssh key scan failed for unknown reason'
         raise ValueError(errmsg)
     return key
Example #11
0
    def _system(self, cmd, options=None):
        stdout = PIPE
        if options and 'stdout' in options:
            stdout = options['stdout']
        stderr = PIPE
        if options and 'stderr' in options:
            stderr = options['stderr']

        proc = Popen(cmd,
                     stdout=stdout,
                     stderr=stderr,
                     shell=True,
                     close_fds=True)
        proc.communicate()
        return proc.returncode
Example #12
0
 def info(self):
     """
     Returns basic system information.
     """
     uptime = Popen(
         "env -u TZ uptime | awk -F', load averages:' '{ print $1 }'",
         stdout=subprocess.PIPE,
         shell=True,
     ).communicate()[0].strip()
     return {
         'version':
         self.version(),
         'hostname':
         socket.gethostname(),
         'physmem':
         sysctl.filter('hw.physmem')[0].value,
         'model':
         sysctl.filter('hw.model')[0].value,
         'loadavg':
         os.getloadavg(),
         'uptime':
         uptime,
         'boottime':
         datetime.fromtimestamp(
             struct.unpack('l',
                           sysctl.filter('kern.boottime')[0].value[:8])[0]),
     }
Example #13
0
    def reboot(self, job, options=None):
        """
        Reboots the operating system.

        Emits an "added" event of name "system" and id "reboot".
        """
        if options is None:
            options = {}

        self.middleware.send_event('system',
                                   'ADDED',
                                   id='reboot',
                                   fields={
                                       'description':
                                       'System is going to reboot',
                                   })

        delay = options.get('delay')
        if delay:
            time.sleep(delay)

        Popen(["/sbin/reboot"])
Example #14
0
    def shutdown(self, job, options=None):
        """
        Shuts down the operating system.

        Emits an "added" event of name "system" and id "shutdown".
        """
        if options is None:
            options = {}

        self.middleware.send_event('system',
                                   'ADDED',
                                   id='shutdown',
                                   fields={
                                       'description':
                                       'System is going to shutdown',
                                   })

        delay = options.get('delay')
        if delay:
            time.sleep(delay)

        Popen(["/sbin/poweroff"])
Example #15
0
    def sync(self, job, backup, credential):
        # Use a temporary file to store s3cmd config file
        with tempfile.NamedTemporaryFile() as f:
            # Make sure only root can read it ad there is sensitive data
            os.chmod(f.name, 0o600)

            fg = gevent.fileobject.FileObject(f.file, 'w', close=False)
            fg.write("""[remote]
type = s3
env_auth = false
access_key_id = {access_key}
secret_access_key = {secret_key}
region = {region}
""".format(
                access_key=credential['attributes']['access_key'],
                secret_key=credential['attributes']['secret_key'],
                region=backup['attributes']['region'] or '',
            ))
            fg.flush()

            args = [
                '/usr/local/bin/rclone',
                '--config', f.name,
                '--stats', '1s',
                'sync',
            ]

            remote_path = 'remote:{}{}'.format(
                backup['attributes']['bucket'],
                '/{}'.format(backup['attributes']['folder']) if backup['attributes'].get('folder') else '',
            )

            if backup['direction'] == 'PUSH':
                args.extend([backup['path'], remote_path])
            else:
                args.extend([remote_path, backup['path']])

            def check_progress(job, proc):
                RE_TRANSF = re.compile(r'Transferred:\s*?(.+)$', re.S)
                read_buffer = ''
                while True:
                    read = proc.stderr.readline()
                    if read == '':
                        break
                    read_buffer += read
                    if len(read_buffer) > 10240:
                        read_buffer = read_buffer[-10240:]
                    reg = RE_TRANSF.search(read)
                    if reg:
                        transferred = reg.group(1).strip()
                        if not transferred.isdigit():
                            job.set_progress(None, transferred)
                return read_buffer

            proc = Popen(
                args,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            check_greenlet = gevent.spawn(check_progress, job, proc)
            proc.communicate()
            if proc.returncode != 0:
                gevent.joinall([check_greenlet])
                raise ValueError('rclone failed: {}'.format(check_greenlet.value))
            return True
Example #16
0
 def _system(self, cmd):
     proc = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True, close_fds=True)
     proc.communicate()
     return proc.returncode
Example #17
0
    def sync_interface(self, name):
        try:
            data = self.middleware.call('datastore.query',
                                        'network.interfaces',
                                        [('int_interface', '=', name)],
                                        {'get': True})
        except IndexError:
            self.logger.info('{} is not in interfaces database'.format(name))
            return

        aliases = self.middleware.call(
            'datastore.query', 'network.alias',
            [('alias_interface_id', '=', data['id'])])

        iface = netif.get_interface(name)

        addrs_database = set()
        addrs_configured = set(
            [a for a in iface.addresses if a.af != netif.AddressFamily.LINK])

        has_ipv6 = data['int_ipv6auto'] or False

        if (not self.middleware.call('system.is_freenas')
                and self.middleware.call('notifier.failover_node') == 'B'):
            ipv4_field = 'int_ipv4address_b'
            ipv6_field = 'int_ipv6address'
            alias_ipv4_field = 'alias_v4address_b'
            alias_ipv6_field = 'alias_v6address_b'
        else:
            ipv4_field = 'int_ipv4address'
            ipv6_field = 'int_ipv6address'
            alias_ipv4_field = 'alias_v4address'
            alias_ipv6_field = 'alias_v6address'

        dhclient_running, dhclient_pid = dhclient_status(name)
        if dhclient_running and data['int_dhcp']:
            leases = dhclient_leases(name)
            if leases:
                reg_address = re.search(r'fixed-address\s+(.+);', leases)
                reg_netmask = re.search(r'option subnet-mask\s+(.+);', leases)
                if reg_address and reg_netmask:
                    addrs_database.add(
                        self.alias_to_addr({
                            'address': reg_address.group(1),
                            'netmask': reg_netmask.group(1),
                        }))
                else:
                    self.logger.info('Unable to get address from dhclient')
            if data[ipv6_field] and has_ipv6 is False:
                addrs_database.add(
                    self.alias_to_addr({
                        'address': data[ipv6_field],
                        'netmask': data['int_v6netmaskbit'],
                    }))
        else:
            if data[ipv4_field]:
                addrs_database.add(
                    self.alias_to_addr({
                        'address': data[ipv4_field],
                        'netmask': data['int_v4netmaskbit'],
                    }))
            if data[ipv6_field] and has_ipv6 is False:
                addrs_database.add(
                    self.alias_to_addr({
                        'address': data[ipv6_field],
                        'netmask': data['int_v6netmaskbit'],
                    }))
                has_ipv6 = True

        carp_vhid = carp_pass = None
        if data['int_vip']:
            addrs_database.add(
                self.alias_to_addr({
                    'address': data['int_vip'],
                    'netmask': '32',
                    'vhid': data['int_vhid'],
                }))
            carp_vhid = data['int_vhid']
            carp_pass = data['int_pass'] or None

        for alias in aliases:
            if alias[alias_ipv4_field]:
                addrs_database.add(
                    self.alias_to_addr({
                        'address': alias[alias_ipv4_field],
                        'netmask': alias['alias_v4netmaskbit'],
                    }))
            if alias[alias_ipv6_field]:
                addrs_database.add(
                    self.alias_to_addr({
                        'address': alias[alias_ipv6_field],
                        'netmask': alias['alias_v6netmaskbit'],
                    }))

            if alias['alias_vip']:
                addrs_database.add(
                    self.alias_to_addr({
                        'address': alias['alias_vip'],
                        'netmask': '32',
                        'vhid': data['int_vhid'],
                    }))

        if carp_vhid:
            advskew = None
            for cc in iface.carp_config:
                if cc.vhid == carp_vhid:
                    advskew = cc.advskew
                    break

        if has_ipv6:
            iface.nd6_flags = iface.nd6_flags - {
                netif.NeighborDiscoveryFlags.IFDISABLED
            }
            iface.nd6_flags = iface.nd6_flags | {
                netif.NeighborDiscoveryFlags.AUTO_LINKLOCAL
            }
        else:
            iface.nd6_flags = iface.nd6_flags | {
                netif.NeighborDiscoveryFlags.IFDISABLED
            }
            iface.nd6_flags = iface.nd6_flags - {
                netif.NeighborDiscoveryFlags.AUTO_LINKLOCAL
            }

        # Remove addresses configured and not in database
        for addr in (addrs_configured - addrs_database):
            if has_ipv6 and str(addr.address).startswith('fe80::'):
                continue
            self.logger.debug('{}: removing {}'.format(name, addr))
            iface.remove_address(addr)

        # carp must be configured after removing addresses
        # in case removing the address removes the carp
        if carp_vhid:
            if not self.middleware.call('notifier.is_freenas') and not advskew:
                if self.middleware.call('notifier.failover_node') == 'A':
                    advskew = 20
                else:
                    advskew = 80
            iface.carp_config = [
                netif.CarpConfig(carp_vhid, advskew=advskew, key=carp_pass)
            ]

        # Add addresses in database and not configured
        for addr in (addrs_database - addrs_configured):
            self.logger.debug('{}: adding {}'.format(name, addr))
            iface.add_address(addr)

        # Apply interface options specified in GUI
        if data['int_options']:
            self.logger.info('{}: applying {}'.format(name,
                                                      data['int_options']))
            proc = Popen('/sbin/ifconfig {} {}'.format(name,
                                                       data['int_options']),
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         close_fds=True)
            err = proc.communicate()[1]
            if err:
                self.logger.info('{}: error applying: {}'.format(name, err))

            # In case there is no MTU in interface options and it is currently
            # different than the default of 1500, revert it
            if data['int_options'].find('mtu') == -1 and iface.mtu != 1500:
                iface.mtu = 1500

        if netif.InterfaceFlags.UP not in iface.flags:
            iface.up()

        # If dhclient is not running and dhcp is configured, lets start it
        if not dhclient_running and data['int_dhcp']:
            self.logger.debug('Starting dhclient for {}'.format(name))
            gevent.spawn(self.dhclient_start, data['int_interface'])
        elif dhclient_running and not data['int_dhcp']:
            self.logger.debug('Killing dhclient for {}'.format(name))
            os.kill(dhclient_pid, signal.SIGTERM)

        if data['int_ipv6auto']:
            iface.nd6_flags = iface.nd6_flags | {
                netif.NeighborDiscoveryFlags.ACCEPT_RTADV
            }
            Popen(
                ['/etc/rc.d/rtsold', 'onestart'],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                close_fds=True,
            ).wait()
        else:
            iface.nd6_flags = iface.nd6_flags - {
                netif.NeighborDiscoveryFlags.ACCEPT_RTADV
            }
Example #18
0
    def sync_interface(self, name):
        try:
            data = self.middleware.call('datastore.query', 'network.interfaces', [('int_interface', '=', name)], {'get': True})
        except IndexError:
            self.logger.info('{} is not in interfaces database'.format(name))
            return

        aliases = self.middleware.call('datastore.query', 'network.alias', [('alias_interface_id', '=', data['id'])])

        iface = netif.get_interface(name)

        addrs_database = set()
        addrs_configured = set([
            a for a in iface.addresses
            if a.af != netif.AddressFamily.LINK
        ])

        has_ipv6 = data['int_ipv6auto'] or False

        if (
            not self.middleware.call('system.is_freenas') and
            self.middleware.call('notifier.failover_node') == 'B'
        ):
            ipv4_field = 'int_ipv4address_b'
            ipv6_field = 'int_ipv6address'
            alias_ipv4_field = 'alias_v4address_b'
            alias_ipv6_field = 'alias_v6address_b'
        else:
            ipv4_field = 'int_ipv4address'
            ipv6_field = 'int_ipv6address'
            alias_ipv4_field = 'alias_v4address'
            alias_ipv6_field = 'alias_v6address'

        dhclient_running, dhclient_pid = dhclient_status(name)
        if dhclient_running and data['int_dhcp']:
            leases = dhclient_leases(name)
            if leases:
                reg_address = re.search(r'fixed-address\s+(.+);', leases)
                reg_netmask = re.search(r'option subnet-mask\s+(.+);', leases)
                if reg_address and reg_netmask:
                    addrs_database.add(self.alias_to_addr({
                        'address': reg_address.group(1),
                        'netmask': reg_netmask.group(1),
                    }))
                else:
                    self.logger.info('Unable to get address from dhclient')
        else:
            if data[ipv4_field]:
                addrs_database.add(self.alias_to_addr({
                    'address': data[ipv4_field],
                    'netmask': data['int_v4netmaskbit'],
                }))
            if data[ipv6_field]:
                addrs_database.add(self.alias_to_addr({
                    'address': data[ipv6_field],
                    'netmask': data['int_v6netmaskbit'],
                }))
                has_ipv6 = True

        carp_vhid = carp_pass = None
        if data['int_vip']:
            addrs_database.add(self.alias_to_addr({
                'address': data['int_vip'],
                'netmask': '32',
                'vhid': data['int_vhid'],
            }))
            carp_vhid = data['int_vhid']
            carp_pass = data['int_pass'] or None

        for alias in aliases:
            if alias[alias_ipv4_field]:
                addrs_database.add(self.alias_to_addr({
                    'address': alias[alias_ipv4_field],
                    'netmask': alias['alias_v4netmaskbit'],
                }))
            if alias[alias_ipv6_field]:
                addrs_database.add(self.alias_to_addr({
                    'address': alias[alias_ipv6_field],
                    'netmask': alias['alias_v6netmaskbit'],
                }))
                has_ipv6 = True

            if alias['alias_vip']:
                addrs_database.add(self.alias_to_addr({
                    'address': alias['alias_vip'],
                    'netmask': '32',
                    'vhid': data['int_vhid'],
                }))

        if has_ipv6:
            iface.nd6_flags = iface.nd6_flags - {netif.NeighborDiscoveryFlags.IFDISABLED}
            iface.nd6_flags = iface.nd6_flags | {netif.NeighborDiscoveryFlags.AUTO_LINKLOCAL}
        else:
            iface.nd6_flags = iface.nd6_flags | {netif.NeighborDiscoveryFlags.IFDISABLED}
            iface.nd6_flags = iface.nd6_flags - {netif.NeighborDiscoveryFlags.AUTO_LINKLOCAL}

        # Remove addresses configured and not in database
        for addr in (addrs_configured - addrs_database):
            if (
                addr.af == netif.AddressFamily.INET6 and
                str(addr.address).startswith('fe80::')
            ):
                continue
            self.logger.debug('{}: removing {}'.format(name, addr))
            iface.remove_address(addr)

        # carp must be configured after removing addresses
        # in case removing the address removes the carp
        if carp_vhid:
            advskew = None
            if not self.middleware.call('notifier.is_freenas'):
                if self.middleware.call('notifier.failover_status') == 'MASTER':
                    advskew = 20
                else:
                    advskew = 80
            iface.carp_config = [netif.CarpConfig(carp_vhid, advskew=advskew, key=carp_pass)]

        # Add addresses in database and not configured
        for addr in (addrs_database - addrs_configured):
            self.logger.debug('{}: adding {}'.format(name, addr))
            iface.add_address(addr)

        # Apply interface options specified in GUI
        if data['int_options']:
            self.logger.info('{}: applying {}'.format(name, data['int_options']))
            proc = Popen('/sbin/ifconfig {} {}'.format(name, data['int_options']), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
            err = proc.communicate()[1]
            if err:
                self.logger.info('{}: error applying: {}'.format(name, err))

            # In case there is no MTU in interface options and it is currently
            # different than the default of 1500, revert it
            if data['int_options'].find('mtu') == -1 and iface.mtu != 1500:
                iface.mtu = 1500

        if netif.InterfaceFlags.UP not in iface.flags:
            iface.up()

        # If dhclient is not running and dhcp is configured, lets start it
        if not dhclient_running and data['int_dhcp']:
            self.logger.debug('Starting dhclient for {}'.format(name))
            gevent.spawn(self.dhclient_start, data['int_interface'])
        elif dhclient_running and not data['int_dhcp']:
            self.logger.debug('Killing dhclient for {}'.format(name))
            os.kill(dhclient_pid, signal.SIGTERM)

        if data['int_ipv6auto']:
            iface.nd6_flags = iface.nd6_flags | {netif.NeighborDiscoveryFlags.ACCEPT_RTADV}
            Popen(
                ['/etc/rc.d/rtsold', 'onestart'],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                close_fds=True,
            ).wait()
        else:
            iface.nd6_flags = iface.nd6_flags - {netif.NeighborDiscoveryFlags.ACCEPT_RTADV}
Example #19
0
def kmod_load():
    kldstat = Popen(['/sbin/kldstat'], stdout=subprocess.PIPE).communicate()[0]
    if 'vmm.ko' not in kldstat:
        Popen(['/sbin/kldload', 'vmm'])
    if 'nmdm.ko' not in kldstat:
        Popen(['/sbin/kldload', 'nmdm'])
Example #20
0
    def run(self):
        args = [
            'bhyve',
            '-A',
            '-P',
            '-H',
            '-c', str(self.vm['vcpus']),
            '-m', str(self.vm['memory']),
            '-s', '0:0,hostbridge',
            '-s', '31,lpc',
            '-l', 'com1,/dev/nmdm{}A'.format(self.vm['id']),
        ]

        if self.vm['bootloader'] in ('UEFI', 'UEFI_CSM'):
            args += [
                '-l', 'bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI{}.fd'.format('_CSM' if self.vm['bootloader'] == 'UEFI_CSM' else ''),
            ]

        nid = Nid(3)
        for device in self.vm['devices']:
            if device['dtype'] == 'DISK':
                if device['attributes'].get('mode') == 'AHCI':
                    args += ['-s', '{},ahci-hd,{}'.format(nid(), device['attributes']['path'])]
                else:
                    args += ['-s', '{},virtio-blk,{}'.format(nid(), device['attributes']['path'])]
            elif device['dtype'] == 'CDROM':
                args += ['-s', '{},ahci-cd,{}'.format(nid(), device['attributes']['path'])]
            elif device['dtype'] == 'NIC':
                tapname = netif.create_interface('tap')
                tap = netif.get_interface(tapname)
                tap.up()
                self.taps.append(tapname)
                # If Bridge
                if True:
                    bridge = None
                    for name, iface in netif.list_interfaces().items():
                        if name.startswith('bridge'):
                            bridge = iface
                            break
                    if not bridge:
                        bridge = netif.get_interface(netif.create_interface('bridge'))
                    bridge.add_member(tapname)

                    defiface = Popen("route -nv show default|grep -w interface|awk '{ print $2 }'", stdout=subprocess.PIPE, shell=True).communicate()[0].strip()
                    if defiface and defiface not in bridge.members:
                        bridge.add_member(defiface)
                    bridge.up()
                if device['attributes'].get('type') == 'VIRTIO':
                    nictype = 'virtio-net'
                else:
                    nictype = 'e1000'
                args += ['-s', '{},{},{}'.format(nid(), nictype, tapname)]
            elif device['dtype'] == 'VNC':
                if device['attributes'].get('wait'):
                    wait = 'wait'
                else:
                    wait = ''
                args += [
                    '-s', '29,fbuf,tcp=0.0.0.0:{},w=1024,h=768,{}'.format(5900 + self.vm['id'], wait),
                    '-s', '30,xhci,tablet',
                ]

        args.append(self.vm['name'])

        self.logger.debug('Starting bhyve: {}'.format(' '.join(args)))
        self.proc = Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        for line in self.proc.stdout:
            self.logger.debug('{}: {}'.format(self.vm['name'], line))

        self.proc.wait()

        self.logger.info('Destroying {}'.format(self.vm['name']))

        Popen(['bhyvectl', '--destroy', '--vm={}'.format(self.vm['name'])], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()

        while self.taps:
            netif.destroy_interface(self.taps.pop())

        self.manager._vm.pop(self.vm['id'], None)