【Ovirt 笔记】ovirt-engine 服务的实现原理

文前说明

作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。

分析整理的版本为 Ovirt 3.4.5 版本。

命令使用方式:Usage: /etc/init.d/ovirt-engine {start|stop|status|restart}

if __name__ == '__main__':
service.setupLogger()
d = Daemon()
d.run()

根据参数打开系统日志

logger = logging.getLogger('ovirt')
logger.propagate = False
if os.environ.get('OVIRT_SERVICE_DEBUG', '0') != '0':
    logger.setLevel(logging.DEBUG)
else:
    logger.setLevel(logging.INFO)

启动守护进程

usage=_('usage: %prog [options] start'),
def _daemon(self):

    self.logger.debug('daemon entry pid=%s', os.getpid())
    self.logger.debug('background=%s', self._options.background)

    os.umask(0o022)

    self.daemonSetup()

    self._daemonReady()
......
  • 设置启动参数
......
parser.add_option(
    '-d', '--debug',
    dest='debug',
    action='store_true',
    default=False,
    help=_('debug mode'),
)
parser.add_option(
    '--pidfile',
    dest='pidfile',
    default=None,
    metavar=_('FILE'),
    help=_('pid file to use'),
)
parser.add_option(
    '--background',
    dest='background',
    action='store_true',
    default=False,
    help=_('Go into the background'),
)
parser.add_option(
    '--systemd',
    dest='systemd',
    default='simple',
    choices=['simple', 'notify'],
    help=_('Systemd type simple|notify'),
)
parser.add_option(
    '--redirect-output',
    dest='redirectOutput',
    action='store_true',
    default=False,
    help=_('Redirect output of daemon'),
)
......
  • 整个服务启动的过程,就是 JBOSS 模块加载的过程
self._executable = os.path.join(
    java.Java().getJavaHome(),
    'bin',
    'java',
)

jbossModulesJar = os.path.join(
    self._config.get('JBOSS_HOME'),
    'jboss-modules.jar',
)
  • 加载参数检测
self._checkInstallation(
    pidfile=self.pidfile,
    jbossModulesJar=jbossModulesJar,
)
self.check(
    name=self._config.get('JBOSS_HOME'),
    directory=True,
)
self.check(
    name=jbossModulesJar,
)

# Check the required engine directories and files:
self.check(
    os.path.join(
        self._config.get('ENGINE_USR'),
        'services',
    ),
    directory=True,
)
self.check(
    self._config.get('ENGINE_CACHE'),
    directory=True,
    writable=True,
)
self.check(
    self._config.get('ENGINE_TMP'),
    directory=True,
    writable=True,
    mustExist=False,
)
self.check(
    self._config.get('ENGINE_LOG'),
    directory=True,
    writable=True,
)
self.check(
    name=os.path.join(
        self._config.get("ENGINE_LOG"),
        'host-deploy',
    ),
    directory=True,
    writable=True,
)
for log in ('engine.log', 'console.log', 'server.log'):
    self.check(
        name=os.path.join(self._config.get("ENGINE_LOG"), log),
        mustExist=False,
        writable=True,
    )
if pidfile is not None:
    self.check(
        name=pidfile,
        writable=True,
        mustExist=False,
    )

日志根据不同的需求,配置不同的日志文件:engine.logconsole.logserver.log

  • 创建运行所需的目录,设置 700 权限
self._tempDir = service.TempDir(self._config.get('ENGINE_TMP'))
self._tempDir.create()

self._jbossRuntime = service.TempDir(self._config.get('JBOSS_RUNTIME'))
self._jbossRuntime.create()

self._setupEngineApps()

jbossTempDir = os.path.join(
    self._jbossRuntime.directory,
    'tmp',
)

jbossConfigDir = os.path.join(
    self._jbossRuntime.directory,
    'config',
)

javaModulePath = self._linkModules(
    os.path.join(
        self._jbossRuntime.directory,
        'modules',
    ),
    '%s:%s' % (
        self._config.get('ENGINE_JAVA_MODULEPATH'),
        os.path.join(
            self._config.get('JBOSS_HOME'),
            'modules',
        ),
    ),
)

os.mkdir(jbossTempDir)
os.mkdir(jbossConfigDir)
os.chmod(jbossConfigDir, 0o700)
  • 创建 jboss_runtime 目录,包含 tmpconfigmodules 子目录
cd /var/lib/ovirt-engine/jboss_runtime
[root@localhost jboss_runtime]# ll
total 16
drwx------. 3 ovirt ovirt 4096 Jul  3 12:04 config
drwxr-xr-x. 2 ovirt ovirt 4096 Jul  3 12:04 deployments
drwxr-xr-x. 4 ovirt ovirt 4096 Jul  3 12:03 modules
drwxr-xr-x. 5 ovirt ovirt 4096 Jul  3 12:03 tmp
  • 根据模板生成配置文件,设置 600 权限
jbossBootLoggingFile = self._processTemplate(
    template=os.path.join(
        os.path.dirname(sys.argv[0]),
        'ovirt-engine-logging.properties.in'
    ),
    dir=jbossConfigDir,
)

jbossConfigFile = self._processTemplate(
    template=os.path.join(
        os.path.dirname(sys.argv[0]),
        'ovirt-engine.xml.in',
    ),
    dir=jbossConfigDir,
    mode=0o600,
)
  • 设置模块启动参数信息
self._engineArgs.extend([
    # The name or the process, as displayed by ps:
    'ovirt-engine',

    # Virtual machine options:
    '-server',
    '-XX:+TieredCompilation',
    '-Xms%s' % self._config.get('ENGINE_HEAP_MIN'),
    '-Xmx%s' % self._config.get('ENGINE_HEAP_MAX'),
    '-XX:PermSize=%s' % self._config.get('ENGINE_PERM_MIN'),
    '-XX:MaxPermSize=%s' % self._config.get(
        'ENGINE_PERM_MAX'
    ),
    '-Djava.net.preferIPv4Stack=true',
    '-Dsun.rmi.dgc.client.gcInterval=3600000',
    '-Dsun.rmi.dgc.server.gcInterval=3600000',
    '-Djava.awt.headless=true',
])

# Add extra system properties provided in the configuration:
for engineProperty in shlex.split(
    self._config.get('ENGINE_PROPERTIES')
):
    if not engineProperty.startswith('-D'):
        engineProperty = '-D' + engineProperty
    self._engineArgs.append(engineProperty)

# Add extra jvm arguments provided in the configuration:
for arg in shlex.split(self._config.get('ENGINE_JVM_ARGS')):
    self._engineArgs.append(arg)

# Add arguments for remote debugging of the java virtual machine:
engineDebugAddress = self._config.get('ENGINE_DEBUG_ADDRESS')
if engineDebugAddress:
    self._engineArgs.append(
        (
            '-Xrunjdwp:transport=dt_socket,address=%s,'
            'server=y,suspend=n'
        ) % (
            engineDebugAddress
        )
    )

# Enable verbose garbage collection if required:
if self._config.getboolean('ENGINE_VERBOSE_GC'):
    self._engineArgs.extend([
        '-verbose:gc',
        '-XX:+PrintGCTimeStamps',
        '-XX:+PrintGCDetails',
    ])

# Add arguments for JBoss:
self._engineArgs.extend([
    '-Djava.util.logging.manager=org.jboss.logmanager',
    '-Dlogging.configuration=file://%s' % jbossBootLoggingFile,
    '-Dorg.jboss.resolver.warning=true',
    '-Djboss.modules.system.pkgs=org.jboss.byteman',
    '-Djboss.modules.write-indexes=false',
    '-Djboss.server.default.config=ovirt-engine',
    '-Djboss.home.dir=%s' % self._config.get(
        'JBOSS_HOME'
    ),
    '-Djboss.server.base.dir=%s' % self._config.get(
        'ENGINE_USR'
    ),
    '-Djboss.server.data.dir=%s' % self._config.get(
        'ENGINE_VAR'
    ),
    '-Djboss.server.log.dir=%s' % self._config.get(
        'ENGINE_LOG'
    ),
    '-Djboss.server.config.dir=%s' % jbossConfigDir,
    '-Djboss.server.temp.dir=%s' % jbossTempDir,
    '-Djboss.controller.temp.dir=%s' % jbossTempDir,
    '-jar', jbossModulesJar,
    '-mp', javaModulePath,
    '-jaxpmodule', 'javax.xml.jaxp-provider',
    'org.jboss.as.standalone',
    '-c', os.path.basename(jbossConfigFile),
])
  • 创建 JBOSS 启动发布模块目录
deploymentsDir = os.path.join(
    self._jbossRuntime.directory,
    'deployments',
)
os.mkdir(deploymentsDir)
  • 与项目中的发布模块映射为链接
for engineAppDir in shlex.split(self._config.get('ENGINE_APPS')+ " " + self._config.get('TERMINAL_APPS')):
self.logger.debug('Deploying: %s', engineAppDir)
if not os.path.isabs(engineAppDir):
    engineAppDir = os.path.join(
        self._config.get('ENGINE_USR'),
        engineAppDir,
    )
if not os.path.exists(engineAppDir):
    self.logger.warning(
        _(
            "Application directory '{directory}' "
            "does not exist, it will be ignored"
        ).format(
            directory=engineAppDir,
        ),
    )
    continue

engineAppLink = os.path.join(
    deploymentsDir,
    os.path.basename(engineAppDir),
)
os.symlink(engineAppDir, engineAppLink)
with open('%s.dodeploy' % engineAppLink, 'w'):
    pass
[root@localhost deployments]# pwd
/var/lib/ovirt-engine/jboss_runtime/deployments
[root@localhost deployments]# ll
total 16
lrwxrwxrwx. 1 ovirt ovirt 34 Jul  3 12:03 engine.ear -> /usr/share/ovirt-engine/engine.ear
-rw-r--r--. 1 ovirt ovirt 10 Jul  3 11:30 engine.ear.deployed
lrwxrwxrwx. 1 ovirt ovirt 54 Jul  3 12:03 ovirt-engine-reports.war -> /var/lib/ovirt-engine-reports/ovirt-engine-reports.war
-rw-r--r--. 1 ovirt ovirt 24 Jul  3 12:03 ovirt-engine-reports.war.deployed
lrwxrwxrwx. 1 ovirt ovirt 67 Jul  3 12:03 rhev.ear -> /usr/share/ovirt-engine/branding/rhev-1.brand/applications/rhev.ear
-rw-r--r--. 1 ovirt ovirt  8 Jun 19 08:00 rhev.ear.deployed
  • 创建 modules 目录,将运行 JBOSS 模块的依赖建立链接关系
def _linkModules(self, directory, modulePath):
    """
    Link all the JBoss modules into a temporary directory.
    This required because jboss tries to automatically update
    indexes based on timestamp even if there is no permission to do so.
    """

    modifiedModulePath = []
    for index, element in enumerate(modulePath.split(':')):
        modulesTmpDir = os.path.join(
            directory,
            '%02d-%s' % (
                index,
                '-'.join(element.split(os.sep)[-2:]),
            ),
        )
        modifiedModulePath.append(modulesTmpDir)

        # For each directory in the modules directory create the
        # same in the temporary directory and populate with symlinks
        # pointing to the original files (excluding indexes):
        for parentDir, childrenDirs, childrenFiles in os.walk(element):
            parentTmpDir = os.path.join(
                modulesTmpDir,
                os.path.relpath(
                    parentDir,
                    element
                ),
            )
            if not os.path.exists(parentTmpDir):
                os.makedirs(parentTmpDir)
            for childFile in childrenFiles:
                if childFile.endswith('.index'):
                    continue
                os.symlink(
                    os.path.join(parentDir, childFile),
                    os.path.join(parentTmpDir, childFile)
                )

    return ':'.join(modifiedModulePath)
[root@localhost main]# pwd
/var/lib/ovirt-engine/jboss_runtime/modules/00-ovirt-engine-modules/com/mchange/c3p0/main
[root@localhost main]# ll
total 8
lrwxrwxrwx. 1 ovirt ovirt 62 Jul  3 12:03 c3p0.jar -> /usr/share/ovirt-engine/modules/com/mchange/c3p0/main/c3p0.jar
lrwxrwxrwx. 1 ovirt ovirt 64 Jul  3 12:03 module.xml -> /usr/share/ovirt-engine/modules/com/mchange/c3p0/main/module.xml

你可能感兴趣的:(【Ovirt 笔记】ovirt-engine 服务的实现原理)