From 8b4e3b1f51c33ffedf27bfb3e0bd3c4f1603a143 Mon Sep 17 00:00:00 2001 From: Zhenguo Niu Date: Wed, 12 Apr 2017 19:32:25 +0800 Subject: [PATCH] Add support to specify userdata when creating a server Change-Id: I283253a778958de5bfc4417fe8cd8b79927d63cb --- moganclient/osc/v1/server.py | 27 ++++++++++++++++++++++++++- moganclient/v1/server.py | 29 ++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/moganclient/osc/v1/server.py b/moganclient/osc/v1/server.py index adebcb8..e7d4a02 100644 --- a/moganclient/osc/v1/server.py +++ b/moganclient/osc/v1/server.py @@ -16,6 +16,7 @@ """Mogan v1 Baremetal server action implementations""" +import io import json import logging import os @@ -107,6 +108,11 @@ class CreateServer(command.ShowOne): metavar="", help=_("The availability zone for the baremetal server placement"), ) + parser.add_argument( + '--user-data', + metavar='', + help=_('User data file to inject into the instance'), + ) parser.add_argument( "--extra", metavar="", @@ -144,17 +150,36 @@ class CreateServer(command.ShowOne): nic['net_id'] = nic['net-id'] del nic['net-id'] - data = bc_client.server.create( + userdata = None + if parsed_args.user_data: + try: + userdata = io.open(parsed_args.user_data) + except IOError as e: + msg = _("Can't open '%(data)s': %(exception)s") + raise exceptions.CommandError( + msg % {"data": parsed_args.user_data, + "exception": e} + ) + + boot_kwargs = dict( name=parsed_args.name, image_uuid=image_data.id, flavor_uuid=flavor_data.uuid, description=parsed_args.description, networks=parsed_args.nic, availability_zone=parsed_args.availability_zone, + userdata=userdata, extra=parsed_args.extra, min_count=parsed_args.min_count, max_count=parsed_args.max_count ) + + try: + data = bc_client.server.create(**boot_kwargs) + finally: + if hasattr(userdata, 'close'): + userdata.close() + info = {} info.update(data._info) return zip(*sorted(info.items())) diff --git a/moganclient/v1/server.py b/moganclient/v1/server.py index d1bbaa3..8d6c357 100644 --- a/moganclient/v1/server.py +++ b/moganclient/v1/server.py @@ -13,6 +13,11 @@ # under the License. # +import base64 + +from oslo_utils import encodeutils +import six + from moganclient.common import base @@ -25,7 +30,7 @@ class ServerManager(base.ManagerWithFind): def create(self, name, image_uuid, flavor_uuid, networks, description=None, availability_zone=None, extra=None, - min_count=None, max_count=None): + userdata=None, min_count=None, max_count=None): url = '/instances' data = { 'name': name, @@ -33,6 +38,28 @@ class ServerManager(base.ManagerWithFind): 'instance_type_uuid': flavor_uuid, 'networks': networks } + + if userdata is not None: + if hasattr(userdata, 'read'): + userdata = userdata.read() + + # NOTE(melwitt): Text file data is converted to bytes prior to + # base64 encoding. The utf-8 encoding will fail for binary files. + if six.PY3: + try: + userdata = userdata.encode("utf-8") + except AttributeError: + # In python 3, 'bytes' object has no attribute 'encode' + pass + else: + try: + userdata = encodeutils.safe_encode(userdata) + except UnicodeDecodeError: + pass + + userdata_b64 = base64.b64encode(userdata).decode('utf-8') + data["user_data"] = userdata_b64 + if availability_zone is not None: data['availability_zone'] = availability_zone if description is not None: