Add custom OpenNebula oned.conf patcher (it uses a SHITTY configuration file format)

This commit is contained in:
Vitaliy Filippov
2024-10-06 13:46:05 +03:00
parent 2e76ceabbe
commit 30e7c2ad1e
2 changed files with 124 additions and 2 deletions
+9 -2
View File
@@ -3,7 +3,9 @@
set -e set -e
reapply_patch() { reapply_patch() {
if ! patch -f --dry-run -F 0 -R $1 < $2 >/dev/null; then if ! [[ -e $1 ]]; then
echo "$1 does not exist, OpenNebula is not installed"
elif ! patch -f --dry-run -F 0 -R $1 < $2 >/dev/null; then
already_applied=0 already_applied=0
if ! patch --no-backup-if-mismatch -r - -F 0 -f $1 < $2; then if ! patch --no-backup-if-mismatch -r - -F 0 -f $1 < $2; then
applied_ok=0 applied_ok=0
@@ -15,8 +17,13 @@ echo "Reapplying Vitastor patches to OpenNebula's oned.conf, vmm_execrc and down
already_applied=1 already_applied=1
applied_ok=1 applied_ok=1
reapply_patch /var/lib/one/remotes/datastore/downloader.sh /var/lib/one/remotes/datastore/vitastor/downloader-vitastor.sh.diff reapply_patch /var/lib/one/remotes/datastore/downloader.sh /var/lib/one/remotes/datastore/vitastor/downloader-vitastor.sh.diff
reapply_patch /etc/one/oned.conf /var/lib/one/remotes/datastore/vitastor/oned.conf.diff
reapply_patch /etc/one/vmm_exec/vmm_execrc /var/lib/one/remotes/datastore/vitastor/vmm_execrc.diff reapply_patch /etc/one/vmm_exec/vmm_execrc /var/lib/one/remotes/datastore/vitastor/vmm_execrc.diff
if [[ -e /etc/one/oned.conf ]]; then
if ! /var/lib/one/remotes/datastore/vitastor/patch-oned-conf.py /etc/one/oned.conf; then
applied_ok=0
already_applied=0
fi
fi
if [[ "$already_applied" = 1 ]]; then if [[ "$already_applied" = 1 ]]; then
echo "OK: Vitastor OpenNebula patches are already applied" echo "OK: Vitastor OpenNebula patches are already applied"
elif [[ "$applied_ok" = 1 ]]; then elif [[ "$applied_ok" = 1 ]]; then
+115
View File
@@ -0,0 +1,115 @@
#!/usr/bin/env python3
# Patch /etc/one/oned.conf for Vitastor support
# -s = also enable save.vitastor/restore.vitastor overrides
import re
import os
import sys
class Fixer:
save_restore = 0
def require_sub_cb(self, m, cb):
self.found = 1
return cb(m)
def require_sub(self, regexp, cb, text, error):
self.found = 0
new_text = re.sub(regexp, lambda m: self.require_sub_cb(m, cb), text)
if not self.found and error:
self.errors.append(error)
return new_text
def fix(self, oned_conf):
self.errors = []
self.kvm_found = 0
oned_conf = self.require_sub(r'((?:^|\n)[ \t]*VM_MAD\s*=\s*\[)([^\]]+)\]', lambda m: m.group(1)+self.fix_vm_mad(m.group(2))+']', oned_conf, 'VM_MAD not found')
if not self.kvm_found:
self.errors.append("VM_MAD[NAME=kvm].ARGUMENTS not found")
oned_conf = self.require_sub(r'((?:^|\n)[ \t]*TM_MAD\s*=\s*\[)([^\]]+)\]', lambda m: m.group(1)+self.fix_tm_mad(m.group(2))+']', oned_conf, 'TM_MAD not found')
oned_conf = self.require_sub(r'((?:^|\n)[ \t]*DATASTORE_MAD\s*=\s*\[)([^\]]+)\]', lambda m: m.group(1)+self.fix_datastore_mad(m.group(2))+']', oned_conf, 'DATASTORE_MAD not found')
if oned_conf[-1:] != '\n':
oned_conf += '\n'
if not re.compile(r'(^|\n)[ \t]*INHERIT_DATASTORE_ATTR\s*=\s*"VITASTOR_CONF"').search(oned_conf):
oned_conf += '\nINHERIT_DATASTORE_ATTR="VITASTOR_CONF"\n'
if not re.compile(r'(^|\n)[ \t]*INHERIT_DATASTORE_ATTR\s*=\s*"IMAGE_PREFIX"').search(oned_conf):
oned_conf += '\nINHERIT_DATASTORE_ATTR="IMAGE_PREFIX"\n'
if not re.compile(r'(^|\n)[ \t]*TM_MAD_CONF\s*=\s*\[[^\]]*NAME\s*=\s*"vitastor"').search(oned_conf):
oned_conf += ('\nTM_MAD_CONF = [\n'+
' NAME = "vitastor", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "YES",\n'+
' DS_MIGRATE = "NO", DRIVER = "raw", ALLOW_ORPHANS="format",\n'+
' TM_MAD_SYSTEM = "ssh,shared", LN_TARGET_SSH = "SYSTEM", CLONE_TARGET_SSH = "SYSTEM",\n'+
' DISK_TYPE_SSH = "FILE", LN_TARGET_SHARED = "NONE",\n'+
' CLONE_TARGET_SHARED = "SELF", DISK_TYPE_SHARED = "FILE"\n'+
']\n')
if not re.compile(r'(^|\n)[ \t]*DS_MAD_CONF\s*=\s*\[[^\]]*NAME\s*=\s*"vitastor"').search(oned_conf):
oned_conf += ('\nDS_MAD_CONF = [\n'+
' NAME = "vitastor",\n'+
' REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST",\n'+
' PERSISTENT_ONLY = "NO",\n'+
' MARKETPLACE_ACTIONS = "export"\n'+
']\n')
return oned_conf
def fix_vm_mad(self, vm_mad_params):
if re.compile(r'\bNAME\s*=\s*"kvm"').search(vm_mad_params):
vm_mad_params = re.sub(r'\b(ARGUMENTS\s*=\s*")([^"]+)"', lambda m: m.group(1)+self.fix_vm_mad_args(m.group(2))+'"', vm_mad_params)
self.kvm_found = 1
return vm_mad_params
def fix_vm_mad_args(self, args):
args = self.fix_vm_mad_override(args, 'deploy')
if self.save_restore:
args = self.fix_vm_mad_override(args, 'save')
args = self.fix_vm_mad_override(args, 'restore')
return args
def fix_vm_mad_override(self, args, override):
m = re.compile(r'-l (\S+)').search(args)
if m and re.compile(override+'='+override+'.vitastor').search(m.group(1)):
return args
elif m and re.compile(override+'=').search(m.group(1)):
self.errors.append(override+"= is already overridden in -l option in VM_MAD[NAME=kvm].ARGUMENTS")
return args
elif m:
return self.require_sub(r'-l (\S+)', lambda m: '-l '+m.group(1)+','+override+'='+override+'.vitastor', args, '-l option not found in VM_MAD[NAME=kvm].ARGUMENTS')
else:
return args+' -l '+override+'='+override+'.vitastor'
def fix_tm_mad(self, params):
return self.require_sub(r'\b(ARGUMENTS\s*=\s*")([^"]+)"', lambda m: m.group(1)+self.fix_tm_mad_args('d', m.group(2), "TM_MAD")+'"', params, "TM_MAD.ARGUMENTS not found")
def fix_tm_mad_args(self, opt, args, v):
return self.require_sub('(-'+opt+r') (\S+)', lambda m: self.fix_tm_mad_arg(m), args, "-"+opt+" option not found in "+v+".ARGUMENTS")
def fix_tm_mad_arg(self, m):
a = m.group(2).split(',')
if 'vitastor' not in a:
a += [ 'vitastor' ]
return m.group(1)+' '+(','.join(a))
def fix_datastore_mad(self, params):
params = self.require_sub(r'\b(ARGUMENTS\s*=\s*")([^"]+)"', lambda m: m.group(1)+self.fix_tm_mad_args('d', m.group(2), "DATASTORE_MAD")+'"', params, "DATASTORE_MAD.ARGUMENTS not found")
return self.require_sub(r'\b(ARGUMENTS\s*=\s*")([^"]+)"', lambda m: m.group(1)+self.fix_tm_mad_args('s', m.group(2), "DATASTORE_MAD")+'"', params, "")
fixer = Fixer()
oned_conf_file = ''
for arg in sys.argv[1:]:
if arg == '-s':
fixer.save_restore = 1
else:
oned_conf_file = arg
break
if not oned_conf_file:
sys.stderr.write("USAGE: ./patch-oned-conf.py [-s] /etc/one/oned.conf\n-s means also enable save.vitastor/restore.vitastor overrides\n")
sys.exit(1)
with open(oned_conf_file, 'r') as fd:
oned_conf = fd.read()
new_conf = fixer.fix(oned_conf)
if new_conf != oned_conf:
os.rename(oned_conf_file, oned_conf_file+'.bak')
with open(oned_conf_file, 'w') as fd:
fd.write(new_conf)
if len(fixer.errors) > 0:
sys.stderr.write("ERROR: Failed to patch "+oned_conf_file+", patch it manually. Errors:\n- "+('\n- '.join(fixer.errors))+'\n')
sys.exit(1)