From 673fb02896064de2e09b7a026e325fff264ea6c8 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Wed, 3 Jan 2018 15:35:08 -0500 Subject: [PATCH] Draft nodemedia command Server side still has some limitations, but it functions when going downhill with a tailwind while spewing error messages. --- confluent_client/bin/nodemedia | 149 +++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 confluent_client/bin/nodemedia diff --git a/confluent_client/bin/nodemedia b/confluent_client/bin/nodemedia new file mode 100644 index 00000000..78fa62e2 --- /dev/null +++ b/confluent_client/bin/nodemedia @@ -0,0 +1,149 @@ +#!/usr/bin/python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2018 Lenovo +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import optparse +import os +import signal +import sys +import time + +try: + signal.signal(signal.SIGPIPE, signal.SIG_DFL) +except AttributeError: + pass +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 +import confluent.screensqueeze as sq + +exitcode = 0 + +def printerror(res, node=None): + global exitcode + if 'errorcode' in res: + exitcode = res['errorcode'] + if 'error' in res: + if node: + sys.stderr.write('{0}: {1}\n'.format(node, res['error'])) + else: + sys.stderr.write('{0}\n'.format(res['error'])) + if 'errorcode' not in res: + exitcode = 1 + +def attach_media(noderange, media): + global exitcode + session = client.Command() + resource = '/noderange/{0}/media/attach'.format(noderange) + print(repr(list(session.update(resource, {'url': media})))) + + +def list_media(noderange, media): + session = client.Command() + resource = '/noderange/{0}/media/current'.format(noderange) + for res in session.read(resource): + printerror(res) + for node in res.get('databynode', []): + url = res['databynode'][node]['url'] + name = res['databynode'][node]['name'] + print('{0}: {1}'.format(node, url if url else name)) + + +def detach_media(noderange, media): + global exitcode + session = client.Command() + resource = '/noderange/{0}/media/detach'.format(noderange) + for res in session.update(resource, {'detach': media}): + printerror(res) + + +def upload_media(noderange, media): + global exitcode + session = client.Command() + output = sq.ScreenPrinter(noderange, session) + filename = os.path.abspath(media) + resource = '/noderange/{0}/media/uploads/'.format(noderange) + upargs = {'filename': filename} + noderrs = {} + nodeurls = {} + for res in session.create(resource, upargs): + if 'created' not in res: + for nodename in res.get('databynode', ()): + output.set_output(nodename, 'error!') + noderrs[nodename] = res['databynode'][nodename].get( + 'error', 'Unknown Error') + continue + watchurl = res['created'] + currnode = watchurl.split('/')[1] + nodeurls[currnode] = '/' + watchurl + while nodeurls: + for node in list(nodeurls): + progress, status, err = get_update_progress( + session, nodeurls[node]) + if status == 'error': + exitcode = 1 + noderrs[node] = err + if status in ('error', 'complete', 'pending'): + list(session.delete(nodeurls[node])) + del nodeurls[node] + output.set_output(node, progress) + time.sleep(2) + allerrnodes = ','.join(noderrs) + if noderrs: + sys.stderr.write( + 'Nodes had errors receiving media ({0})!\n'.format(allerrnodes)) + for node in noderrs: + sys.stderr.write('{0}: {1}\n'.format(node, noderrs[node])) + +funmap = { + 'upload': upload_media, + 'attach': attach_media, + 'detach': detach_media, + 'list': list_media, +} + + +def main(): + argparser = optparse.OptionParser( + usage="Usage: %prog [list|upload|attach|detach] " + "|all|", + epilog='upload will take the specified file and upload it to the BMC, ' + 'attach will instruct the BMC to connect a remote media to the ' + 'specified url, and detach all will remove all uploaded and' + 'attached urls from the BMC, list shows currently mounted ' + 'media.') + (options, args) = argparser.parse_args() + media = None + try: + noderange = args[0] + operation = args[1] + if operation != 'list': + media = args[2] + except IndexError: + argparser.print_help() + sys.exit(1) + client.check_globbing(noderange) + try: + handler = funmap[operation] + except KeyError: + argparser.print_help() + sys.exit(1) + handler(noderange, media) +if __name__ == '__main__': + main() \ No newline at end of file