Example #1
0
def main(argv=sys.argv[1:]):
    parser = argparse.ArgumentParser(
        prog='VirtualBMC server',
        description='A virtual BMC server for controlling virtual instances',
    )
    parser.add_argument('--version', action='version',
                        version=virtualbmc.__version__)
    parser.add_argument('--foreground',
                        action='store_true',
                        default=False,
                        help='Do not daemonize')

    args = parser.parse_args(argv)

    pid_file = CONF['default']['pid_file']

    try:
        with open(pid_file) as f:
            pid = int(f.read())

        os.kill(pid, 0)

    except Exception:
        pass

    else:
        LOG.error('server PID #%(pid)d still running', {'pid': pid})
        return 1

    def wrap_with_pidfile(func, pid):
        dir_name = os.path.dirname(pid_file)

        if not os.path.exists(dir_name):
            os.makedirs(dir_name, mode=0o700)

        try:
            with tempfile.NamedTemporaryFile(mode='w+t', dir=dir_name,
                                             delete=False) as f:
                f.write(str(pid))
                os.rename(f.name, pid_file)

            func()

        except Exception as e:
            LOG.error('%(error)s', {'error': e})
            return 1

        finally:
            try:
                os.unlink(pid_file)

            except Exception:
                pass

    if args.foreground:
        return wrap_with_pidfile(control.application, os.getpid())
    else:
        with utils.detach_process() as pid:
            return wrap_with_pidfile(control.application, pid)
Example #2
0
    def start(self, domain_name):
        domain_path = os.path.join(self.config_dir, domain_name)
        if not os.path.exists(domain_path):
            raise exception.DomainNotFound(domain=domain_name)

        bmc_config = self._parse_config(domain_name)

        # check libvirt's connection and domain prior to starting the BMC
        utils.check_libvirt_connection_and_domain(
            bmc_config['libvirt_uri'],
            domain_name,
            sasl_username=bmc_config['libvirt_sasl_username'],
            sasl_password=bmc_config['libvirt_sasl_password'])

        # mask the passwords if requested
        log_config = bmc_config.copy()
        if not CONF['default']['show_passwords']:
            log_config = utils.mask_dict_password(bmc_config)

        LOG.debug(
            'Starting a Virtual BMC for domain %(domain)s with the '
            'following configuration options: %(config)s', {
                'domain':
                domain_name,
                'config':
                ' '.join(['%s="%s"' % (k, log_config[k]) for k in log_config])
            })

        with utils.detach_process() as pid_num:
            try:
                vbmc = VirtualBMC(**bmc_config)
            except Exception as e:
                msg = ('Error starting a Virtual BMC for domain %(domain)s. '
                       'Error: %(error)s' % {
                           'domain': domain_name,
                           'error': e
                       })
                LOG.error(msg)
                raise exception.VirtualBMCError(msg)

            # Save the PID number
            pidfile_path = os.path.join(domain_path, 'pid')
            with open(pidfile_path, 'w') as f:
                f.write(str(pid_num))

            LOG.info('Virtual BMC for domain %s started', domain_name)
            vbmc.listen(timeout=CONF['ipmi']['session_timeout'])
Example #3
0
    def test_detach_process(self, mock_os):

        # 2nd value > 0 so _exit get called and we can assert that we've
        # killed the parent's process
        mock_os.fork.side_effect = (0, 999)
        mock_os.devnull = os.devnull

        with utils.detach_process() as pid:
            self.assertEqual(0, pid)

        # assert fork() has been called twice
        expected_fork_calls = [mock.call()] * 2
        self.assertEqual(expected_fork_calls, mock_os.fork.call_args_list)

        mock_os.setsid.assert_called_once_with()
        mock_os.chdir.assert_called_once_with('/')
        mock_os.umask.assert_called_once_with(0)
        mock_os._exit.assert_called_once_with(0)