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
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)
|
|
|
|
|