2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-30 01:26:38 +00:00

268 lines
8.3 KiB
Python
Executable File

#!/usr/bin/python
from __future__ import print_function
import yaml
import json
import os
import re
import sys
import shutil
import subprocess
#remove the dict entries whose value is null or ''
def Util_rmnullindict(mydict):
for key in mydict.keys():
if isinstance(mydict[key],dict):
Util_rmnullindict(mydict[key])
if not mydict[key].keys():
del mydict[key]
else:
if not mydict[key]:
del mydict[key]
# get the dict value mydict[a][b][c] with key path a.b.c
def Util_getdictval(mydict,keystr):
if not isinstance(mydict,dict):
return None
dictkeyregex=re.compile("([^\.]+)\.?(\S+)*")
result=re.findall(dictkeyregex,keystr)
if result:
(key,remdkey)=result[0]
if key not in mydict.keys():
return None
if remdkey:
return Util_getdictval(mydict[key],remdkey)
else:
return mydict[key]
# get the dict value mydict[a][b][c] with key path a.b.c
def Util_setdictval(mydict,keystr,value):
dictkeyregex=re.compile("([^\.]+)\.?(\S+)*")
result=re.findall(dictkeyregex,keystr)
if result:
(key,remdkey)=result[0]
if remdkey:
if key not in mydict.keys():
mydict[key]={}
Util_setdictval(mydict[key],remdkey,value)
else:
mydict[key]=value
def GetAttrInFile(fpath,objtype,objname,attrpath):
f=open(fpath,'r')
try:
objdict=json.loads(f)
except TypeError,ValueError:
try:
objdict=yaml.load(f)
except Exception,e:
raise Exception("Error: (\[.*?\]: )?cannot open file "+fpath+"! "+str(e))
f.close()
myattrpath=objtype+"."+objname+"."+attrpath
myvalue=Util_getdictval(objdict,myattrpath)
return myvalue
def compattr(exptattr,rawattr):
if isinstance(exptattr,list) and re.match(r'^\[.*\]$',rawattr):
rawattr=eval(rawattr)
if isinstance(rawattr,str):
if rawattr in exptattr:
return 0
else:
return 1
else:
return cmp(exptattr,rawattr)
def runCommand(cmd, env=None):
""" Run one command only, when you don't want to bother setting up
the Popen stuff.
"""
print('Running command: %s' %cmd)
try:
p = subprocess.Popen(cmd,
env=env,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
out, err = p.communicate()
except OSError,e:
print('RunCommand failed due to OSError %s' % e)
if p.returncode:
print('Command %s failed with return code %d : %s' % (cmd , p.returncode, err))
print(out)
print(err)
return p.returncode
def UpdateAttrInFile(fpath,fformat,objtype,objname,attrpath,value):
f=open(fpath,'r')
try:
objdict=json.loads(f)
except TypeError,ValueError:
try:
objdict=yaml.load(f)
except Exception,e:
raise Exception("Error: (\[.*?\]: )?cannot open file "+fpath+"! "+str(e))
f.close()
myattrpath=objtype+"."+objname+"."+attrpath
if value == "":
Util_setdictval(objdict,myattrpath,"")
Util_rmnullindict(objdict)
else:
origobjdict=Util_getdictval(objdict,myattrpath)
origattrtype=type(origobjdict)
newvalue=value
if origattrtype == list and re.match(r'^\[.*\]$',value):
#import pdb
#pdb.set_trace()
newvalue=eval(value)
if isinstance(origobjdict,list) and isinstance(newvalue,str):
newvalue=[newvalue]
Util_setdictval(objdict,myattrpath,newvalue)
f=open(fpath,'w')
if fformat == "yaml":
print(yaml.dump(objdict,default_flow_style=False),file=f)
elif fformat == "json":
print(json.dumps(objdict, sort_keys=True, indent=4, separators=(',', ': ')),file=f)
f.close()
def removeobj(objtype,objname):
print("removing existing \""+objtype+"\" type object \""+objname+"\" from xCAT\n")
if str(objtype) in ('node','osimage','network','site','route','zone','policy'):
runCommand("rmdef -t "+objtype+" -o "+objname)
elif str(objtype) in ('passwd'):
runCommand("tabch -d key="+objname+" passwd")
def Usage():
print("Usage:\n")
print(sys.argv[0]+" [OBJTYPE OBJNAME ATTRIBUTE ATTRVALUE TMPDIR]")
if len(sys.argv) < 6:
Usage()
exit(1)
objtype=str(sys.argv[1])
objname=str(sys.argv[2])
attribute=str(sys.argv[3])
attrvalue=str(sys.argv[4])
tmpdir=str(sys.argv[5])
print("objtype=%s\nobjname=%s\nattribute=%s\nattrvalue=%s\ntmpdir=%s\n"%(objtype,objname,attribute,attrvalue,tmpdir))
if os.path.exists(tmpdir):
runCommand("rm -rf "+tmpdir)
os.mkdir(tmpdir)
print("Temporary directory to hold intermediate files: "+tmpdir+"\n")
curdir=os.path.split(os.path.realpath(sys.argv[0]))[0]
yamldeftmpl=curdir+"/templates/"+objtype+'.yaml'
jsondeftmpl=curdir+"/templates/"+objtype+'.json'
yamldef=tmpdir+"/"+objtype+'.yaml'
jsondef=tmpdir+"/"+objtype+'.json'
yamldefout=tmpdir+"/"+objtype+'.out.yaml'
jsondefout=tmpdir+"/"+objtype+'.out.json'
shutil.copyfile(yamldeftmpl,yamldef)
shutil.copyfile(jsondeftmpl,jsondef)
rcfinal=0
rcyaml=0
rcjson=0
rc=0
UpdateAttrInFile(yamldef,'yaml',objtype,objname,attribute,attrvalue)
print("=================the inventory file to import: "+yamldef+"=====================\n")
runCommand("cat "+yamldef)
print("===============================================================================\n")
print("import the inventory file "+yamldef+"\n")
rc=runCommand("xcat-inventory import -t "+objtype+" -o "+objname+" -f "+yamldef)
if rc !=0:
print("failed to import the inventory file "+yamldef)
rcyaml=1
else:
print("the inventory file "+yamldef+" imported successfully\n")
print("export the \""+objtype+"\" type object \""+objname+"\" just imported\n")
rc=runCommand("xcat-inventory export -t "+objtype+" -o "+objname+" --format=yaml 1>"+yamldefout)
if rc!=0:
print("failed to export the \""+objtype+"\" type object \""+objname+"\"\n")
rcyaml=1
else:
print("==============the exported inventory file "+yamldefout+"======================\n")
runCommand("cat "+yamldefout)
print("===========================================================================\n")
myattrvalue=GetAttrInFile(yamldefout,objtype,objname,attribute)
if attrvalue == '':
if myattrvalue is not None:
rcyaml=1
else:
if compattr(myattrvalue,attrvalue) != 0 :
rcyaml=1
if rcyaml == 0:
print("yaml validation passed\n")
else:
print("yaml validation failed\n")
removeobj(objtype,objname)
UpdateAttrInFile(jsondef,'json',objtype,objname,attribute,attrvalue)
print("=================the inventory file to import: "+jsondef+"=====================\n")
runCommand("cat "+jsondef)
print("===============================================================================\n")
print("import the inventory file "+jsondef+"\n")
rc=runCommand("xcat-inventory import -t "+objtype+" -o "+objname+" -f "+jsondef)
print("rc="+str(rc))
if rc !=0:
print("failed to import the inventory file "+jsondef)
rcjson=1
else:
print("the inventory file "+jsondef+" imported successfully\n")
print("export the \""+objtype+"\" type object \""+objname+"\" just imported\n")
rc=runCommand("xcat-inventory export -t "+objtype+" -o "+objname+" --format=json 1>"+jsondefout)
if rc!=0:
print("failed to export the \""+objtype+"\" type object \""+objname+"\"\n")
rcjson=1
else:
print("==============the exported inventory file "+jsondefout+"======================\n")
runCommand("cat "+jsondefout)
print("===========================================================================\n")
myattrvalue=GetAttrInFile(jsondefout,objtype,objname,attribute)
if attrvalue == '':
if myattrvalue is not None:
rcjson=1
else:
if compattr(myattrvalue,attrvalue) != 0 :
rcjson=1
if rcjson ==0:
print("json validation passed\n")
else:
print("json validation failed\n")
removeobj(objtype,objname)
if rcjson !=0 or rcyaml!=0:
rcfinal=1
print("remove intermediate directory "+tmpdir)
if os.path.exists(tmpdir):
runCommand("rm -rf "+tmpdir)
exit(rcfinal)