Ejemplo n.º 1
0
    def create_volume(self, **args):

        if "name" not in args or not args["name"]:
            return {"message": "Volume name not specified", "code": 1}
        name = args["name"]

        if "instance_name" not in args or not args["instance_name"]:
            return {"message": "Domain name not specified", "code": 1}
        instance_name = args["instance_name"]

        if "volume_size" not in args \
                      or not args["volume_size"] \
                      or not isinstance(args["volume_size"], int):
            return {"message": "Volume size(GB) not specified", "code": 1}
        volume_size = args["volume_size"]

        image = args.get("image", None)
        volume_config = self.prepare_volume(name, image, volume_size)
        if not len(volume_config):
            return {
                "message":
                "Fail to craete volume %s, read log file for details" % name,
                "code": 1
            }

        target = "%s%s%s%s.xml" % (config.instance_data, instance_name, os.sep,
                                   name)
        utils.persist(volume_config, target)
        return {"message": "Volume %s created" % name, "code": 0}
Ejemplo n.º 2
0
    def attach_volume(self, **args):

        if "instance_name" not in args or not args["instance_name"]:
            return {"message": "Domain name not specified", "code": 1}
        instance_name = args["instance_name"]

        domain_exists = utils.domain_exists(instance_name)
        if not domain_exists:
            return {
                "message": "Domain %s not found" % instance_name,
                "code": 1
            }
        stat = utils.domain_stat(instance_name)
        live = "shut off" not in stat

        if "name" not in args or not args["name"]:
            return {"message": "Volume name not specified", "code": 1}
        name = args["name"]

        target = "%s%s%s%s.xml" % (config.instance_data, instance_name, os.sep,
                                   name)
        if not os.path.exists(target):
            return {"message": "Volume %s xml not found" % name, "code": 1}
        volume_config = open(target).read()
        log.debug("Volume: %s" % volume_config)

        if "TARGET" in volume_config:
            device = utils.get_available_blk_target(instance_name)
            volume_config, count = re.subn("'vd[a-z]'|'TARGET'",
                                           "'%s'" % device, volume_config)
            log.debug(volume_config)
            utils.persist(volume_config, target)

        virshcmd = "virsh attach-device \
                       --domain %s --file %s \
                       --config %s" % (instance_name, target,
                                       "--live" if live else "")

        pipe = Popen(virshcmd, shell=True, stdout=PIPE, stderr=PIPE)
        err = pipe.stderr.read()
        info = pipe.stdout.read()
        log.debug("Attach Disk with command '%s', and system output:'%s %s'" %
                  (virshcmd, err, info))

        if info and "Device attached successfully" in info:
            return {
                "message":
                "Volume %s attached to domain %s" % (name, instance_name),
                "code":
                0
            }
        else:
            return {
                "message":
                "Fail to attach %s to domain %s" % (name, instance_name),
                "code": 1
            }
Ejemplo n.º 3
0
    def persist_meta_data(self, hostname, domain, domain_id):
        self.meta_data["hostname"] = hostname
        self.meta_data["launch_index"] = 0
        self.meta_data["name"] = domain
        self.meta_data["uuid"] = domain_id if domain_id else str(uuid.uuid4())
        self.meta_data["files"] = self.content_files

        utils.persist(json.dumps(self.meta_data),
                      "%s%s%s%s%s%s%s" % (self.config_drive_tree,
                                          os.sep, "openstack",
                                          os.sep, "latest",
                                          os.sep, "meta_data.json"))
Ejemplo n.º 4
0
    def attach_cdrom(self, **args):

        if "name" not in args or not args["name"]:
            return {"message": 1, "code": "Domain name not specified !"}
        domain = args["name"]
        if not utils.domain_exists(domain):
            return {"message": 1, "code": "Domain %s not found !" % domain}

        if "iso_file" not in args or not args["iso_file"]:
            return {"message": "ISO file not specified !", "code": 1}
        iso_file = args["iso_file"]
        if not utils.ceph_blk_exists(config.ceph_iso_pool, iso_file,
                                     config.ceph_iso_pool_user):
            return {
                "message":
                "File %s not uploaded to pool %s" %
                (iso_file, config.ceph_iso_pool),
                "code":
                1
            }

        if "iso_type" not in args:
            return {
                "message":
                "ISO file type not specified: 0 for PE,1 for Oracle/MSSQL,etc",
                "code": 1
            }
        iso_type = args["iso_type"]

        cdrom_xml = utils.assemble_cdrom_xml(config.ceph_iso_pool, iso_file)
        target = "%s%s%s%s.xml" % (config.instance_data, domain, os.sep,
                                   iso_file)
        utils.persist(cdrom_xml, target)

        if not self.__update_cdrom(domain, target):
            return {
                "message": "Cannot attach iso, read log for more details .",
                "code": 1
            }

        if iso_type > 0:
            return {"message": "SUCCESS", "code": 0}

        result = utils.reset_cdrom_index(domain, 0)
        if not result:
            return {
                "message":
                "Fail to reset boot order for CDROM, read log for details.",
                "code": 1
            }
        return {"message": "SUCCESS", "code": 0}
Ejemplo n.º 5
0
    def attach_volume(self, **args):

        if "instance_name" not in args or not args["instance_name"]:
            return {"message": "Domain name not specified", "code": 1}
        instance_name = args["instance_name"]

        domain_exists = utils.domain_exists(instance_name)
        if not domain_exists:
            return {"message": "Domain %s not found" % instance_name, "code": 1}
        stat = utils.domain_stat(instance_name)
        live = "shut off" not in stat
        
        if "name" not in args or not args["name"]:
            return {"message": "Volume name not specified", "code": 1}
        name = args["name"]
       
        target = "%s%s%s%s.xml" % (config.instance_data, instance_name, os.sep, name)
        if not os.path.exists(target):
            return {"message": "Volume %s xml not found" % name, "code": 1}
        volume_config = open(target).read()
        log.debug("Volume: %s" % volume_config)

        if "TARGET" in volume_config:
            device = utils.get_available_blk_target(instance_name)
            volume_config, count = re.subn("'vd[a-z]'|'TARGET'", "'%s'" % device, volume_config)
            log.debug(volume_config)
            utils.persist(volume_config, target)
        
        virshcmd = "virsh attach-device \
                       --domain %s --file %s \
                       --config %s" % (instance_name, target, "--live" if live else "")
        
        pipe = Popen(virshcmd, shell=True, stdout=PIPE, stderr=PIPE)
        err = pipe.stderr.read()
        info = pipe.stdout.read()
        log.debug("Attach Disk with command '%s', and system output:'%s %s'" % (virshcmd, err, info))

        if info and "Device attached successfully" in info:
            return {"message": "Volume %s attached to domain %s" % (name, instance_name), "code": 0}
        else:
            return {"message": "Fail to attach %s to domain %s" % (name, instance_name), "code": 1}
Ejemplo n.º 6
0
    def detach_cdrom(self, **args):

        if "name" not in args or not args["name"]:
            return {"message": 1, "code": "Domain name not specified !"}
        domain = args["name"]
        if not utils.domain_exists(domain):
            return {"message": 1, "code": "Domain %s not found !" % domain}

        empty_cdrom = utils.assemble_cdrom_xml(None, None)
        target = "/tmp/empty_cdrom.xml"
        utils.persist(empty_cdrom, target)

        if not self.__update_cdrom(domain, target):
            return {"message": "Fail to detach cdrom", "code": 1}

        cdrom_first = utils.cdrom_in_first_order(domain)
        if cdrom_first:
            result = utils.reset_cdrom_index(domain, 1)
            if not result:
                return {"message": "Fail to restore boot order", "code": 1}
        return {"message": "SUCCESS", "code": 0}
Ejemplo n.º 7
0
    def update_content_with_networks(self, networks):
        # NOTE:
        # Now, config drive content only provides Domain ifcfg-XX file copying
        # In future, hosts/resolve/yum.conf and so on , can be injected
        if not getattr(self, "content_files"):
            self.content_files = []
        for dev, dev_conf in networks.iteritems():
            item = {}
            item["path"] = "%s%s" % (config.NETWORK_CONF_PREFIX["RH"], dev)
            content_index = len(self.content_files)
            item["content_path"] = \
                "/content/%s" % self.__num_trans(content_index)
            self.content_files.append(item)

            dev_conf = self.assemble_dev_config(dev, **dev_conf)
            dev_content_file = "%s%s%s%s" % (self.config_drive_tree,
                                             os.sep, "openstack",
                                             item["content_path"])
            utils.persist(dev_conf, dev_content_file)

        return self.content_files
Ejemplo n.º 8
0
    def create_volume(self, **args):

        if "name" not in args or not args["name"]:
            return {"message": "Volume name not specified", "code": 1}
        name = args["name"]

        if "instance_name" not in args or not args["instance_name"]:
            return {"message": "Domain name not specified", "code": 1}
        instance_name = args["instance_name"]
        
        if "volume_size" not in args \
                      or not args["volume_size"] \
                      or not isinstance(args["volume_size"], int):
            return {"message": "Volume size(GB) not specified", "code": 1}
        volume_size = args["volume_size"]
        
        image = args.get("image", None)
        volume_config = self.prepare_volume(name, image, volume_size)       
        if not len(volume_config):
            return {"message": "Fail to craete volume %s, read log file for details" % name, "code": 1}
        
        target = "%s%s%s%s.xml" % (config.instance_data, instance_name, os.sep, name)
        utils.persist(volume_config, target)
        return {"message": "Volume %s created" % name, "code": 0}        
Ejemplo n.º 9
0
    def persist_user_data(self):

        self.user_data = "%s%s" % (self.user_data, "#!/bin/bash\n")
        # NOTE:
        # In user_data script, it's import to arrange
        # specified action around appropriate EVENT .
        # e.g:
        # It's fit that you start your haproxy process after
        # domain network restarted and IPs configured
        self.set_admin_pass()
        self.set_network()
        # e.g: unarchive httpd.tar.gz
        # e.g: install httpd.rpm & dependency packages
        # e.g: copy user website to httpd wwwroot & chmod
        # e.g: start httpd service
        # e.g: set firewall and expose service port
        #
        # In future, 'ACTION GROUPs' will be added and executed in sequence
        # this's very similar to Iptable Chains and Chain rules
        # e.g:
        # Basic_Settings = ('set_adminPass', 'set_hosts',
        #                   'set_hostname', 'set_yum', ...)
        # Rpm_Install  = ('install_httpd', 'install_haproxy', ...)
        # Service_Settings = ('init_mariadb', 'deploy_httpd', ...)
        # Service_Starting = ('start_httpd', 'start_hginx', ...)
        # Expose_Service_Ports = ('enable_http_access',
        #                         'enable_nginx_access', ...)
        #
        # For simplicity, this method only provides functions:
        # (1) set adminPass
        # (2) restart network
        utils.persist("%s" % self.user_data,
                      "%s%s%s%s%s%s%s" % (self.config_drive_tree,
                                          os.sep, "openstack",
                                          os.sep, "latest",
                                          os.sep, "user_data"))
Ejemplo n.º 10
0
def create_config_drive_tree(domain):

    # The following diagram shows the standard
    # file tree of ConfigDrive that CloudInit can
    # read and parse:
    #
    # openstack
    # ├- content
    # └- latest
    #     ├── meta_data.json
    #     ├── user_data
    #     └  vendor_data.json
    #
    # (1) content: storing files to be copied to domain from config drive,eg:
    #        nic configurations(ifcfg-eth0), hosts, softwares, etc
    # (2) meta_data.json: storing domain metadata, e.g: hostname, uuid, name
    # (3) user_data: /python/shell/powershell/bat scripts
    # (4) vendor_data.json: default {} is ok
    domain_drive = "%s%s" % (config.config_drives, domain)
    if os.path.exists(domain_drive):
        __import__("shutil").rmtree(domain_drive)
    os.makedirs(domain_drive)

    topdir = "%s%s%s" % (domain_drive, os.sep, "openstack")
    file_store = "%s%s%s" % (topdir, os.sep, "content")
    os.makedirs(file_store)

    conf_store = "%s%s%s" % (topdir, os.sep, "latest")
    os.makedirs(conf_store)
    meta_target = "%s%s%s" % (conf_store, os.sep, "meta_data.json")
    utils.persist("{}", meta_target)
    userd_target = "%s%s%s" % (conf_store, os.sep, "user_data")
    utils.persist("# user data scripts\n", userd_target)

    vendor_target = "%s%s%s" % (conf_store, os.sep, "vendor_data.json")
    utils.persist("{}", vendor_target)
    return domain_drive
Ejemplo n.º 11
0
    def create_instance(self, **args):
        if "name" not in args or not args["name"]:
            return {"code": 1, "message": "Domain name not specified !"}
        name = args["name"]
        domain_exists = utils.domain_exists(name)
        if domain_exists:
            return {"code": 1, "message": "Domain %s already exists!" % name}
        self.instance_base_dir = "%s%s%s" % (self.instance_data, name, os.sep)
        self.__ensure_instance_dir(self.instance_base_dir)

        if "image" not in args or not args["image"]:
            return {"code": 1, "message": "Image name not specified !"}
        image_name = args["image"]
        if not self.__image_exists(image_name):
            return {
                "code": 1,
                "message":
                "Contact Administrator to upload image %s" % image_name
            }
        possible_os_type = image_name.lower().count("win")
        clock_offset = config.clock_offset_windows if possible_os_type else config.clock_offset_linux
        """ Prepare system volume """
        boot_volume = config.volume_name_format % {
            "domain": name,
            "type": config.volume_type_boot,
            "uuid": uuid.uuid4()
        }
        volumexml = self.__prepare_volume(name=boot_volume, image=image_name)
        """ As bootable volume, blk target should be set to 'vda' """
        volumexml = volumexml.replace("TARGET", "vda")
        persist_volume = "%s%s.xml" % (self.instance_base_dir, boot_volume)
        utils.persist(volumexml, persist_volume)

        build_link_result = self.__build_network_links(name)
        if not build_link_result:
            return {
                "code": 1,
                "message": "Fail to build links for domain %s" % name
            }
        instance_template = self.__read_instance_template()
        if len(instance_template) == 0:
            return {"code": 1, "message": "Tempalte file error"}

        if "vcpu" not in args or "memory" not in args:
            return {
                "code": 1,
                "message": "Domain flavor(vcpu,memory) not specified"
            }

        # MB -> KB
        memory = args["memory"] * 1024
        vcpu = args["vcpu"]
        instance_template = self.__init_domain_params(instance_template, name,
                                                      vcpu, memory,
                                                      clock_offset, volumexml)
        virshxml = self.__persist_virshxml(instance_template, name)

        def define_domain_from_xml(xml):
            virshcmd = "virsh define %s" % xml
            output = Popen(virshcmd, shell=True, stdout=PIPE).stdout.read()
            log.info("Define domain %s with %s:%s" % (name, xml, output))

        define_domain_from_xml(virshxml)

        def start(name):
            virshcmd = "virsh start %s" % name
            output = Popen(virshcmd, shell=True, stdout=PIPE).stdout.read()
            log.info("Boot domain %s:%s" % (name, output))

        start(name)
        return {"code": 0, "message": "Domain %s booting " % name}
Ejemplo n.º 12
0
 def __persist_virshxml(self, xml, domain):
     target = "%s%s.xml" % (self.instance_base_dir, domain)
     utils.persist(xml, target)
     return target
Ejemplo n.º 13
0
def test_persist(content, target):
    utils.persist(content, target)
Ejemplo n.º 14
0
def test_persist(content, target):
    utils.persist(content, target)