2
0
mirror of https://github.com/xcat2/confluent.git synced 2024-12-23 19:52:10 +00:00

Implement a 'staged' phase of profile

This allows a limbo where remote deployment is blocked
but final deployment is not yet flagged.
This commit is contained in:
Jarrod Johnson 2020-07-01 14:01:28 -04:00
parent 22085e38f5
commit 78e5d343e7
3 changed files with 35 additions and 21 deletions

View File

@ -29,38 +29,38 @@ def armonce(nr, cli):
def setpending(nr, profile, cli):
for rsp in cli.update('/noderange/{0}/attributes/current'.format(nr),
{'deployment.pendingprofile': profile}):
{'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', action='store_true')
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:
sys.stderr.write('Currently only network (-n) deployment is supported\n')
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([])
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
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__':

View File

@ -188,6 +188,12 @@ node = {
'the network boot subsystem what should be offered when a potential '
'network boot request comes in')
},
'deployment.stagedprofile': {
'description': ('A profile that has been staged, but is awaiting final '
'boot to be activated. This allows an OS profile to '
'remove itself from netboot without indicating '
'completion to any watcher.')
},
'deployment.profile': {
'description': ('The profile that has most recently reported '
'completion of deployment. Note that an image may opt '

View File

@ -162,17 +162,25 @@ def handle_request(env, start_response):
yield dumper(sorted(nodes))
elif env['PATH_INFO'] == '/self/updatestatus':
update = yaml.safe_load(reqbody)
if update['status'] != 'complete':
if update['status'] == 'staged':
targattr = 'deployment.stagedprofile'
elif update['status'] == 'complete':
targattr = 'deployment.profile'
else
raise Exception('Unknown update status request')
currattr = cfg.get_node_attributes(nodename, 'deployment.*').get(
nodename, {})
pending = currattr.get('deployment.pendingprofile', {}).get('value', '')
pending = None
if targattr == 'deployment.profile':
pending = currattr.get('deployment.stagedprofile', {}).get('value', '')
if not pending:
pending = currattr.get('deployment.pendingprofile', {}).get('value', '')
updates = {}
if pending:
updates['deployment.pendingprofile'] = {'value': ''}
currprof = currattr.get('deployment.profile', {}).get('value', '')
currprof = currattr.get(targattr, {}).get('value', '')
if currprof != pending:
updates['deployment.profile'] = {'value': pending}
updates[targattr] = {'value': pending}
cfg.set_node_attributes({nodename: updates})
start_response('200 OK', (('Content-Type', 'text/plain'),))
yield 'OK'