1 ##############################################################################
2 # Copyright (c) 2015 Huawei Technologies Co.,Ltd and others.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
10 from vstf.common.utils import check_call
14 LOG = logging.getLogger(__name__)
17 class _ImageManager(object):
19 A qemu-img wrapper to create qcow2 child image from a parent image.
23 def __init__(self, parent_image_path, child_image_dir):
25 :param parent_image_path str: the parent image path.
26 :param child_image_dir str: the destination path to put child images.
28 self._create_child_str = 'qemu-img create -f %(image_type)s %(child_path)s -o backing_file=%(parent_path)s'
29 self._convert_str = "qemu-img convert -O %(image_type)s %(parent_path)s %(child_path)s"
30 self.child_image_dir = child_image_dir
31 self.parent_image_path = parent_image_path
32 assert os.path.isfile(self.parent_image_path)
33 assert os.path.isdir(self.child_image_dir)
35 def create_child_image(
41 create a child image and put it in self.child_image_dir.
43 :param child_name: the image name to be created..
44 :return: return the path of child image.
47 image_path = os.path.join(
49 child_name) + '.' + image_type
51 cmd = self._convert_str % {
52 'image_type': image_type,
53 'child_path': image_path,
54 'parent_path': self.parent_image_path}
56 cmd = self._create_child_str % {
57 'child_path': image_path,
58 'parent_path': self.parent_image_path,
59 'image_type': image_type}
60 check_call(cmd.split())
64 class ImageManager(object):
66 def __init__(self, cfg):
68 ImageManager creates images from configuration context.
70 :param cfg: dict, example:
72 'parent_image': "/mnt/sdb/ubuntu_salt_master.img",
73 'dst_location': "/mnt/sdb",
76 'names': ['vm1','vm2','vm3','vm4']
80 super(ImageManager, self).__init__()
81 cfg = self._check_cfg(cfg)
82 self.parent_image = cfg['parent_image']
83 self.image_dir = cfg['dst_location']
84 self.full_clone = cfg['full_clone']
85 self.image_type = cfg['type']
86 self.names = cfg['names']
87 self.mgr = _ImageManager(self.parent_image, self.image_dir)
98 raise Exception("does't find %s config" % key)
99 if cfg['type'] not in ('raw', 'qcow2'):
101 "type:%s not supported, only support 'raw' and 'qcow2'" %
103 if not cfg['full_clone'] and cfg['type'] == 'raw':
105 "only support 'qcow2' for not full_clone image creation" %
109 def create_all(self):
111 create images by configuration context.
113 :return: True for success, False for failure.
115 for name in self.names:
116 image = self.mgr.create_child_image(
117 name, self.full_clone, self.image_type)
118 LOG.info("image: %s created", image)
123 remove all the images created in one go.
125 :return: True for success. Raise exception otherwise.
127 for name in self.names:
128 image_path = os.path.join(
129 self.image_dir, name + '.' + self.image_type)
131 os.unlink(image_path)
132 LOG.info("remove:%s successfully", image_path)
134 LOG.info("cann't find path:%s", image_path)
138 if __name__ == '__main__':
141 parser = argparse.ArgumentParser()
147 help='action:create|clean')
148 parser.add_argument('--config', help='config file to parse')
149 args = parser.parse_args()
150 logging.basicConfig(level=logging.INFO)
151 image_cfg = json.load(open(args.config))
152 mgr = ImageManager(image_cfg)
153 if args.action == 'create':
155 if args.action == 'clean':