@@ -614,6 +614,93 @@ def test_server_boot_with_bdm_snapshot(self):
614614 # the attached volume had been deleted
615615 pass
616616
617+ def test_server_boot_with_bdm_image (self ):
618+ # Tests creating a server where the root disk is backed by the given
619+ # --image but a --block-device-mapping with type=image is provided so
620+ # that the compute service creates a volume from that image and
621+ # attaches it as a non-root volume on the server. The block device is
622+ # marked as delete_on_termination=True so it will be automatically
623+ # deleted when the server is deleted.
624+
625+ # create server with bdm type=image
626+ # NOTE(mriedem): This test is a bit unrealistic in that specifying the
627+ # same image in the block device as the --image option does not really
628+ # make sense, but we just want to make sure everything is processed
629+ # as expected where nova creates a volume from the image and attaches
630+ # that volume to the server.
631+ server_name = uuid .uuid4 ().hex
632+ server = json .loads (self .openstack (
633+ 'server create -f json ' +
634+ '--flavor ' + self .flavor_name + ' ' +
635+ '--image ' + self .image_name + ' ' +
636+ '--block-device-mapping '
637+ # This means create a 1GB volume from the specified image, attach
638+ # it to the server at /dev/vdb and delete the volume when the
639+ # server is deleted.
640+ 'vdb=' + self .image_name + ':image:1:true ' +
641+ self .network_arg + ' ' +
642+ '--wait ' +
643+ server_name
644+ ))
645+ self .assertIsNotNone (server ["id" ])
646+ self .assertEqual (
647+ server_name ,
648+ server ['name' ],
649+ )
650+ self .wait_for_status (server_name , 'ACTIVE' )
651+
652+ # check server volumes_attached, format is
653+ # {"volumes_attached": "id='2518bc76-bf0b-476e-ad6b-571973745bb5'",}
654+ cmd_output = json .loads (self .openstack (
655+ 'server show -f json ' +
656+ server_name
657+ ))
658+ volumes_attached = cmd_output ['volumes_attached' ]
659+ self .assertTrue (volumes_attached .startswith ('id=' ))
660+ attached_volume_id = volumes_attached .replace ('id=' , '' )
661+
662+ # check the volume that attached on server
663+ cmd_output = json .loads (self .openstack (
664+ 'volume show -f json ' +
665+ attached_volume_id
666+ ))
667+ attachments = cmd_output ['attachments' ]
668+ self .assertEqual (
669+ 1 ,
670+ len (attachments ),
671+ )
672+ self .assertEqual (
673+ server ['id' ],
674+ attachments [0 ]['server_id' ],
675+ )
676+ self .assertEqual (
677+ "in-use" ,
678+ cmd_output ['status' ],
679+ )
680+ # TODO(mriedem): If we can parse the volume_image_metadata field from
681+ # the volume show output we could assert the image_name is what we
682+ # specified. volume_image_metadata is something like this:
683+ # {u'container_format': u'bare', u'min_ram': u'0',
684+ # u'disk_format': u'qcow2', u'image_name': u'cirros-0.4.0-x86_64-disk',
685+ # u'image_id': u'05496c83-e2df-4c2f-9e48-453b6e49160d',
686+ # u'checksum': u'443b7623e27ecf03dc9e01ee93f67afe', u'min_disk': u'0',
687+ # u'size': u'12716032'}
688+
689+ # delete server, then check the attached volume has been deleted
690+ self .openstack ('server delete --wait ' + server_name )
691+ cmd_output = json .loads (self .openstack (
692+ 'volume list -f json'
693+ ))
694+ target_volume = [each_volume
695+ for each_volume in cmd_output
696+ if each_volume ['ID' ] == attached_volume_id ]
697+ if target_volume :
698+ # check the attached volume is 'deleting' status
699+ self .assertEqual ('deleting' , target_volume [0 ]['Status' ])
700+ else :
701+ # the attached volume had been deleted
702+ pass
703+
617704 def test_server_create_with_none_network (self ):
618705 """Test server create with none network option."""
619706 server_name = uuid .uuid4 ().hex
0 commit comments