Add custom OpenNebula oned.conf patcher (it uses a SHITTY configuration file format)
This commit is contained in:
@@ -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
@@ -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)
|
||||||
Reference in New Issue
Block a user