#!/usr/bin/python3 import argparse import os import sys path = os.path.dirname(os.path.realpath(__file__)) path = os.path.realpath(os.path.join(path, '..', 'lib', 'python')) if path.startswith('/opt'): sys.path.append(path) import confluent.client as client def armonce(nr, cli): nodes = set([]) for rsp in cli.read('/noderange/{0}/attributes/current'.format(nr)): for node in rsp.get('databynode', {}): nodeinfo = rsp['databynode'][node] for attr in nodeinfo: if attr == 'deployment.apiarmed': curr = nodeinfo[attr].get('value', '') if curr == 'continuous': nodes.add(node) noderange = nr if nodes: noderange += ',-({0})'.format(','.join(nodes)) for rsp in cli.update('/noderange/{0}/attributes/current'.format(noderange), {'deployment.apiarmed': 'once'}): pass def setpending(nr, profile, cli): for rsp in cli.update('/noderange/{0}/attributes/current'.format(nr), {'deployment.pendingprofile': profile, 'deployment.stagedprofile': None}): pass def main(args): ap = argparse.ArgumentParser(description='Deploy OS to nodes') ap.add_argument('-n', '--network', help='Initiate deployment over PXE/HTTP', action='store_true') ap.add_argument('-p', '--prepare', help='Configure for deployment without setting boot device or rebooting', action='store_true') ap.add_argument('-m', '--maxnodes', help='Specifiy a maximum nodes to be deployed') ap.add_argument('noderange', help='Set of nodes to deploy') ap.add_argument('profile', help='Profile name to deploy') args = ap.parse_args(args) if not args.network and not args.prepare: sys.stderr.write('-n or -p is a required argument currently) return 1 c = client.Command() c.stop_if_noderange_over(args.noderange, args.maxnodes) armonce(args.noderange, c) setpending(args.noderange, args.profile, c) errnodes = set([]) if args.network: rc = c.simple_noderange_command(args.noderange, '/boot/nextdevice', 'network', bootmode='uefi', persistent=False, errnodes=errnodes) if errnodes: sys.stderr.write( 'Unable to set boot device for following nodes: {0}\n'.format( ','.join(errnodes))) return 1 rc |= c.simple_noderange_command(args.noderange, '/power/state', 'boot') return rc return 0 if __name__ == '__main__': sys.exit(main(sys.argv[1:]))