Merge "trivial: Rework 'CreateServer' function"
This commit is contained in:
commit
987af4e390
@ -640,13 +640,15 @@ class CreateServer(command.ShowOne):
|
|||||||
disk_group.add_argument(
|
disk_group.add_argument(
|
||||||
'--volume',
|
'--volume',
|
||||||
metavar='<volume>',
|
metavar='<volume>',
|
||||||
help=_('Create server using this volume as the boot disk (name '
|
help=_(
|
||||||
'or ID).\n'
|
'Create server using this volume as the boot disk (name or ID)'
|
||||||
'This option automatically creates a block device mapping '
|
'\n'
|
||||||
'with a boot index of 0. On many hypervisors (libvirt/kvm '
|
'This option automatically creates a block device mapping '
|
||||||
'for example) this will be device vda. Do not create a '
|
'with a boot index of 0. On many hypervisors (libvirt/kvm '
|
||||||
'duplicate mapping using --block-device-mapping for this '
|
'for example) this will be device vda. Do not create a '
|
||||||
'volume.'),
|
'duplicate mapping using --block-device-mapping for this '
|
||||||
|
'volume.'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--password',
|
'--password',
|
||||||
@ -664,28 +666,34 @@ class CreateServer(command.ShowOne):
|
|||||||
metavar='<security-group>',
|
metavar='<security-group>',
|
||||||
action='append',
|
action='append',
|
||||||
default=[],
|
default=[],
|
||||||
help=_('Security group to assign to this server (name or ID) '
|
help=_(
|
||||||
'(repeat option to set multiple groups)'),
|
'Security group to assign to this server (name or ID) '
|
||||||
|
'(repeat option to set multiple groups)'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--key-name',
|
'--key-name',
|
||||||
metavar='<key-name>',
|
metavar='<key-name>',
|
||||||
help=_('Keypair to inject into this server (optional extension)'),
|
help=_('Keypair to inject into this server'),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--property',
|
'--property',
|
||||||
metavar='<key=value>',
|
metavar='<key=value>',
|
||||||
action=parseractions.KeyValueAction,
|
action=parseractions.KeyValueAction,
|
||||||
help=_('Set a property on this server '
|
help=_(
|
||||||
'(repeat option to set multiple values)'),
|
'Set a property on this server '
|
||||||
|
'(repeat option to set multiple values)'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--file',
|
'--file',
|
||||||
metavar='<dest-filename=source-filename>',
|
metavar='<dest-filename=source-filename>',
|
||||||
action='append',
|
action='append',
|
||||||
default=[],
|
default=[],
|
||||||
help=_('File to inject into image before boot '
|
help=_(
|
||||||
'(repeat option to set multiple files)'),
|
'File to inject into image before boot '
|
||||||
|
'(repeat option to set multiple files)'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--user-data',
|
'--user-data',
|
||||||
@ -695,8 +703,10 @@ class CreateServer(command.ShowOne):
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--description',
|
'--description',
|
||||||
metavar='<description>',
|
metavar='<description>',
|
||||||
help=_('Set description for the server (supported by '
|
help=_(
|
||||||
'--os-compute-api-version 2.19 or above)'),
|
'Set description for the server '
|
||||||
|
'(supported by --os-compute-api-version 2.19 or above)'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--availability-zone',
|
'--availability-zone',
|
||||||
@ -706,29 +716,35 @@ class CreateServer(command.ShowOne):
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--host',
|
'--host',
|
||||||
metavar='<host>',
|
metavar='<host>',
|
||||||
help=_('Requested host to create servers. Admin only '
|
help=_(
|
||||||
'by default. (supported by --os-compute-api-version 2.74 '
|
'Requested host to create servers. '
|
||||||
'or above)'),
|
'(admin only) '
|
||||||
|
'(supported by --os-compute-api-version 2.74 or above)'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--hypervisor-hostname',
|
'--hypervisor-hostname',
|
||||||
metavar='<hypervisor-hostname>',
|
metavar='<hypervisor-hostname>',
|
||||||
help=_('Requested hypervisor hostname to create servers. Admin '
|
help=_(
|
||||||
'only by default. (supported by --os-compute-api-version '
|
'Requested hypervisor hostname to create servers. '
|
||||||
'2.74 or above)'),
|
'(admin only) '
|
||||||
|
'(supported by --os-compute-api-version 2.74 or above)'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--boot-from-volume',
|
'--boot-from-volume',
|
||||||
metavar='<volume-size>',
|
metavar='<volume-size>',
|
||||||
type=int,
|
type=int,
|
||||||
help=_('When used in conjunction with the ``--image`` or '
|
help=_(
|
||||||
'``--image-property`` option, this option automatically '
|
'When used in conjunction with the ``--image`` or '
|
||||||
'creates a block device mapping with a boot index of 0 '
|
'``--image-property`` option, this option automatically '
|
||||||
'and tells the compute service to create a volume of the '
|
'creates a block device mapping with a boot index of 0 '
|
||||||
'given size (in GB) from the specified image and use it '
|
'and tells the compute service to create a volume of the '
|
||||||
'as the root disk of the server. The root volume will not '
|
'given size (in GB) from the specified image and use it '
|
||||||
'be deleted when the server is deleted. This option is '
|
'as the root disk of the server. The root volume will not '
|
||||||
'mutually exclusive with the ``--volume`` option.')
|
'be deleted when the server is deleted. This option is '
|
||||||
|
'mutually exclusive with the ``--volume`` option.'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--block-device-mapping',
|
'--block-device-mapping',
|
||||||
@ -738,37 +754,40 @@ class CreateServer(command.ShowOne):
|
|||||||
# NOTE(RuiChen): Add '\n' at the end of line to put each item in
|
# NOTE(RuiChen): Add '\n' at the end of line to put each item in
|
||||||
# the separated line, avoid the help message looks
|
# the separated line, avoid the help message looks
|
||||||
# messy, see _SmartHelpFormatter in cliff.
|
# messy, see _SmartHelpFormatter in cliff.
|
||||||
help=_('Create a block device on the server.\n'
|
help=_(
|
||||||
'Block device mapping in the format\n'
|
'Create a block device on the server.\n'
|
||||||
'<dev-name>=<id>:<type>:<size(GB)>:<delete-on-terminate>\n'
|
'Block device mapping in the format\n'
|
||||||
'<dev-name>: block device name, like: vdb, xvdc '
|
'<dev-name>=<id>:<type>:<size(GB)>:<delete-on-terminate>\n'
|
||||||
'(required)\n'
|
'<dev-name>: block device name, like: vdb, xvdc '
|
||||||
'<id>: Name or ID of the volume, volume snapshot or image '
|
'(required)\n'
|
||||||
'(required)\n'
|
'<id>: Name or ID of the volume, volume snapshot or image '
|
||||||
'<type>: volume, snapshot or image; default: volume '
|
'(required)\n'
|
||||||
'(optional)\n'
|
'<type>: volume, snapshot or image; default: volume '
|
||||||
'<size(GB)>: volume size if create from image or snapshot '
|
'(optional)\n'
|
||||||
'(optional)\n'
|
'<size(GB)>: volume size if create from image or snapshot '
|
||||||
'<delete-on-terminate>: true or false; default: false '
|
'(optional)\n'
|
||||||
'(optional)\n'
|
'<delete-on-terminate>: true or false; default: false '
|
||||||
'(optional extension)'),
|
'(optional)\n'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--nic',
|
'--nic',
|
||||||
metavar="<net-id=net-uuid,v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr,"
|
metavar="<net-id=net-uuid,v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr,"
|
||||||
"port-id=port-uuid,auto,none>",
|
"port-id=port-uuid,auto,none>",
|
||||||
action='append',
|
action='append',
|
||||||
help=_("Create a NIC on the server. "
|
help=_(
|
||||||
"Specify option multiple times to create multiple NICs. "
|
"Create a NIC on the server. "
|
||||||
"Either net-id or port-id must be provided, but not both. "
|
"Specify option multiple times to create multiple NICs. "
|
||||||
"net-id: attach NIC to network with this UUID, "
|
"Either net-id or port-id must be provided, but not both. "
|
||||||
"port-id: attach NIC to port with this UUID, "
|
"net-id: attach NIC to network with this UUID, "
|
||||||
"v4-fixed-ip: IPv4 fixed address for NIC (optional), "
|
"port-id: attach NIC to port with this UUID, "
|
||||||
"v6-fixed-ip: IPv6 fixed address for NIC (optional), "
|
"v4-fixed-ip: IPv4 fixed address for NIC (optional), "
|
||||||
"none: (v2.37+) no network is attached, "
|
"v6-fixed-ip: IPv6 fixed address for NIC (optional), "
|
||||||
"auto: (v2.37+) the compute service will automatically "
|
"none: (v2.37+) no network is attached, "
|
||||||
"allocate a network. Specifying a --nic of auto or none "
|
"auto: (v2.37+) the compute service will automatically "
|
||||||
"cannot be used with any other --nic value."),
|
"allocate a network. Specifying a --nic of auto or none "
|
||||||
|
"cannot be used with any other --nic value."
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--network',
|
'--network',
|
||||||
@ -776,13 +795,15 @@ class CreateServer(command.ShowOne):
|
|||||||
action='append',
|
action='append',
|
||||||
dest='nic',
|
dest='nic',
|
||||||
type=_prefix_checked_value('net-id='),
|
type=_prefix_checked_value('net-id='),
|
||||||
help=_("Create a NIC on the server and connect it to network. "
|
help=_(
|
||||||
"Specify option multiple times to create multiple NICs. "
|
"Create a NIC on the server and connect it to network. "
|
||||||
"This is a wrapper for the '--nic net-id=<network>' "
|
"Specify option multiple times to create multiple NICs. "
|
||||||
"parameter that provides simple syntax for the standard "
|
"This is a wrapper for the '--nic net-id=<network>' "
|
||||||
"use case of connecting a new server to a given network. "
|
"parameter that provides simple syntax for the standard "
|
||||||
"For more advanced use cases, refer to the '--nic' "
|
"use case of connecting a new server to a given network. "
|
||||||
"parameter."),
|
"For more advanced use cases, refer to the '--nic' "
|
||||||
|
"parameter."
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--port',
|
'--port',
|
||||||
@ -790,12 +811,14 @@ class CreateServer(command.ShowOne):
|
|||||||
action='append',
|
action='append',
|
||||||
dest='nic',
|
dest='nic',
|
||||||
type=_prefix_checked_value('port-id='),
|
type=_prefix_checked_value('port-id='),
|
||||||
help=_("Create a NIC on the server and connect it to port. "
|
help=_(
|
||||||
"Specify option multiple times to create multiple NICs. "
|
"Create a NIC on the server and connect it to port. "
|
||||||
"This is a wrapper for the '--nic port-id=<port>' "
|
"Specify option multiple times to create multiple NICs. "
|
||||||
"parameter that provides simple syntax for the standard "
|
"This is a wrapper for the '--nic port-id=<port>' "
|
||||||
"use case of connecting a new server to a given port. For "
|
"parameter that provides simple syntax for the standard "
|
||||||
"more advanced use cases, refer to the '--nic' parameter."),
|
"use case of connecting a new server to a given port. For "
|
||||||
|
"more advanced use cases, refer to the '--nic' parameter."
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--hint',
|
'--hint',
|
||||||
@ -882,10 +905,13 @@ class CreateServer(command.ShowOne):
|
|||||||
if not image and parsed_args.image_property:
|
if not image and parsed_args.image_property:
|
||||||
def emit_duplicated_warning(img, image_property):
|
def emit_duplicated_warning(img, image_property):
|
||||||
img_uuid_list = [str(image.id) for image in img]
|
img_uuid_list = [str(image.id) for image in img]
|
||||||
LOG.warning(_('Multiple matching images: %(img_uuid_list)s\n'
|
LOG.warning(
|
||||||
'Using image: %(chosen_one)s') %
|
'Multiple matching images: %(img_uuid_list)s\n'
|
||||||
{'img_uuid_list': img_uuid_list,
|
'Using image: %(chosen_one)s',
|
||||||
'chosen_one': img_uuid_list[0]})
|
{
|
||||||
|
'img_uuid_list': img_uuid_list,
|
||||||
|
'chosen_one': img_uuid_list[0],
|
||||||
|
})
|
||||||
|
|
||||||
def _match_image(image_api, wanted_properties):
|
def _match_image(image_api, wanted_properties):
|
||||||
image_list = image_api.images()
|
image_list = image_api.images()
|
||||||
@ -902,45 +928,52 @@ class CreateServer(command.ShowOne):
|
|||||||
set([key, value])
|
set([key, value])
|
||||||
except TypeError:
|
except TypeError:
|
||||||
if key != 'properties':
|
if key != 'properties':
|
||||||
LOG.debug('Skipped the \'%s\' attribute. '
|
LOG.debug(
|
||||||
'That cannot be compared. '
|
'Skipped the \'%s\' attribute. '
|
||||||
'(image: %s, value: %s)',
|
'That cannot be compared. '
|
||||||
key, img.id, value)
|
'(image: %s, value: %s)',
|
||||||
|
key, img.id, value,
|
||||||
|
)
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
img_dict[key] = value
|
img_dict[key] = value
|
||||||
|
|
||||||
if all(k in img_dict and img_dict[k] == v
|
if all(
|
||||||
for k, v in wanted_properties.items()):
|
k in img_dict and img_dict[k] == v
|
||||||
|
for k, v in wanted_properties.items()
|
||||||
|
):
|
||||||
images_matched.append(img)
|
images_matched.append(img)
|
||||||
|
|
||||||
return images_matched
|
return images_matched
|
||||||
|
|
||||||
images = _match_image(image_client, parsed_args.image_property)
|
images = _match_image(image_client, parsed_args.image_property)
|
||||||
if len(images) > 1:
|
if len(images) > 1:
|
||||||
emit_duplicated_warning(images,
|
emit_duplicated_warning(images, parsed_args.image_property)
|
||||||
parsed_args.image_property)
|
|
||||||
if images:
|
if images:
|
||||||
image = images[0]
|
image = images[0]
|
||||||
else:
|
else:
|
||||||
raise exceptions.CommandError(_("No images match the "
|
msg = _(
|
||||||
"property expected by "
|
'No images match the property expected by '
|
||||||
"--image-property"))
|
'--image-property'
|
||||||
|
)
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
# Lookup parsed_args.volume
|
# Lookup parsed_args.volume
|
||||||
volume = None
|
volume = None
|
||||||
if parsed_args.volume:
|
if parsed_args.volume:
|
||||||
# --volume and --boot-from-volume are mutually exclusive.
|
# --volume and --boot-from-volume are mutually exclusive.
|
||||||
if parsed_args.boot_from_volume:
|
if parsed_args.boot_from_volume:
|
||||||
raise exceptions.CommandError(
|
msg = _('--volume is not allowed with --boot-from-volume')
|
||||||
_('--volume is not allowed with --boot-from-volume'))
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
volume = utils.find_resource(
|
volume = utils.find_resource(
|
||||||
volume_client.volumes,
|
volume_client.volumes,
|
||||||
parsed_args.volume,
|
parsed_args.volume,
|
||||||
).id
|
).id
|
||||||
|
|
||||||
# Lookup parsed_args.flavor
|
# Lookup parsed_args.flavor
|
||||||
flavor = utils.find_resource(compute_client.flavors,
|
flavor = utils.find_resource(
|
||||||
parsed_args.flavor)
|
compute_client.flavors, parsed_args.flavor)
|
||||||
|
|
||||||
files = {}
|
files = {}
|
||||||
for f in parsed_args.file:
|
for f in parsed_args.file:
|
||||||
@ -950,16 +983,17 @@ class CreateServer(command.ShowOne):
|
|||||||
except IOError as e:
|
except IOError as e:
|
||||||
msg = _("Can't open '%(source)s': %(exception)s")
|
msg = _("Can't open '%(source)s': %(exception)s")
|
||||||
raise exceptions.CommandError(
|
raise exceptions.CommandError(
|
||||||
msg % {"source": src,
|
msg % {'source': src, 'exception': e}
|
||||||
"exception": e}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if parsed_args.min > parsed_args.max:
|
if parsed_args.min > parsed_args.max:
|
||||||
msg = _("min instances should be <= max instances")
|
msg = _("min instances should be <= max instances")
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
if parsed_args.min < 1:
|
if parsed_args.min < 1:
|
||||||
msg = _("min instances should be > 0")
|
msg = _("min instances should be > 0")
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
if parsed_args.max < 1:
|
if parsed_args.max < 1:
|
||||||
msg = _("max instances should be > 0")
|
msg = _("max instances should be > 0")
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
@ -971,8 +1005,7 @@ class CreateServer(command.ShowOne):
|
|||||||
except IOError as e:
|
except IOError as e:
|
||||||
msg = _("Can't open '%(data)s': %(exception)s")
|
msg = _("Can't open '%(data)s': %(exception)s")
|
||||||
raise exceptions.CommandError(
|
raise exceptions.CommandError(
|
||||||
msg % {"data": parsed_args.user_data,
|
msg % {'data': parsed_args.user_data, 'exception': e}
|
||||||
"exception": e}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if parsed_args.description:
|
if parsed_args.description:
|
||||||
@ -983,11 +1016,12 @@ class CreateServer(command.ShowOne):
|
|||||||
|
|
||||||
block_device_mapping_v2 = []
|
block_device_mapping_v2 = []
|
||||||
if volume:
|
if volume:
|
||||||
block_device_mapping_v2 = [{'uuid': volume,
|
block_device_mapping_v2 = [{
|
||||||
'boot_index': '0',
|
'uuid': volume,
|
||||||
'source_type': 'volume',
|
'boot_index': '0',
|
||||||
'destination_type': 'volume'
|
'source_type': 'volume',
|
||||||
}]
|
'destination_type': 'volume'
|
||||||
|
}]
|
||||||
elif parsed_args.boot_from_volume:
|
elif parsed_args.boot_from_volume:
|
||||||
# Tell nova to create a root volume from the image provided.
|
# Tell nova to create a root volume from the image provided.
|
||||||
block_device_mapping_v2 = [{
|
block_device_mapping_v2 = [{
|
||||||
@ -1008,13 +1042,16 @@ class CreateServer(command.ShowOne):
|
|||||||
dev_map = dev_map.split(':')
|
dev_map = dev_map.split(':')
|
||||||
if dev_map[0]:
|
if dev_map[0]:
|
||||||
mapping = {'device_name': dev_name}
|
mapping = {'device_name': dev_name}
|
||||||
|
|
||||||
# 1. decide source and destination type
|
# 1. decide source and destination type
|
||||||
if (len(dev_map) > 1 and
|
if (len(dev_map) > 1 and
|
||||||
dev_map[1] in ('volume', 'snapshot', 'image')):
|
dev_map[1] in ('volume', 'snapshot', 'image')):
|
||||||
mapping['source_type'] = dev_map[1]
|
mapping['source_type'] = dev_map[1]
|
||||||
else:
|
else:
|
||||||
mapping['source_type'] = 'volume'
|
mapping['source_type'] = 'volume'
|
||||||
|
|
||||||
mapping['destination_type'] = 'volume'
|
mapping['destination_type'] = 'volume'
|
||||||
|
|
||||||
# 2. check target exist, update target uuid according by
|
# 2. check target exist, update target uuid according by
|
||||||
# source type
|
# source type
|
||||||
if mapping['source_type'] == 'volume':
|
if mapping['source_type'] == 'volume':
|
||||||
@ -1040,14 +1077,18 @@ class CreateServer(command.ShowOne):
|
|||||||
image_id = image_client.find_image(dev_map[0],
|
image_id = image_client.find_image(dev_map[0],
|
||||||
ignore_missing=False).id
|
ignore_missing=False).id
|
||||||
mapping['uuid'] = image_id
|
mapping['uuid'] = image_id
|
||||||
|
|
||||||
# 3. append size and delete_on_termination if exist
|
# 3. append size and delete_on_termination if exist
|
||||||
if len(dev_map) > 2 and dev_map[2]:
|
if len(dev_map) > 2 and dev_map[2]:
|
||||||
mapping['volume_size'] = dev_map[2]
|
mapping['volume_size'] = dev_map[2]
|
||||||
|
|
||||||
if len(dev_map) > 3 and dev_map[3]:
|
if len(dev_map) > 3 and dev_map[3]:
|
||||||
mapping['delete_on_termination'] = dev_map[3]
|
mapping['delete_on_termination'] = dev_map[3]
|
||||||
else:
|
else:
|
||||||
msg = _("Volume, volume snapshot or image (name or ID) must "
|
msg = _(
|
||||||
"be specified if --block-device-mapping is specified")
|
'Volume, volume snapshot or image (name or ID) must '
|
||||||
|
'be specified if --block-device-mapping is specified'
|
||||||
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
block_device_mapping_v2.append(mapping)
|
block_device_mapping_v2.append(mapping)
|
||||||
|
|
||||||
@ -1061,22 +1102,32 @@ class CreateServer(command.ShowOne):
|
|||||||
auto_or_none = True
|
auto_or_none = True
|
||||||
nics.append(nic_str)
|
nics.append(nic_str)
|
||||||
else:
|
else:
|
||||||
nic_info = {"net-id": "", "v4-fixed-ip": "",
|
nic_info = {
|
||||||
"v6-fixed-ip": "", "port-id": ""}
|
'net-id': '',
|
||||||
|
'v4-fixed-ip': '',
|
||||||
|
'v6-fixed-ip': '',
|
||||||
|
'port-id': '',
|
||||||
|
}
|
||||||
for kv_str in nic_str.split(","):
|
for kv_str in nic_str.split(","):
|
||||||
k, sep, v = kv_str.partition("=")
|
k, sep, v = kv_str.partition("=")
|
||||||
if k in nic_info and v:
|
if k in nic_info and v:
|
||||||
nic_info[k] = v
|
nic_info[k] = v
|
||||||
else:
|
else:
|
||||||
msg = (_("Invalid nic argument '%s'. Nic arguments "
|
msg = _(
|
||||||
"must be of the form --nic <net-id=net-uuid"
|
"Invalid nic argument '%s'. Nic arguments "
|
||||||
",v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr,"
|
"must be of the form --nic <net-id=net-uuid"
|
||||||
"port-id=port-uuid>."))
|
",v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr,"
|
||||||
|
"port-id=port-uuid>."
|
||||||
|
)
|
||||||
raise exceptions.CommandError(msg % k)
|
raise exceptions.CommandError(msg % k)
|
||||||
|
|
||||||
if bool(nic_info["net-id"]) == bool(nic_info["port-id"]):
|
if bool(nic_info["net-id"]) == bool(nic_info["port-id"]):
|
||||||
msg = _("either network or port should be specified "
|
msg = _(
|
||||||
"but not both")
|
'Either network or port should be specified '
|
||||||
|
'but not both'
|
||||||
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
if self.app.client_manager.is_network_endpoint_enabled():
|
if self.app.client_manager.is_network_endpoint_enabled():
|
||||||
network_client = self.app.client_manager.network
|
network_client = self.app.client_manager.network
|
||||||
if nic_info["net-id"]:
|
if nic_info["net-id"]:
|
||||||
@ -1093,17 +1144,22 @@ class CreateServer(command.ShowOne):
|
|||||||
nic_info["net-id"]
|
nic_info["net-id"]
|
||||||
)['id']
|
)['id']
|
||||||
if nic_info["port-id"]:
|
if nic_info["port-id"]:
|
||||||
msg = _("can't create server with port specified "
|
msg = _(
|
||||||
"since network endpoint not enabled")
|
"Can't create server with port specified "
|
||||||
|
"since network endpoint not enabled"
|
||||||
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
nics.append(nic_info)
|
nics.append(nic_info)
|
||||||
|
|
||||||
if nics:
|
if nics:
|
||||||
if auto_or_none:
|
if auto_or_none:
|
||||||
if len(nics) > 1:
|
if len(nics) > 1:
|
||||||
msg = _('Specifying a --nic of auto or none cannot '
|
msg = _(
|
||||||
'be used with any other --nic, --network '
|
'Specifying a --nic of auto or none cannot '
|
||||||
'or --port value.')
|
'be used with any other --nic, --network '
|
||||||
|
'or --port value.'
|
||||||
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
nics = nics[0]
|
nics = nics[0]
|
||||||
else:
|
else:
|
||||||
@ -1185,16 +1241,22 @@ class CreateServer(command.ShowOne):
|
|||||||
|
|
||||||
if parsed_args.host:
|
if parsed_args.host:
|
||||||
if compute_client.api_version < api_versions.APIVersion("2.74"):
|
if compute_client.api_version < api_versions.APIVersion("2.74"):
|
||||||
msg = _("Specifying --host is not supported for "
|
msg = _(
|
||||||
"--os-compute-api-version less than 2.74")
|
'--os-compute-api-version 2.74 or greater is required to '
|
||||||
|
'support the --host option'
|
||||||
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
boot_kwargs['host'] = parsed_args.host
|
boot_kwargs['host'] = parsed_args.host
|
||||||
|
|
||||||
if parsed_args.hypervisor_hostname:
|
if parsed_args.hypervisor_hostname:
|
||||||
if compute_client.api_version < api_versions.APIVersion("2.74"):
|
if compute_client.api_version < api_versions.APIVersion("2.74"):
|
||||||
msg = _("Specifying --hypervisor-hostname is not supported "
|
msg = _(
|
||||||
"for --os-compute-api-version less than 2.74")
|
'--os-compute-api-version 2.74 or greater is required to '
|
||||||
|
'support the --hypervisor-hostname option'
|
||||||
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
boot_kwargs['hypervisor_hostname'] = (
|
boot_kwargs['hypervisor_hostname'] = (
|
||||||
parsed_args.hypervisor_hostname)
|
parsed_args.hypervisor_hostname)
|
||||||
|
|
||||||
@ -1220,8 +1282,7 @@ class CreateServer(command.ShowOne):
|
|||||||
):
|
):
|
||||||
self.app.stdout.write('\n')
|
self.app.stdout.write('\n')
|
||||||
else:
|
else:
|
||||||
LOG.error(_('Error creating server: %s'),
|
LOG.error('Error creating server: %s', parsed_args.server_name)
|
||||||
parsed_args.server_name)
|
|
||||||
self.app.stdout.write(_('Error creating server\n'))
|
self.app.stdout.write(_('Error creating server\n'))
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user