Example #1
0
def single(install_list):
    """ 单台机器安装.

    """
    idc = install_list["idc"]
    sn = install_list["sn"]
    _type = install_list["type"]
    version = install_list["version"]
    usage = install_list["usage"]
    device = install_list["device"]
    product = install_list["product"]
    cabinet = install_list["cabinet"]
    user_data = install_list["user_data"]

    message = "start to install %s." % sn
    logger.info(message)

    # 查询控制卡 ip.
    ip = ilo_info.ip(idc, sn)
    if not ip or not utils.is_valid_ip(ip):
        result = "failed"
        message = "get ilo ip failed"
        install_list["result"] = result
        install_list["message"] = message
        return install_list
    message = "get %s ilo ip: %s" % (sn, ip)
    logger.info(message)

    # 拿到密码.
    passwd = ilo_info.passwd(idc, ip, sn)
    if not passwd:
        result = "failed"
        message = "get ilo passwd failed"
        install_list["result"] = result
        install_list["message"] = message
        return install_list
    passwd = passwd.strip()
    message = "get %s ilo passwd: %s" % (sn, passwd)
    logger.info(message)

    # 获取 ilo 对象.
    oj = ilo_oper.generate(idc, ip, passwd)
    message = "get %s ilo object" % (sn)
    logger.info(message)

    # 检查 SN 是否一致.
    curr_sn = oj.get_sn()
    if sn != curr_sn:
        result = "failed"
        message = "check sn failed"
        install_list["result"] = result
        install_list["message"] = message
        return install_list
    message = "check %s sn consistency success" % (sn)
    logger.info(message)

    # 查询网卡名称.
    nic = oj.get_nic_name(device)
    if not nic:
        logger.error("cann't get nic name")
        result = "failed"
        message = "cann't get nic name"
        install_list["result"] = result
        install_list["message"] = message
        return install_list
    message = "get %s nic name: %s" % (sn, nic)
    logger.info(message)

    # 设置网卡支持 PXE 启动.
    if not oj.get_nic_pxeboot(nic):
        if not oj.setup_nic_pxeboot(nic):
            result = "failed"
            message = "setup network device to support pxe boot failed"
            install_list["result"] = result
            install_list["message"] = message
            return install_list
    message = "set %s nic pxe boot success" % sn
    logger.info(message)

    # 设置启动顺序.
    nic_seq = oj.get_boot_order(nic)
    if not oj.check_boot_order(nic_seq):
        if not oj.setup_boot_order(nic_seq):
            result = "failed"
            message = "can't setup right bootseq - %s" % nic_seq
            install_list["result"] = result
            install_list["message"] = message
            return install_list
    message = "set %s nic support pxe boot success" % sn
    logger.info(message)

    # 设置机器从 PXE 启动一次.
    if not oj.setup_pxeboot_once():
        result = "failed"
        message = "setup pxe once boot failed"
        install_list["result"] = result
        install_list["message"] = message
        return install_list
    message = "set %s nic pxe boot once success" % sn
    logger.info(message)

    # 拷贝 pxelinux 配置文件.
    mac = oj.get_mac(nic)
    if not oj.constract_tftp(_type, version, mac):
        result = "failed"
        message = "copy pxelinux cfg failed"
        install_list["result"] = result
        install_list["message"] = message
        return install_list
    message = "copy %s pxelinux cfg success" % sn
    logger.info(message)

    # 重启.
    if not oj.reboot():
        result = "failed"
        message = "restart server failed"
        install_list["result"] = result
        install_list["message"] = message
        return install_list
    message = "reboot %s success" % sn
    logger.info(message)

    # 安装信息进 redis.
    client.hset(sn, "idc", idc)
    client.hset(sn, "usage", usage)

    client.hset(sn, "hostname", "")
    client.hset(sn, "ip", "")

    message = "set %s's idc, usage, hostname, ip to redis success" % sn
    logger.info(message)

    # 设置 user_data, 装机之后机器会获取并执行 user_data 中的内容.
    if user_data is None:
        client_user_data.exists(sn) and client_user_data.delete(sn)
    else:
        client_user_data.set(sn, user_data)

    # 循环等待安装完成.
    timeout = 2700
    interval = 30
    timetotal = 0

    installed = False
    inasset = False

    while timetotal < timeout:
        if not installed:
            hostname = client.hget(sn, "hostname")
            ip = client.hget(sn, "ip")

            if "" in [hostname, ip]:
                time.sleep(interval)
                timetotal += interval
            else:
                installed = True
        elif installed and not inasset:
            try:
                ret = server.get("sn", sn)
                if not isinstance(ret, dict):
                    time.sleep(interval)
                    timetotal += interval
                elif "hostname" not in ret:
                    time.sleep(interval)
                    timetotal += interval
                elif ret["hostname"] != hostname:
                    time.sleep(interval)
                    timetotal += interval
                else:
                    inasset = True
            except Exception, e:
                message = traceback.format_exc()
                logger.error(message)
                time.sleep(interval)
                timetotal += interval
        else:
            break
Example #2
0
def create_origin(name, uuid, version, vcpu, mem, os_size, data_size, ip,
                  location, netmask, gateway, ks, bridge):
    """ 用传统方法创建 instance.

    """
    # 确认 IP 是否合法.
    if not utils.is_valid_ip(ip):
        message = "ip:{ip} is illegal".format(ip=ip)
        logger.warning(message)
        raise Exception(message)

    # 如果没有 location, 则下载.
    if not os.path.isfile(location):
        cmd = ''' wget {url} -O {location}'''.format(url=ISO_URLS[version],
                                                     location=location)
        utils.shell(cmd)

    # 创建系统盘.
    os_volume_path = volume.create(name, os_size)

    # 执行安装操作.
    cmd = """virt-install --name {name} --uuid {uuid} --vcpus={vcpu} --ram {mem} """\
        """--disk path={os_volume_path} -localtime --accelerate """\
        """--location={location} -x "ip={ip} netmask={netmask} gateway={gateway} """\
        """dns={dns} dnsdomain={dnsdomain} ks={ks} console=tty0 console=ttyS0,115200n8" """\
        """--nographics --network bridge={bridge} --noautoconsole &>/dev/null""".format(
        name=name, uuid=uuid, vcpu=vcpu, mem=mem, os_volume_path=os_volume_path,
        location=location, ip=ip, netmask=netmask, gateway=gateway, dns=NAMESERVER,
        dnsdomain=DOMAIN, ks=ks, bridge=bridge)
    utils.shell(cmd)

    # 设置自动启动.
    cmd = "virsh autostart {name}".format(name=name)
    utils.shell(cmd)

    # 创建数据盘, 盘的标识是 ${name}_data.
    data_volume = name + "_data"
    data_volume_path = volume.create(data_volume, data_size)

    # 默认也会自动增加第二块网卡.
    interface.add(name, "br1")

    # 删除一些无用配置, 不删的话起不来(第二种存储结构有问题, 第一种没问题).
    cmd = """sed -i '/<kernel>/d' /etc/libvirt/qemu/{name}.xml;
             sed -i '/<initrd>/d' /etc/libvirt/qemu/{name}.xml;
             sed -i '/<cmdline>/d' /etc/libvirt/qemu/{name}.xml;
             virsh define /etc/libvirt/qemu/{name}.xml
            """.format(name=name)
    utils.shell(cmd)

    # 这里是安装完成之后自动重启.
    check_cmd = "virsh list | grep -q {name} ".format(name=name)
    start_cmd = "sleep 1 && sh libs/guestfish_origin.sh {name} {uuid} && virsh start {name} && sleep 1 ".format(
        name=name, uuid=uuid)
    if utils.check_wait(check_cmd, start_cmd):
        logger.info("post start {name} success".format(name=name))
    else:
        message = "post start {name} timeout".format(name=name)
        logger.warning(message)
        raise Exception(message)

    # 关联成 instance 的 vdb, 在装机完成之后 attach 的原因是:
    # 我发现在装机开始就 attach 的话, vdb 会被搞成 swap,
    # pvcreate 的时候就会失败.
    volume.attach(name, data_volume_path, "vdb")
Example #3
0
def create_wmi(name, uuid, vcpu, mem, os_size, data_size, ip, hostname, wmi_id,
               netmask, gateway, bridge):
    """ 根据 wmi 创建 instance.

    大概步骤是这样:
    1. 根据 wmi_id 获取到 wmi 的信息, 数据结构类似.
    2. 创建相应的系统盘和数据盘.
    3. 下载对应的镜像, 覆盖掉上一步创建的盘.
    4. 如果要求的 size 比 镜像中的大, 则增大空间.
    5. 根据模板文件生成虚拟机配置文件, 需修改:
       1). 硬盘信息;   # 最麻烦
       2). 网卡信息;
       3). name;
       4). uuid;
       5). vcpu;
       6). mem;
    6. 定义配置文件, 修改系统镜像.
    7. 启动系统.
    8. 增加虚拟机机器的 DNS 记录.

    """
    # 确认 IP 是否合法.
    if not utils.is_valid_ip(ip):
        message = "ip:{ip} is illegal".format(ip=ip)
        logger.warning(message)
        raise Exception(message)

    # 获取 wmi 数据.
    wmi_data = wmi.get(wmi_id)

    os_name = name
    os_volume_path = volume.create(os_name, os_size)

    data_name = name + "_data"
    data_volume_path = volume.create(data_name, data_size)

    os_url = wmi_data["os"]["url"]
    # 对于 qcow2 格式的系统盘, 直接 wget, 并重置大小.
    if volume.path_type(os_volume_path) == "qcow2":
        utils.wget(os_url, os_volume_path)
        if int(os_size.strip("G")) > int(wmi_data["os"]["size"].strip("G")):
            volume.resize(os_name, os_size)
        if int(data_size.strip("G")) > int(
                wmi_data["data"]["size"].strip("G")):
            volume.resize(data_name, data_size)

    # 对于 raw 格式的系统盘, 不能使用 wget.
    # 一种选择是使用 qemu-img convert -O raw 命令,
    # 但是会有系统盘大小的数据写入, 给 IO 造成很大压力.
    # 这里我使用 分区表 的方式来减少 IO.
    if volume.path_type(os_volume_path) == "raw":
        storage.restore_rawos_from_qcow2_image(os_volume_path, wmi_data)

    # 数据盘初始化.
    init_data_volume_cmd = """virt-format -a {data_volume_path} --lvm=/dev/datavg/home --filesystem=ext4""".format(
        data_volume_path=data_volume_path)
    try:
        utils.shell(init_data_volume_cmd)
    except Exception, e:
        utils.shell("yum -y update qemu-kvm")
        utils.shell(init_data_volume_cmd)
Example #4
0
def single(check_list):
    """ 检查是否能够正常安装.

    """

    idc = check_list["idc"]
    sn = check_list["sn"]
    device = check_list["device"]

    # 查询控制卡 ip.    
    ip = ilo_info.ip(idc, sn)
    if ip == False or utils.is_valid_ip(ip) == False:
        result = "failed"
        message = "get ilo ip failed"
        check_list["result"] = result
        check_list["message"] = message
        return check_list

    # 拿到密码.
    passwd = ilo_info.passwd(idc, ip, sn)
    if passwd == False:
        result = "failed"
        message = "get ilo passwd failed"
        check_list["result"] = result
        check_list["message"] = message
        return check_list

    passwd = passwd.strip()

    # 获取 ilo 对象.
    oj = ilo_oper.generate(idc, ip, passwd)

    # 检查 SN 是否一致.
    curr_sn = oj.get_sn()
    if sn != curr_sn:
        result = "failed"
        message = "check sn failed"
        check_list["result"] = result
        check_list["message"] = message
        return check_list

    # 查询网卡名称.
    nic = oj.get_nic_name(device)
    if not nic:
        logger.error("cann't get nic name")
        result = "failed"
        message = "cann't get nic name"
        check_list["result"] = result
        check_list["message"] = message
        return check_list

    # 设置网卡支持 PXE 启动.
    if not oj.get_nic_pxeboot(nic):
        if not oj.setup_nic_pxeboot(nic):
            result = "failed"
            message = "setup network device to support pxe boot failed"
            check_list["result"] = result
            check_list["message"] = message
            return check_list

    # 设置启动顺序.
    nic_seq = oj.get_boot_order(nic)
    if not oj.check_boot_order(nic_seq):
        if not oj.setup_boot_order(nic_seq):
            result = "failed"
            message = "can't setup right bootseq - %s" % nic_seq
            check_list["result"] = result
            check_list["message"] = message
            return check_list

    logger.info("%s(%s) check install success ", sn, ip)

    result = "success"
    message = "check success"
    check_list["result"] = result
    check_list["message"] = message
    return check_list