@@ -116,7 +116,6 @@ class CreateImage(show.ShowOne):
116116
117117 def get_parser (self , prog_name ):
118118 parser = super (CreateImage , self ).get_parser (prog_name )
119- # TODO(mordred): add --volume and --force parameters and support
120119 # TODO(bunting): There are additional arguments that v1 supported
121120 # that v2 either doesn't support or supports weirdly.
122121 # --checksum - could be faked clientside perhaps?
@@ -166,6 +165,19 @@ def get_parser(self, prog_name):
166165 metavar = "<file>" ,
167166 help = "Upload image from local file" ,
168167 )
168+ parser .add_argument (
169+ "--volume" ,
170+ metavar = "<volume>" ,
171+ help = "Create image from a volume" ,
172+ )
173+ parser .add_argument (
174+ "--force" ,
175+ dest = 'force' ,
176+ action = 'store_true' ,
177+ default = False ,
178+ help = "Force image creation if volume is in use "
179+ "(only meaningful with --volume)" ,
180+ )
169181 protected_group = parser .add_mutually_exclusive_group ()
170182 protected_group .add_argument (
171183 "--protected" ,
@@ -241,6 +253,7 @@ def take_action(self, parsed_args):
241253 if getattr (parsed_args , 'properties' , None ):
242254 for k , v in six .iteritems (parsed_args .properties ):
243255 kwargs [k ] = str (v )
256+
244257 # Handle exclusive booleans with care
245258 # Avoid including attributes in kwargs if an option is not
246259 # present on the command line. These exclusive booleans are not
@@ -259,12 +272,33 @@ def take_action(self, parsed_args):
259272 # open the file first to ensure any failures are handled before the
260273 # image is created
261274 fp = gc_utils .get_data_file (parsed_args )
275+ info = {}
276+ if fp is not None and parsed_args .volume :
277+ raise exceptions .CommandError ("Uploading data and using container "
278+ "are not allowed at the same time" )
262279
263280 if fp is None and parsed_args .file :
264281 self .log .warning ("Failed to get an image file." )
265282 return {}, {}
266283
267- image = image_client .images .create (** kwargs )
284+ # If a volume is specified.
285+ if parsed_args .volume :
286+ volume_client = self .app .client_manager .volume
287+ source_volume = utils .find_resource (
288+ volume_client .volumes ,
289+ parsed_args .volume ,
290+ )
291+ response , body = volume_client .volumes .upload_to_image (
292+ source_volume .id ,
293+ parsed_args .force ,
294+ parsed_args .name ,
295+ parsed_args .container_format ,
296+ parsed_args .disk_format ,
297+ )
298+ info = body ['os-volume_upload_image' ]
299+ info ['volume_type' ] = info ['volume_type' ]['name' ]
300+ else :
301+ image = image_client .images .create (** kwargs )
268302
269303 if fp is not None :
270304 with fp :
@@ -285,7 +319,9 @@ def take_action(self, parsed_args):
285319 # update the image after the data has been uploaded
286320 image = image_client .images .get (image .id )
287321
288- info = _format_image (image )
322+ if not info :
323+ info = _format_image (image )
324+
289325 return zip (* sorted (six .iteritems (info )))
290326
291327
@@ -535,8 +571,8 @@ def get_parser(self, prog_name):
535571 # --location - maybe location add?
536572 # --copy-from - does not exist in v2
537573 # --file - should be able to upload file
538- # --volume - needs adding
539- # --force - needs adding
574+ # --volume - not possible with v2 as can't change id
575+ # --force - see `--volume`
540576 # --checksum - maybe could be done client side
541577 # --stdin - could be implemented
542578 parser .add_argument (
0 commit comments