文前说明
作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。
本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。
分析整理的版本为 Ovirt 3.4.5 版本。
命令使用方式:/usr/bin/engine-cleanup
--log=file
write log to this file.
--config=file
Load configuration files.
--config-append=file
Load extra configuration files or answer file.
--generate-answer=file
Generate answer file.
命令采用了 python 方式进行实现。
- 主要调用了 otopi
exec "${otopidir}/otopi" "${baseenv} ${environment} ${otopienv}"
baseenv="APPEND:BASE/pluginPath=str:${scriptdir}/../plugins APPEND:BASE/pluginGroups=str:ovirt-engine-common:ovirt-engine-remove"
- 参数是设置 environment 的过程。
--otopi-environment=*)
otopienv="${v}"
;;
--log=*)
environment="${environment} CORE/logFileName=str:${v}"
;;
--config=*)
environment="${environment} APPEND:CORE/configFileName=str:${v}"
;;
--config-append=*)
environment="${environment} APPEND:CORE/configFileAppend=str:${v}"
;;
--generate-answer=*)
environment="${environment} OVESETUP_CORE/answerFile=str:${v}"
;;
--help)
usage
;;
*)
otopi
otopi 是 oVirt 面向任务的可插拔安装/实施。是用于安装独立插件的系统组件。插件只需提供简单的添加的安装功能而无需复杂的事务管理。
使用方式:otopi [variables]
variables ::= name=type:value variables | APPEND:name=type:value | ''
type ::= none | bool | int | str | multi-str
APPEND: prefix appends as colon list string.
CUSTOMIZATION
-------------
Set the following environment:
DIALOG/customization=bool:True
This will trigger command-line prompt before validation and
before termination.
Refer to README.dialog for more information.
FILES
-----
CONFIGURATION
Configuration files used to override the environment.
System environment:
OTOPI_CONFIG
Environment:
CORE/configFileName
Default:
/etc/otopi.conf
Config files to be read:
@configFileName@
@[email protected]/*.conf (sorted)
Structure:
[environment:default]
key=type:value
[environment:init]
key=type:value
[environment:override]
key=type:value
[environment:enforce]
key=type:value
default is applied during setup without override.
init is applied during setup with override.
override is applied before customization with override.
enforce is applied after customization with override.
type ::= none | bool | int | str | multi-str
ENVIRONMENT
-----------
Refer to README.environment
UNPRIVILEDGE EXECUTION
----------------------
Using sudo it is possible to escalate privilege. Use the following
configuration:
/etc/sudoers.d/50-otopi.conf
Defaults:user1 !requiretty
user1 ALL=(ALL) NOPASSWD: /bin/sh
COMPATIBILITY
-------------
- Python-2.6
- Python-2.7
- Python-3.2
执行流程,分析 ovirt-engine-common 和 ovirt-engine-remove 源码。
[ INFO ] Stage: Transaction setup
[ INFO ] Stopping engine service
[ INFO ] Stopping websocket-proxy service
[ INFO ] Stage: Misc configuration
[ INFO ] Stage: Package installation
[ INFO ] Stage: Misc configuration
[ INFO ] Backing up PKI configuration and keys
[ INFO ] Backing up database localhost:engine to '/var/lib/ovirt-engine/backups/engine-20170520122832.Mtf_w7.dump'.
[ INFO ] Clearing Engine database engine
[ INFO ] Removing files
[ INFO ] Reverting changes to files
[ INFO ] Stage: Transaction commit
[ INFO ] Stage: Closing up
--== SUMMARY ==--
A backup of the Engine database is available at /var/lib/ovirt-engine/backups/engine-20170520122832.Mtf_w7.dump
A backup of PKI configuration and keys is available at /var/lib/ovirt-engine/backups/engine-pki-20170520122832PJgsGW.tar.gz
Engine setup successfully cleaned up
--== END OF SUMMARY ==--
[ INFO ] Stage: Clean up
Log file is located at /var/log/ovirt-engine/setup/ovirt-engine-remove-20170520122814-wughvt.log
[ INFO ] Generating answer file '/var/lib/ovirt-engine/setup/answers/20170520122845-cleanup.conf'
[ INFO ] Stage: Pre-termination
[ INFO ] Stage: Termination
[ INFO ] Execution of cleanup completed successfully
- 停止 engine 服务。/usr/share/ovirt-engine/setup/plugins/ovirt-engine-common/base/core/engine.py
def _transactionBegin(self):
if self.services.exists(name=osetupcons.Const.ENGINE_SERVICE_NAME):
self.logger.info(_('Stopping engine service'))
self.services.state(
name=osetupcons.Const.ENGINE_SERVICE_NAME,
state=False
)
- 停止 websocket-proxy 服务。/usr/share/ovirt-engine/setup/plugins/ovirt-engine-common/websocket_proxy/core.py
def _transactionBegin(self):
if self.services.exists(
name=osetupcons.Const.WEBSOCKET_PROXY_SERVICE_NAME,
):
self.logger.info(_('Stopping websocket-proxy service'))
self.services.state(
name=osetupcons.Const.WEBSOCKET_PROXY_SERVICE_NAME,
state=False
)
- 使用 otopi 安装 ovirt-engine-common 和 ovirt-engine-remove 插件,使用插件功能执行下面步骤。
- 备份 PKI 配置文件。
def _misc(self):
self.logger.info(
_('Backing up PKI configuration and keys')
)
fd, self._bkpfile = tempfile.mkstemp(
prefix=(
'engine-pki-%s' %
datetime.datetime.now().strftime('%Y%m%d%H%M%S')
),
suffix='.tar.gz',
dir=osetupcons.FileLocations.OVIRT_ENGINE_DB_BACKUP_DIR,
)
os.fchown(
fd,
osetuputil.getUid(
self.environment[osetupcons.SystemEnv.USER_ROOT]
),
-1
)
os.fchmod(fd, 0o600)
with os.fdopen(fd, 'wb') as fileobj:
# fileobj is not closed, when TarFile is closed
# cannot use with tarfile.open()
- 备份 数据库。/usr/share/ovirt-engine/setup/ovirt_engine_setup/database.py
def backup(
self,
dir,
prefix,
):
fd, backupFile = tempfile.mkstemp(
prefix='%s-%s.' % (
prefix,
datetime.datetime.now().strftime('%Y%m%d%H%M%S')
),
suffix='.dump',
dir=dir,
)
os.close(fd)
self.logger.info(
_("Backing up database {host}:{database} to '{file}'.").format(
host=self.environment[self._dbenvkeys['host']],
database=self.environment[self._dbenvkeys['database']],
file=backupFile,
)
)
self._plugin.execute(
(
self.command.get('pg_dump'),
'-E', 'UTF8',
'--disable-dollar-quoting',
'--disable-triggers',
'--format=c',
'-U', self.environment[self._dbenvkeys['user']],
'-h', self.environment[self._dbenvkeys['host']],
'-p', str(self.environment[self._dbenvkeys['port']]),
'-f', backupFile,
self.environment[self._dbenvkeys['database']],
),
envAppend={
'PGPASSWORD': '',
'PGPASSFILE': self.environment[self._dbenvkeys['pgpassfile']],
},
)
return backupFile
备份数据使用的是 pg_dump 命令
- 删除数据库。/usr/share/ovirt-engine/setup/plugins/ovirt-engine-remove/ovirt-engine/db/clear.py
def _misc(self):
try:
dbovirtutils = database.OvirtUtils(
plugin=self,
dbenvkeys=osetupcons.Const.ENGINE_DB_ENV_KEYS,
)
dbovirtutils.tryDatabaseConnect()
self._bkpfile = dbovirtutils.backup(
dir=osetupcons.FileLocations.OVIRT_ENGINE_DB_BACKUP_DIR,
prefix=osetupcons.Const.ENGINE_DB_BACKUP_PREFIX,
)
self.logger.info(
_('Clearing Engine database {database}').format(
database=self.environment[osetupcons.DBEnv.DATABASE],
)
)
dbovirtutils.clearDatabase()
......
调用了 /usr/share/ovirt-engine/setup/ovirt_engine_setup/database.py 的 clearDatabase 方法。
def clearDatabase(self):
self.createLanguage('plpgsql')
statement = Statement(
environment=self.environment,
dbenvkeys=self._dbenvkeys,
)
statement.execute(
statement="""
create or replace
function
oesetup_generate_drop_all_syntax()
returns setof text
AS $procedure$ begin
return query
select
'drop function if exists ' ||
ns.nspname ||
'.' ||
proname ||
'(' ||
oidvectortypes(proargtypes) ||
') cascade;'
from
pg_proc inner join pg_namespace ns on (
pg_proc.pronamespace=ns.oid
)
where
ns.nspname = 'public'
union
......
实际执行了一系列 drop 命令。
- 删除文件 /usr/share/ovirt-engine/setup/plugins/ovirt-engine-remove/ovirt-engine/files/simple.py。
def _misc(self):
self.logger.info(_('Removing files'))
for f in self._toremove:
if os.path.exists(f):
if self._digestFile(f) != self._files[f]:
self.logger.warning(
_(
"Preserving '{file}' as changed since installation"
).format(
file=f,
)
)
else:
self._safeDelete(f)
elif os.path.islink(f):
# dead link
self._safeDelete(f)
self.logger.info(_('Reverting changes to files'))
for f in self._tomodifylines:
if os.path.exists(f):
self._revertChanges(f, self._lines[f])
for info in self._infos:
self._safeDelete(info)
......
self._infos = sorted(
glob.glob(
os.path.join(
osetupcons.FileLocations.OVIRT_ENGINE_UNINSTALL_DIR,
'*.conf',
)
)
)
......
实际删除的文件:
OVESETUP_REMOVE/filesToRemove=set:'set(['/etc/httpd/conf.d/ovirt-engine-root-redirect.conf', '/etc/pki/ovirt-engine/cacert.conf', '/var/lib/exports/iso-20170521063135/8c87de5d-b0f5-4ac2-ae42-5725a7977bc9/images/11111111-1111-1111-1111-111111111111/.keep', '/var/lib/exports/iso-20170521063135/8c87de5d-b0f5-4ac2-ae42-5725a7977bc9/dom_md/ids', '/etc/ovirt-engine/notifier/notifier.conf.d/10-setup-jboss.conf', '/var/lib/exports/iso-20170521063135/8c87de5d-b0f5-4ac2-ae42-5725a7977bc9/images/11111111-1111-1111-1111-111111111111/virtio-win_x86.vfd', '/etc/ovirt-engine/ovirt-websocket-proxy.conf.d/10-setup.conf', '/etc/pki/ovirt-engine/.truststore', '/etc/pki/ovirt-engine/cert.template', '/etc/pki/ovirt-engine/keys/apache.p12', '/etc/pki/ovirt-engine/keys/engine_id_rsa', '/var/lib/exports/iso-20170521063135/8c87de5d-b0f5-4ac2-ae42-5725a7977bc9/dom_md/inbox', '/etc/ovirt-engine/imageuploader.conf.d/10-engine-setup.conf', '/etc/pki/ovirt-engine/cert.conf', '/etc/ovirt-engine/engine.conf.d/10-setup-pki.conf', '/etc/ovirt-engine/engine.conf.d/10-setup-protocols.conf', '/etc/pki/ovirt-engine/certs/websocket-proxy.cer', '/etc/httpd/conf.d/z-ovirt-engine-proxy.conf', '/var/lib/exports/iso-20170521063135/8c87de5d-b0f5-4ac2-ae42-5725a7977bc9/images/11111111-1111-1111-1111-111111111111/virtio-win_amd64.vfd', '/etc/ovirt-engine/isouploader.conf.d/10-engine-setup.conf', '/etc/pki/ovirt-engine/keys/engine.p12', '/etc/pki/ovirt-engine/certs/apache.cer', '/etc/ovirt-engine/iptables.example', '/var/lib/exports/iso-20170521063135/8c87de5d-b0f5-4ac2-ae42-5725a7977bc9/dom_md/outbox', '/etc/pki/ovirt-engine/certs/engine.cer', '/etc/pki/ovirt-engine/keys/websocket-proxy.key.nopass', '/etc/pki/ovirt-engine/keys/apache.key.nopass', '/var/lib/exports/iso-20170521063135/8c87de5d-b0f5-4ac2-ae42-5725a7977bc9/images/11111111-1111-1111-1111-111111111111/sdcos-tools-setup.iso', '/etc/pki/ovirt-engine/keys/jboss.p12', '/etc/ovirt-engine/engine.conf.d/10-setup-database.conf', '/etc/pki/ovirt-engine/keys/websocket-proxy.p12', '/etc/pki/ovirt-engine/private/ca.pem', '/etc/pki/ovirt-engine/cacert.template', '/etc/pki/ovirt-engine/apache-ca.pem', '/var/lib/exports/iso-20170521063135/8c87de5d-b0f5-4ac2-ae42-5725a7977bc9/dom_md/leases', '/var/lib/exports/iso-20170521063135/8c87de5d-b0f5-4ac2-ae42-5725a7977bc9/images/11111111-1111-1111-1111-111111111111/virtio-win.iso', '/etc/ovirt-engine-setup.conf.d/20-setup-ovirt-post.conf', '/etc/pki/ovirt-engine/ca.pem', '/etc/ovirt-engine/logcollector.conf.d/10-engine-setup.conf', '/etc/ovirt-engine/engine.conf.d/10-setup-jboss.conf', '/var/lib/exports/iso-20170521063135/8c87de5d-b0f5-4ac2-ae42-5725a7977bc9/dom_md/metadata'])'
备份后的数据库文件:/var/lib/ovirt-engine/backups/engine-20170520122832.Mtf_w7.dump
备份后的 PKI 文件:/var/lib/ovirt-engine/backups/engine-pki-20170520122832PJgsGW.tar.gz