summaryrefslogtreecommitdiff
path: root/openstackclient/compute
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient/compute')
-rw-r--r--openstackclient/compute/v2/console.py7
-rw-r--r--openstackclient/compute/v2/flavor.py28
-rw-r--r--openstackclient/compute/v2/host.py18
-rw-r--r--openstackclient/compute/v2/server.py225
-rw-r--r--openstackclient/compute/v2/server_backup.py16
-rw-r--r--openstackclient/compute/v2/server_image.py15
-rw-r--r--openstackclient/compute/v2/service.py26
-rw-r--r--openstackclient/compute/v2/usage.py8
8 files changed, 244 insertions, 99 deletions
diff --git a/openstackclient/compute/v2/console.py b/openstackclient/compute/v2/console.py
index 25f92108..b2f7288f 100644
--- a/openstackclient/compute/v2/console.py
+++ b/openstackclient/compute/v2/console.py
@@ -15,8 +15,6 @@
"""Compute v2 Console action implementations"""
-import sys
-
from osc_lib.cli import parseractions
from osc_lib.command import command
from osc_lib import utils
@@ -60,7 +58,10 @@ class ShowConsoleLog(command.Command):
length += 1
data = server.get_console_output(length=length)
- sys.stdout.write(data)
+
+ if data and data[-1] != '\n':
+ data += '\n'
+ self.app.stdout.write(data)
class ShowConsoleURL(command.ShowOne):
diff --git a/openstackclient/compute/v2/flavor.py b/openstackclient/compute/v2/flavor.py
index 0f5dd742..2cc5f1e8 100644
--- a/openstackclient/compute/v2/flavor.py
+++ b/openstackclient/compute/v2/flavor.py
@@ -17,6 +17,7 @@
import logging
+from novaclient import api_versions
from osc_lib.cli import parseractions
from osc_lib.command import command
from osc_lib import exceptions
@@ -134,6 +135,12 @@ class CreateFlavor(command.ShowOne):
help=_("Allow <project> to access private flavor (name or ID) "
"(Must be used with --private option)"),
)
+ parser.add_argument(
+ '--description',
+ metavar='<description>',
+ help=_("Description for the flavor.(Supported by API versions "
+ "'2.55' - '2.latest'")
+ )
identity_common.add_project_domain_option_to_parser(parser)
return parser
@@ -145,6 +152,11 @@ class CreateFlavor(command.ShowOne):
msg = _("--project is only allowed with --private")
raise exceptions.CommandError(msg)
+ if parsed_args.description:
+ if compute_client.api_version < api_versions.APIVersion("2.55"):
+ msg = _("--os-compute-api-version 2.55 or later is required")
+ raise exceptions.CommandError(msg)
+
args = (
parsed_args.name,
parsed_args.ram,
@@ -154,7 +166,8 @@ class CreateFlavor(command.ShowOne):
parsed_args.ephemeral,
parsed_args.swap,
parsed_args.rxtx_factor,
- parsed_args.public
+ parsed_args.public,
+ parsed_args.description
)
flavor = compute_client.flavors.create(*args)
@@ -332,6 +345,12 @@ class SetFlavor(command.Command):
help=_('Set flavor access to project (name or ID) '
'(admin only)'),
)
+ parser.add_argument(
+ '--description',
+ metavar='<description>',
+ help=_("Set description for the flavor.(Supported by API "
+ "versions '2.55' - '2.latest'")
+ )
identity_common.add_project_domain_option_to_parser(parser)
return parser
@@ -380,6 +399,13 @@ class SetFlavor(command.Command):
raise exceptions.CommandError(_("Command Failed: One or more of"
" the operations failed"))
+ if parsed_args.description:
+ if compute_client.api_version < api_versions.APIVersion("2.55"):
+ msg = _("--os-compute-api-version 2.55 or later is required")
+ raise exceptions.CommandError(msg)
+ compute_client.flavors.update(flavor=parsed_args.flavor,
+ description=parsed_args.description)
+
class ShowFlavor(command.ShowOne):
_description = _("Display flavor details")
diff --git a/openstackclient/compute/v2/host.py b/openstackclient/compute/v2/host.py
index a495b367..9fdfd927 100644
--- a/openstackclient/compute/v2/host.py
+++ b/openstackclient/compute/v2/host.py
@@ -40,9 +40,9 @@ class ListHost(command.Lister):
"Service",
"Zone"
)
- data = compute_client.hosts.list_all(parsed_args.zone)
+ data = compute_client.api.host_list(parsed_args.zone)
return (columns,
- (utils.get_item_properties(
+ (utils.get_dict_properties(
s, columns,
) for s in data))
@@ -95,13 +95,7 @@ class SetHost(command.Command):
compute_client = self.app.client_manager.compute
- # More than one hosts will be returned by using find_resource()
- # so that the return value cannot be used in host update() method.
- # find_resource() is just used for checking existence of host and
- # keeping the exception message consistent with other commands.
- utils.find_resource(compute_client.hosts, parsed_args.host)
-
- compute_client.hosts.update(
+ compute_client.api.host_set(
parsed_args.host,
kwargs
)
@@ -128,8 +122,10 @@ class ShowHost(command.Lister):
"Memory MB",
"Disk GB"
)
- data = compute_client.hosts.get(parsed_args.host)
+
+ data = compute_client.api.host_show(parsed_args.host)
+
return (columns,
- (utils.get_item_properties(
+ (utils.get_dict_properties(
s, columns,
) for s in data))
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index f40fbdf6..b82f895c 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -20,7 +20,6 @@ import getpass
import io
import logging
import os
-import sys
from novaclient.v2 import servers
from osc_lib.cli import parseractions
@@ -32,6 +31,7 @@ import six
from openstackclient.i18n import _
from openstackclient.identity import common as identity_common
+from openstackclient.network import common as network_common
LOG = logging.getLogger(__name__)
@@ -120,17 +120,21 @@ def _prefix_checked_value(prefix):
return func
-def _prep_server_detail(compute_client, image_client, server):
+def _prep_server_detail(compute_client, image_client, server, refresh=True):
"""Prepare the detailed server dict for printing
:param compute_client: a compute client instance
+ :param image_client: an image client instance
:param server: a Server resource
+ :param refresh: Flag indicating if ``server`` is already the latest version
+ or if it needs to be refreshed, for example when showing
+ the latest details of a server after creating it.
:rtype: a dict of server details
"""
- info = server._info.copy()
-
- server = utils.find_resource(compute_client.servers, info['id'])
- info.update(server._info)
+ info = server.to_dict()
+ if refresh:
+ server = utils.find_resource(compute_client.servers, info['id'])
+ info.update(server.to_dict())
# Convert the image blob to a name
image_info = info.get('image', {})
@@ -144,12 +148,18 @@ def _prep_server_detail(compute_client, image_client, server):
# Convert the flavor blob to a name
flavor_info = info.get('flavor', {})
- flavor_id = flavor_info.get('id', '')
- try:
- flavor = utils.find_resource(compute_client.flavors, flavor_id)
- info['flavor'] = "%s (%s)" % (flavor.name, flavor_id)
- except Exception:
- info['flavor'] = flavor_id
+ # Microversion 2.47 puts the embedded flavor into the server response
+ # body but omits the id, so if not present we just expose the flavor
+ # dict in the server output.
+ if 'id' in flavor_info:
+ flavor_id = flavor_info.get('id', '')
+ try:
+ flavor = utils.find_resource(compute_client.flavors, flavor_id)
+ info['flavor'] = "%s (%s)" % (flavor.name, flavor_id)
+ except Exception:
+ info['flavor'] = flavor_id
+ else:
+ info['flavor'] = utils.format_dict(flavor_info)
if 'os-extended-volumes:volumes_attached' in info:
info.update(
@@ -178,7 +188,7 @@ def _prep_server_detail(compute_client, image_client, server):
if 'tenant_id' in info:
info['project_id'] = info.pop('tenant_id')
- # Map power state num to meanful string
+ # Map power state num to meaningful string
if 'OS-EXT-STS:power_state' in info:
info['OS-EXT-STS:power_state'] = _format_servers_list_power_state(
info['OS-EXT-STS:power_state'])
@@ -189,12 +199,6 @@ def _prep_server_detail(compute_client, image_client, server):
return info
-def _show_progress(progress):
- if progress:
- sys.stdout.write('\rProgress: %s' % progress)
- sys.stdout.flush()
-
-
class AddFixedIP(command.Command):
_description = _("Add fixed IP address to server")
@@ -234,11 +238,10 @@ class AddFixedIP(command.Command):
)
-class AddFloatingIP(command.Command):
+class AddFloatingIP(network_common.NetworkAndComputeCommand):
_description = _("Add floating IP address to server")
- def get_parser(self, prog_name):
- parser = super(AddFloatingIP, self).get_parser(prog_name)
+ def update_parser_common(self, parser):
parser.add_argument(
"server",
metavar="<server>",
@@ -252,19 +255,37 @@ class AddFloatingIP(command.Command):
parser.add_argument(
"--fixed-ip-address",
metavar="<ip-address>",
- help=_("Fixed IP address to associate with this floating IP "
- "address"),
+ help=_(
+ "Fixed IP address to associate with this floating IP address"
+ ),
)
return parser
- def take_action(self, parsed_args):
+ def take_action_network(self, client, parsed_args):
compute_client = self.app.client_manager.compute
+ attrs = {}
+ obj = client.find_ip(
+ parsed_args.ip_address,
+ ignore_missing=False,
+ )
server = utils.find_resource(
- compute_client.servers, parsed_args.server)
+ compute_client.servers,
+ parsed_args.server,
+ )
+ port = list(client.ports(device_id=server.id))[0]
+ attrs['port_id'] = port.id
+ if parsed_args.fixed_ip_address:
+ attrs['fixed_ip_address'] = parsed_args.fixed_ip_address
- server.add_floating_ip(parsed_args.ip_address,
- parsed_args.fixed_ip_address)
+ client.update_ip(obj, **attrs)
+
+ def take_action_compute(self, client, parsed_args):
+ client.api.floating_ip_add(
+ parsed_args.server,
+ parsed_args.ip_address,
+ fixed_address=parsed_args.fixed_ip_address,
+ )
class AddPort(command.Command):
@@ -425,6 +446,12 @@ class CreateServer(command.ShowOne):
help=_('Create server boot disk from this image (name or ID)'),
)
disk_group.add_argument(
+ '--image-property',
+ metavar='<key=value>',
+ action=parseractions.KeyValueAction,
+ help=_("Image property to be matched"),
+ )
+ disk_group.add_argument(
'--volume',
metavar='<volume>',
help=_('Create server using this volume as the boot disk (name '
@@ -580,6 +607,12 @@ class CreateServer(command.ShowOne):
return parser
def take_action(self, parsed_args):
+
+ def _show_progress(progress):
+ if progress:
+ self.app.stdout.write('\rProgress: %s' % progress)
+ self.app.stdout.flush()
+
compute_client = self.app.client_manager.compute
volume_client = self.app.client_manager.volume
image_client = self.app.client_manager.image
@@ -592,6 +625,45 @@ class CreateServer(command.ShowOne):
parsed_args.image,
)
+ if not image and parsed_args.image_property:
+ def emit_duplicated_warning(img, image_property):
+ img_uuid_list = [str(image.id) for image in img]
+ LOG.warning(_('Multiple matching images: %(img_uuid_list)s\n'
+ 'Using image: %(chosen_one)s') %
+ {'img_uuid_list': img_uuid_list,
+ 'chosen_one': img_uuid_list[0]})
+
+ def _match_image(image_api, wanted_properties):
+ image_list = image_api.image_list()
+ images_matched = []
+ for img in image_list:
+ img_dict = {}
+ # exclude any unhashable entries
+ for key, value in img.items():
+ try:
+ set([key, value])
+ except TypeError:
+ pass
+ else:
+ img_dict[key] = value
+ if all(k in img_dict and img_dict[k] == v
+ for k, v in wanted_properties.items()):
+ images_matched.append(img)
+ else:
+ return []
+ return images_matched
+
+ images = _match_image(image_client.api, parsed_args.image_property)
+ if len(images) > 1:
+ emit_duplicated_warning(images,
+ parsed_args.image_property)
+ if images:
+ image = images[0]
+ else:
+ raise exceptions.CommandError(_("No images match the "
+ "property expected by "
+ "--image-property"))
+
# Lookup parsed_args.volume
volume = None
if parsed_args.volume:
@@ -814,11 +886,11 @@ class CreateServer(command.ShowOne):
server.id,
callback=_show_progress,
):
- sys.stdout.write('\n')
+ self.app.stdout.write('\n')
else:
LOG.error(_('Error creating server: %s'),
parsed_args.server_name)
- sys.stdout.write(_('Error creating server\n'))
+ self.app.stdout.write(_('Error creating server\n'))
raise SystemExit
details = _prep_server_detail(compute_client, image_client, server)
@@ -872,6 +944,12 @@ class DeleteServer(command.Command):
return parser
def take_action(self, parsed_args):
+
+ def _show_progress(progress):
+ if progress:
+ self.app.stdout.write('\rProgress: %s' % progress)
+ self.app.stdout.flush()
+
compute_client = self.app.client_manager.compute
for server in parsed_args.server:
server_obj = utils.find_resource(
@@ -883,11 +961,11 @@ class DeleteServer(command.Command):
server_obj.id,
callback=_show_progress,
):
- sys.stdout.write('\n')
+ self.app.stdout.write('\n')
else:
LOG.error(_('Error deleting server: %s'),
server_obj.id)
- sys.stdout.write(_('Error deleting server\n'))
+ self.app.stdout.write(_('Error deleting server\n'))
raise SystemExit
@@ -1185,6 +1263,10 @@ class ListServer(command.Lister):
s.flavor_name = flavor.name
s.flavor_id = s.flavor['id']
else:
+ # TODO(mriedem): Fix this for microversion >= 2.47 where the
+ # flavor is embedded in the server response without the id.
+ # We likely need to drop the Flavor ID column in that case if
+ # --long is specified.
s.flavor_name = ''
s.flavor_id = ''
@@ -1290,6 +1372,11 @@ class MigrateServer(command.Command):
def take_action(self, parsed_args):
+ def _show_progress(progress):
+ if progress:
+ self.app.stdout.write('\rProgress: %s' % progress)
+ self.app.stdout.flush()
+
compute_client = self.app.client_manager.compute
server = utils.find_resource(
@@ -1313,13 +1400,14 @@ class MigrateServer(command.Command):
if utils.wait_for_status(
compute_client.servers.get,
server.id,
+ success_status=['active', 'verify_resize'],
callback=_show_progress,
):
- sys.stdout.write(_('Complete\n'))
+ self.app.stdout.write(_('Complete\n'))
else:
LOG.error(_('Error migrating server: %s'),
server.id)
- sys.stdout.write(_('Error migrating server\n'))
+ self.app.stdout.write(_('Error migrating server\n'))
raise SystemExit
@@ -1380,6 +1468,12 @@ class RebootServer(command.Command):
return parser
def take_action(self, parsed_args):
+
+ def _show_progress(progress):
+ if progress:
+ self.app.stdout.write('\rProgress: %s' % progress)
+ self.app.stdout.flush()
+
compute_client = self.app.client_manager.compute
server = utils.find_resource(
compute_client.servers, parsed_args.server)
@@ -1391,11 +1485,11 @@ class RebootServer(command.Command):
server.id,
callback=_show_progress,
):
- sys.stdout.write(_('Complete\n'))
+ self.app.stdout.write(_('Complete\n'))
else:
LOG.error(_('Error rebooting server: %s'),
server.id)
- sys.stdout.write(_('Error rebooting server\n'))
+ self.app.stdout.write(_('Error rebooting server\n'))
raise SystemExit
@@ -1428,6 +1522,12 @@ class RebuildServer(command.ShowOne):
return parser
def take_action(self, parsed_args):
+
+ def _show_progress(progress):
+ if progress:
+ self.app.stdout.write('\rProgress: %s' % progress)
+ self.app.stdout.flush()
+
compute_client = self.app.client_manager.compute
image_client = self.app.client_manager.image
@@ -1435,7 +1535,8 @@ class RebuildServer(command.ShowOne):
compute_client.servers, parsed_args.server)
# If parsed_args.image is not set, default to the currently used one.
- image_id = parsed_args.image or server._info.get('image', {}).get('id')
+ image_id = parsed_args.image or server.to_dict().get(
+ 'image', {}).get('id')
image = utils.find_resource(image_client.images, image_id)
server = server.rebuild(image, parsed_args.password)
@@ -1445,14 +1546,15 @@ class RebuildServer(command.ShowOne):
server.id,
callback=_show_progress,
):
- sys.stdout.write(_('Complete\n'))
+ self.app.stdout.write(_('Complete\n'))
else:
LOG.error(_('Error rebuilding server: %s'),
server.id)
- sys.stdout.write(_('Error rebuilding server\n'))
+ self.app.stdout.write(_('Error rebuilding server\n'))
raise SystemExit
- details = _prep_server_detail(compute_client, image_client, server)
+ details = _prep_server_detail(compute_client, image_client, server,
+ refresh=False)
return zip(*sorted(six.iteritems(details)))
@@ -1482,11 +1584,10 @@ class RemoveFixedIP(command.Command):
server.remove_fixed_ip(parsed_args.ip_address)
-class RemoveFloatingIP(command.Command):
+class RemoveFloatingIP(network_common.NetworkAndComputeCommand):
_description = _("Remove floating IP address from server")
- def get_parser(self, prog_name):
- parser = super(RemoveFloatingIP, self).get_parser(prog_name)
+ def update_parser_common(self, parser):
parser.add_argument(
"server",
metavar="<server>",
@@ -1501,13 +1602,21 @@ class RemoveFloatingIP(command.Command):
)
return parser
- def take_action(self, parsed_args):
- compute_client = self.app.client_manager.compute
+ def take_action_network(self, client, parsed_args):
+ attrs = {}
+ obj = client.find_ip(
+ parsed_args.ip_address,
+ ignore_missing=False,
+ )
+ attrs['port_id'] = None
- server = utils.find_resource(
- compute_client.servers, parsed_args.server)
+ client.update_ip(obj, **attrs)
- server.remove_floating_ip(parsed_args.ip_address)
+ def take_action_compute(self, client, parsed_args):
+ client.api.floating_ip_remove(
+ parsed_args.server,
+ parsed_args.ip_address,
+ )
class RemovePort(command.Command):
@@ -1727,6 +1836,11 @@ the new server and restart the old one.""")
def take_action(self, parsed_args):
+ def _show_progress(progress):
+ if progress:
+ self.app.stdout.write('\rProgress: %s' % progress)
+ self.app.stdout.flush()
+
compute_client = self.app.client_manager.compute
server = utils.find_resource(
compute_client.servers,
@@ -1745,11 +1859,11 @@ the new server and restart the old one.""")
success_status=['active', 'verify_resize'],
callback=_show_progress,
):
- sys.stdout.write(_('Complete\n'))
+ self.app.stdout.write(_('Complete\n'))
else:
LOG.error(_('Error resizing server: %s'),
server.id)
- sys.stdout.write(_('Error resizing server\n'))
+ self.app.stdout.write(_('Error resizing server\n'))
raise SystemExit
elif parsed_args.confirm:
compute_client.servers.confirm_resize(server)
@@ -1890,7 +2004,9 @@ class ShelveServer(command.Command):
class ShowServer(command.ShowOne):
- _description = _("Show server details")
+ _description = _(
+ "Show server details. Specify ``--os-compute-api-version 2.47`` "
+ "or higher to see the embedded flavor information for the server.")
def get_parser(self, prog_name):
parser = super(ShowServer, self).get_parser(prog_name)
@@ -1915,11 +2031,14 @@ class ShowServer(command.ShowOne):
if parsed_args.diagnostics:
(resp, data) = server.diagnostics()
if not resp.status_code == 200:
- sys.stderr.write(_("Error retrieving diagnostics data\n"))
+ self.app.stderr.write(_(
+ "Error retrieving diagnostics data\n"
+ ))
return ({}, {})
else:
data = _prep_server_detail(compute_client,
- self.app.client_manager.image, server)
+ self.app.client_manager.image, server,
+ refresh=False)
return zip(*sorted(six.iteritems(data)))
diff --git a/openstackclient/compute/v2/server_backup.py b/openstackclient/compute/v2/server_backup.py
index ddcf9101..a79f5f70 100644
--- a/openstackclient/compute/v2/server_backup.py
+++ b/openstackclient/compute/v2/server_backup.py
@@ -15,8 +15,6 @@
"""Compute v2 Server action implementations"""
-import sys
-
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -26,12 +24,6 @@ import six
from openstackclient.i18n import _
-def _show_progress(progress):
- if progress:
- sys.stderr.write('\rProgress: %s' % progress)
- sys.stderr.flush()
-
-
class CreateServerBackup(command.ShowOne):
_description = _("Create a server backup image")
@@ -74,6 +66,12 @@ class CreateServerBackup(command.ShowOne):
return parser
def take_action(self, parsed_args):
+
+ def _show_progress(progress):
+ if progress:
+ self.app.stderr.write('\rProgress: %s' % progress)
+ self.app.stderr.flush()
+
compute_client = self.app.client_manager.compute
server = utils.find_resource(
@@ -114,7 +112,7 @@ class CreateServerBackup(command.ShowOne):
image.id,
callback=_show_progress,
):
- sys.stdout.write('\n')
+ self.app.stdout.write('\n')
else:
msg = _('Error creating server backup: %s') % parsed_args.name
raise exceptions.CommandError(msg)
diff --git a/openstackclient/compute/v2/server_image.py b/openstackclient/compute/v2/server_image.py
index c66e0674..3bc5d94a 100644
--- a/openstackclient/compute/v2/server_image.py
+++ b/openstackclient/compute/v2/server_image.py
@@ -16,7 +16,6 @@
"""Compute v2 Server action implementations"""
import logging
-import sys
from osc_lib.command import command
from osc_lib import exceptions
@@ -30,12 +29,6 @@ from openstackclient.i18n import _
LOG = logging.getLogger(__name__)
-def _show_progress(progress):
- if progress:
- sys.stdout.write('\rProgress: %s' % progress)
- sys.stdout.flush()
-
-
class CreateServerImage(command.ShowOne):
_description = _("Create a new server disk image from an existing server")
@@ -64,6 +57,12 @@ class CreateServerImage(command.ShowOne):
return parser
def take_action(self, parsed_args):
+
+ def _show_progress(progress):
+ if progress:
+ self.app.stdout.write('\rProgress: %s' % progress)
+ self.app.stdout.flush()
+
compute_client = self.app.client_manager.compute
server = utils.find_resource(
@@ -92,7 +91,7 @@ class CreateServerImage(command.ShowOne):
image_id,
callback=_show_progress,
):
- sys.stdout.write('\n')
+ self.app.stdout.write('\n')
else:
LOG.error(_('Error creating server image: %s'),
parsed_args.server)
diff --git a/openstackclient/compute/v2/service.py b/openstackclient/compute/v2/service.py
index 7331d29d..18e6d9d9 100644
--- a/openstackclient/compute/v2/service.py
+++ b/openstackclient/compute/v2/service.py
@@ -17,6 +17,7 @@
import logging
+from novaclient import api_versions
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
@@ -192,18 +193,23 @@ class SetService(command.Command):
result += 1
force_down = None
- try:
- if parsed_args.down:
- force_down = True
- if parsed_args.up:
- force_down = False
- if force_down is not None:
+ if parsed_args.down:
+ force_down = True
+ if parsed_args.up:
+ force_down = False
+ if force_down is not None:
+ if compute_client.api_version < api_versions.APIVersion(
+ '2.11'):
+ msg = _('--os-compute-api-version 2.11 or later is '
+ 'required')
+ raise exceptions.CommandError(msg)
+ try:
cs.force_down(parsed_args.host, parsed_args.service,
force_down=force_down)
- except Exception:
- state = "down" if force_down else "up"
- LOG.error("Failed to set service state to %s", state)
- result += 1
+ except Exception:
+ state = "down" if force_down else "up"
+ LOG.error("Failed to set service state to %s", state)
+ result += 1
if result > 0:
msg = _("Compute service %(service)s of host %(host)s failed to "
diff --git a/openstackclient/compute/v2/usage.py b/openstackclient/compute/v2/usage.py
index 3edcffe4..4320bf90 100644
--- a/openstackclient/compute/v2/usage.py
+++ b/openstackclient/compute/v2/usage.py
@@ -16,7 +16,6 @@
"""Usage action implementations"""
import datetime
-import sys
from osc_lib.command import command
from osc_lib import utils
@@ -96,7 +95,7 @@ class ListUsage(command.Lister):
pass
if parsed_args.formatter == 'table' and len(usage_list) > 0:
- sys.stdout.write(_("Usage from %(start)s to %(end)s: \n") % {
+ self.app.stdout.write(_("Usage from %(start)s to %(end)s: \n") % {
"start": start.strftime(dateformat),
"end": end.strftime(dateformat),
})
@@ -168,8 +167,9 @@ class ShowUsage(command.ShowOne):
usage = compute_client.usage.get(project, start, end)
if parsed_args.formatter == 'table':
- sys.stdout.write(_("Usage from %(start)s to %(end)s on "
- "project %(project)s: \n") % {
+ self.app.stdout.write(_(
+ "Usage from %(start)s to %(end)s on project %(project)s: \n"
+ ) % {
"start": start.strftime(dateformat),
"end": end.strftime(dateformat),
"project": project,