Add server image create command

Translation of 'nova image-create', with tests!

Change-Id: I8a833aeff6f291e4774063ed235876eb2ba9c13c
This commit is contained in:
Dean Troyer 2013-11-18 17:10:39 -06:00
parent 6460f1eb35
commit 200ed62054
5 changed files with 169 additions and 8 deletions

View File

@ -384,6 +384,73 @@ class CreateServer(show.ShowOne):
return zip(*sorted(six.iteritems(details)))
class CreateServerImage(show.ShowOne):
"""Create a new disk image from a running server"""
log = logging.getLogger(__name__ + '.CreateServerImage')
def get_parser(self, prog_name):
parser = super(CreateServerImage, self).get_parser(prog_name)
parser.add_argument(
'server',
metavar='<server',
help='Server (name or ID)',
)
parser.add_argument(
'--name',
metavar='<image-name>',
help='Name of new image (default is server name)',
)
parser.add_argument(
'--wait',
action='store_true',
help='Wait for image create to complete',
)
return parser
def take_action(self, parsed_args):
self.log.debug('take_action(%s)' % parsed_args)
compute_client = self.app.client_manager.compute
image_client = self.app.client_manager.image
server = utils.find_resource(
compute_client.servers,
parsed_args.server,
)
if parsed_args.name:
name = parsed_args.name
else:
name = server.name
image = compute_client.servers.create_image(
server,
name,
)
if parsed_args.wait:
if utils.wait_for_status(
image_client.images.get,
image,
callback=_show_progress,
):
sys.stdout.write('\n')
else:
self.log.error(
'Error creating server snapshot: %s' %
parsed_args.image_name,
)
sys.stdout.write('\nError creating server snapshot')
raise SystemExit
image = utils.find_resource(
image_client.images,
image.id,
)
info = {}
info.update(image._info)
return zip(*sorted(six.iteritems(info)))
class DeleteServer(command.Command):
"""Delete server command"""

View File

@ -16,16 +16,10 @@
import mock
from openstackclient.tests import fakes
from openstackclient.tests.image.v2 import fakes as image_fakes
from openstackclient.tests import utils
image_id = 'im1'
IMAGE = {
'id': image_id,
}
server_id = 'serv1'
server_name = 'waiter'
@ -53,3 +47,8 @@ class TestComputev2(utils.TestCommand):
endpoint=fakes.AUTH_URL,
token=fakes.AUTH_TOKEN,
)
self.app.client_manager.image = image_fakes.FakeImagev2Client(
endpoint=fakes.AUTH_URL,
token=fakes.AUTH_TOKEN,
)

View File

@ -18,6 +18,7 @@ import copy
from openstackclient.compute.v2 import server
from openstackclient.tests.compute.v2 import fakes as compute_fakes
from openstackclient.tests import fakes
from openstackclient.tests.image.v2 import fakes as image_fakes
class TestServer(compute_fakes.TestComputev2):
@ -29,6 +30,10 @@ class TestServer(compute_fakes.TestComputev2):
self.servers_mock = self.app.client_manager.compute.servers
self.servers_mock.reset_mock()
# Get a shortcut to the ImageManager Mock
self.images_mock = self.app.client_manager.image.images
self.images_mock.reset_mock()
class TestServerDelete(TestServer):
@ -61,3 +66,89 @@ class TestServerDelete(TestServer):
self.servers_mock.delete.assert_called_with(
compute_fakes.server_id,
)
class TestServerImageCreate(TestServer):
def setUp(self):
super(TestServerImageCreate, self).setUp()
# This is the return value for utils.find_resource()
self.servers_mock.get.return_value = fakes.FakeResource(
None,
copy.deepcopy(compute_fakes.SERVER),
loaded=True,
)
self.servers_mock.create_image.return_value = fakes.FakeResource(
None,
copy.deepcopy(image_fakes.IMAGE),
loaded=True,
)
self.images_mock.get.return_value = fakes.FakeResource(
None,
copy.deepcopy(image_fakes.IMAGE),
loaded=True,
)
# Get the command object to test
self.cmd = server.CreateServerImage(self.app, None)
def test_server_image_create_no_options(self):
arglist = [
compute_fakes.server_id,
]
verifylist = [
('server', compute_fakes.server_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
# ServerManager.create_image(server, image_name, metadata=)
self.servers_mock.create_image.assert_called_with(
self.servers_mock.get.return_value,
compute_fakes.server_name,
)
collist = ('id', 'is_public', 'name', 'owner')
self.assertEqual(columns, collist)
datalist = (
image_fakes.image_id,
False,
image_fakes.image_name,
image_fakes.image_owner,
)
self.assertEqual(data, datalist)
def test_server_image_create_name(self):
arglist = [
'--name', 'img-nam',
compute_fakes.server_id,
]
verifylist = [
('name', 'img-nam'),
('server', compute_fakes.server_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
columns, data = self.cmd.take_action(parsed_args)
# ServerManager.create_image(server, image_name, metadata=)
self.servers_mock.create_image.assert_called_with(
self.servers_mock.get.return_value,
'img-nam',
)
collist = ('id', 'is_public', 'name', 'owner')
self.assertEqual(columns, collist)
datalist = (
image_fakes.image_id,
False,
image_fakes.image_name,
image_fakes.image_owner,
)
self.assertEqual(data, datalist)

View File

@ -21,10 +21,13 @@ from openstackclient.tests import utils
image_id = 'im1'
image_name = 'graven'
image_owner = 'baal'
IMAGE = {
'id': image_id,
'name': image_name
'name': image_name,
'is_public': False,
'owner': image_owner,
}

View File

@ -94,6 +94,7 @@ openstack.compute.v2 =
server_add_volume = openstackclient.compute.v2.server:AddServerVolume
server_create = openstackclient.compute.v2.server:CreateServer
server_delete = openstackclient.compute.v2.server:DeleteServer
server_image_create = openstackclient.compute.v2.server:CreateServerImage
server_list = openstackclient.compute.v2.server:ListServer
server_lock = openstackclient.compute.v2.server:LockServer
server_migrate = openstackclient.compute.v2.server:MigrateServer