mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-03 21:02:34 +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)
 | 
						|
 | 
						|
 |