├── .gitignore ├── Linux_img_make.md ├── README ├── README.md ├── Windows_img_make.md ├── first.sh ├── readme.txt ├── ser ├── http1.pv ├── httpser2.py ├── httpser3_with_thread.py └── httpser4.py ├── soft_script ├── nicinfo.ini ├── nicinfo.log ├── reboot.exe ├── routeaddinnet.vbs └── setnicip.vbs ├── test ├── v1.py └── v2.py ├── virtauto.py ├── virtclass └── classvm.py ├── virtdb └── data.py ├── virtgetopt └── v1.py ├── virtmod ├── colpt.py ├── osprobe.py ├── syncTemp.py ├── virtcli │ ├── __init__.py │ ├── cli.cfg │ ├── cliconfig.py │ └── cliutils.py └── virtinst │ ├── Boot.py │ ├── CPU.py │ ├── CapabilitiesParser.py │ ├── Clock.py │ ├── CloneManager.py │ ├── DistroInstaller.py │ ├── DomainFeatures.py │ ├── DomainNumatune.py │ ├── Guest.py │ ├── ImageFetcher.py │ ├── ImageInstaller.py │ ├── ImageParser.py │ ├── ImportInstaller.py │ ├── Installer.py │ ├── Interface.py │ ├── LiveCDInstaller.py │ ├── NodeDeviceParser.py │ ├── OSDistro.py │ ├── PXEInstaller.py │ ├── Seclabel.py │ ├── Storage.py │ ├── User.py │ ├── VirtualAudio.py │ ├── VirtualCharDevice.py │ ├── VirtualController.py │ ├── VirtualDevice.py │ ├── VirtualDisk.py │ ├── VirtualFilesystem.py │ ├── VirtualGraphics.py │ ├── VirtualHostDevice.py │ ├── VirtualInputDevice.py │ ├── VirtualMemballoon.py │ ├── VirtualNetworkInterface.py │ ├── VirtualRNGDevice.py │ ├── VirtualRedirDevice.py │ ├── VirtualSmartCardDevice.py │ ├── VirtualVideoDevice.py │ ├── VirtualWatchdog.py │ ├── XMLBuilderDomain.py │ ├── __init__.py │ ├── cli.py │ ├── hostkeymap.py │ ├── osdict.py │ ├── support.py │ ├── uriutil.py │ └── util.py ├── virtscript ├── libguestfs-winsupport-1.0-7.el6.x86_64.rpm ├── libguestfs-winsupport-7.0-2.el7.x86_64.rpm ├── setipbymac-ubuntu.sh ├── setipbymac.sh └── setipbymac.sh.bak ├── virttmp ├── nicinfo.ini └── rc.local ├── virtvdb ├── win2k3.vdb └── win2k8.vdb ├── virtxml └── win03.xml └── vm.csv /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[co] 2 | 3 | # Packages 4 | *.egg 5 | *.egg-info 6 | dist 7 | build 8 | eggs 9 | parts 10 | bin 11 | var 12 | sdist 13 | develop-eggs 14 | .installed.cfg 15 | 16 | # Installer logs 17 | pip-log.txt 18 | 19 | # Unit test / coverage reports 20 | .coverage 21 | .tox 22 | 23 | #Translations 24 | *.mo 25 | 26 | #Mr Developer 27 | .mr.developer.cfg 28 | -------------------------------------------------------------------------------- /Linux_img_make.md: -------------------------------------------------------------------------------- 1 | Linux 镜像制作方法 2 | 3 | 1 RHEL/CentOS镜像制作方法 4 | 5 | 首先进行系统的安装,安装过程就不详细介绍了,有以下几个注意点: 6 | 7 | (1)关于镜像大小 8 | 9 | 根据我的经验,一般Linux系统盘20GB大小比较合适。 10 | 11 | 但也不是绝对的,要根据业务类型来决定,比如在生产环境中,根据业务需要,我有的Linux系统镜像模版为150GB大小。 12 | 13 | (2)关于分区大小 14 | 15 | 分区建议使用自定义方式安装,boot、swap、根分区我的配置经验如下: 16 | 17 | 1)boot分区大小配置 18 | 19 | boot分区建议按照下表配置: 20 | 21 | 系统 boot分区大小(MB) 22 | 23 | RHEL/CentOS 5系列 100 24 | 25 | RHEL/CentOS 6系列 200 26 | 27 | RHEL/CentOS 7系列 500 28 | 29 | 2)swap分区配置 30 | 31 | swap一般和内存大小一致,或者安装的时候不创建swap分区,安装完成后使用文件的格式: 32 | 33 | swap文件分区操作方法: 34 | 35 | ① 创建swap 36 | # fallocate -l 512M /swapfile 37 | 38 | ② 启用swap 39 | 40 | # chmod 600 /swapfile 41 | 42 | # mkswap –f /swapfile 43 | 44 | # swapon /swapfile 45 | 46 | ③ 验证swap是否生效,大小是否符合预期 47 | 48 | # swapon -s 49 | 50 | # free -m 51 | 52 | ④ 修改fstab ,使swap开机自动挂载 53 | 54 | 添加以下内容: 55 | 56 | /swapfile none swap defaults 0 0 57 | 58 | 3)关于根分区大小和业务数据存储 59 | 60 | 建议剩余空间全部留给跟分区,业务数据存储另外挂载一块磁盘,根据业务需求配置大小。 61 | 62 | (3)系统升级,这步很重要, 升级系统可以提升虚拟化的转换效率,使用较新的Virtio驱动,命令如下: 63 | 64 | # yum update –y 65 | 66 | (4)删除旧的内核 67 | 68 | 为了节约空间,删除旧的内核,并修改启动菜单不用的内核。 69 | 70 | (5)安装基础组件和开发组件 71 | 72 | 基础组件Base和开发组件一般系统都需要使用,建议安装。 73 | 74 | (6)yum配置 75 | 76 | 建议搭建内部yum源,好处如下: 77 | 78 | 更新速度快; 79 | 80 | 省带宽; 81 | 82 | 可以将自己制作的rpm包放入yum源中。 83 | 84 | 如果有自定义的yum源,在模版镜像中添加自建的yum源配置。 85 | 86 | (7)配置NTP 87 | 88 | 可以配置外网的NTP地址,也可以自己搭建NTP服务,以外网NTP为例: 89 | 90 | 将/etc/ntp.conf中的ntp服务器更换为亚洲的ntp源: 91 | 92 | # vim /etc/ntp.conf 93 | 94 | server 0.centos.pool.ntp.org 95 | 96 | server 1.centos.pool.ntp.org 97 | 98 | server 2.centos.pool.ntp.org 99 | 100 | 修改为: 101 | 102 | server 0.asia.pool.ntp.org 103 | 104 | server 1.asia.pool.ntp.org 105 | 106 | server 2.asia.pool.ntp.org 107 | 108 | 开启NTP服务、配置NTP服务开机运行: 109 | 110 | # service ntpd start 111 | 112 | # chkconfig ntpd on 113 | 114 | (8)关闭SELinux 115 | 116 | SELinux和许多程序都有冲突,一般在生产环境建议关闭。 117 | 118 | 方法为修改/etc/selinux/config将SELINUX=enforcing修改为SELINUX=disabled。 119 | 120 | 2 Ubuntu、Debian虚拟机配置注意点 121 | 122 | Ubuntu、Debian的虚拟机安装配置和CentOS类似,这里只介绍下需要注意的地方: 123 | 124 | 因为Ubuntu系统的升级比较激进,尽量选择长支持的版本和长支持的内核, 125 | 126 | 我在生产环境中碰到多次Ubuntu系统使用较新内核,系统崩溃的问题。 127 | 128 | 用手工分区,不要使用lvm方式,笔者碰到过多次使用lvm方式,重启系统的时候文件系统检查不通过的情况。 129 | 130 | 进行严格的性能和稳定性测试。 131 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | kvm vm setup script 2 | -h, --help print this 3 | --vg,assige vg name,such as --vg=datavg,vg=vmVG 4 | default vg name is 'datavg' if not assige 5 | --config,assige config file name ,such as --config=vm.csv 6 | config file must in same directory and must be csv 7 | default config file name is 'vm.csv' if not assige 8 | --url,give path to download vm images,such as --url=ftp://user1:pass@172.16.1.100/ 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##kvm\_vm\_setup## 2 | ============================================================ 3 | 4 | KVM 虚拟机自动部署脚本,可以自动化的完成kvm虚拟机的部署,包括ip注入。 5 | 6 | ##主要功能如下:## 7 | 8 | 1 全自动的完成虚拟机生成、主机名、ip地址配置; 9 | 10 | 2 支持Windows系统、RHEL6/RHEL7、CentOS6/CentOS7、RHEL6/RHEL7衍生系统、Ubuntu系统的部署,其它系统未做测试; 11 | 12 | ##使用前提条件:## 13 | 14 | 1 Windows、Linux系统按照帮助文档要求制作镜像: 15 | 16 | Windows 镜像制作请参考Windows_img_make,Linux镜像制作请参考Linux_img_make; 17 | 18 | 2 宿主机上,镜像、虚拟机的存储路径为/datapool; 19 | 20 | 3 如果要使用lvm,vg的名字必须是datavg; 21 | 22 | 4 宿主机系统只支持RHEL6/RHEL7、CentOS6/CentOS7、RHEL6/RHEL7衍生系统,本脚本通过调用Libvirt配置虚拟机,通过guestfish编辑虚拟机镜像,需要安装虚拟化组件、Libvirt组件、guestfish组件: 23 | 24 | 首先需要运行firsh.sh脚本,会自动判断操作系统,并安装组件,升级操作系统。 25 | 26 | 安装完成后重启系统,并启动libvirt服务。 27 | 28 | service libvirtd restart 29 | 30 | 31 | ##使用方法:## 32 | 33 | 1 下载脚本源代码 34 | 35 | git clone https://github.com/xiaoli110/kvm_vm_setup 36 | 37 | 2 编辑vm.csv文件,格式如下: 38 | 39 | \#vmflag,template,name,disk1_size,disk2_size,mem_size,cpu_num,nic_type,nic1_bridge,nic2_bridge,vnc_port,outip,outmask,outgw,inip,inmask,ingw 40 | 41 | \#vm template name must be ''win2003ent32chs' 'win2003ent64chs' 'win2008ent64chs' 'centos56x64' 'ubuntu1204X64' 42 | 43 | \#keyword vmLvm means create lvm for vm,default vg is datavg 44 | 45 | \#keyword vmCpOnly means not resize images , just cp imaiges,default vg is datavg 46 | 47 | \#kerword url: means download vm images path,like 48 | 49 | \#url:http://172.16.1.100/ 50 | 51 | ftp:ftp://ftpuser1:password@ftp.myimages.com:10021/ 52 | 53 | ftp:ftp://ftpuser2:password@ftp.myimages2.com:10021/ 54 | 55 | 56 | 此处如果指定url,会到url上去拉去虚拟机镜像,支持ftp方式,拉取方式为url加镜像名字,镜像名字为下面虚拟机配置文件中的镜像名字。 57 | 58 | 可以指定两个url,脚本会自动比较多个url的速度,需要在url里面放置一个200MB大小的名为“ratetest”的文件。 59 | 60 | 如果没有指定url,脚本会认为/datapool已经有指定的镜像,如果/datapool下面也没有镜像,就会报错退出。 61 | 62 | vm,win2003ent32chs,win2003-138,20G,20G,2048,2,e1000,br1,br1,5921,10.10.10.21,255.255.255.0,10.10.10.1,192.168.122.138,255.255.255.0,none 63 | 64 | vmLvm,win2003ent32chs,virt1-lab-222,10G,10G,2048,2,e1000,br2,br2,59222,10.0.0.222,255.0.0.0,10.0.0.1,172.16.2.222,255.255.255.0,none 65 | 66 | vmCpOnly,centos6564.qcow2,centos65-8,30G,20G,2048,2,virtio,br1,br1,59008,10.10.10.8,255.255.255.0,10.10.10.1,172.16.2.8,255.255.255.0,none 67 | 68 | 69 | 虚拟机生成配置文件信息如下: 70 | 71 | 第一个关键字意义如下: 72 | 73 | vm 使用qcow2方式,并通过guestfish进行文件系统的扩展; 74 | 75 | vmLvm 使用lvm方式; 76 | 77 | vmCpOnly 使用qcow2方式,直接复制镜像。 78 | 79 | 第二个关键字为镜像名字,建议名字包含操作系统信息。 80 | 81 | 后面的配置关机字依次为虚拟机主机名,第一块磁盘大小,第二块磁盘大小,CPU、内存配置等信息。 82 | 83 | 注意: 84 | 85 | 1 如果使用vm关键字进行磁盘扩展,第一块磁盘必须大于镜像; 86 | 87 | 2 每个关键字必须有内容,第二块磁盘必须有,最小为1G; 88 | 89 | 3 ip地址合法性本脚本不作检查; 90 | 91 | 4 CentOS7的虚拟机只支持在CentOS7的宿主机上进行配置。 92 | 93 | ###运行脚本### 94 | 95 | 使用命令 96 | 97 | python virtauto.py 就可以自动生成虚拟机。 98 | 99 | virtauto.py 帮助信息如下: 100 | 101 | kvm vm setup script 102 | 103 | -h, --help print this 104 | 105 | --vg,assige vg name,such as --vg=datavg,vg=vmVG 106 | 107 | default vg name is 'datavg' if not assige 108 | 109 | --config,assige config file name ,such as --config=vm.csv 110 | 111 | config file must in same directory and must be csv 112 | 113 | default config file name is 'vm.csv' if not assige 114 | 115 | --url,give path to download vm images,such as --url=ftp://user1:pass@172.16.1.100/ 116 | 117 | 118 | ##一个bug的临时修改方法:## 119 | 120 | 目前脚本cpu模式使用的是host-passthrough,脚本跑完,cpu这里的xml文件是: 121 | 122 | \ 123 | 124 | \host-passthrough\ 125 | 126 | \ 127 | 需要手动将这里修改为: 128 | 129 | \ 130 | 131 | 否则虚拟机不能启动,这个应该是virt-install命令行的一个bug,后面准备增加一个功能,判断并替换。 132 | 133 | 134 | -------------------------------------------------------------------------------- /Windows_img_make.md: -------------------------------------------------------------------------------- 1 | ###Windows 虚拟机制作方法### 2 | 3 | 目前在生产环境使用的Windows版本主要是Windows Server 2008 R2及Windows Server 2012 R2。本文以Windows Server 2008 R为例说明Windows系统镜像的制作方法,Windows Server 2012 R2制作方法非常类似,就不介绍了。 4 | 5 | 本文也会简单介绍下Windows Server 2003镜像的制作注意点。 6 | 7 | 需要说明的是,最新一代服务器已经不提供对Windows Server 2003驱动的支持 ,但是虚拟化对Windows Server 2003支持的很好。如果有老的业务需要使用Windows Server 2003,通过虚拟化提供支持也是很好的解决方案。 8 | 9 | 10 | **1. Windows虚拟机的安装** 11 | 12 | (1)准备操作系统ISO文件 13 | 14 | 建议使用正版Windows ISO镜像,强烈建议生产环境不要使用非正常渠道获得的Windows ISO文件。 15 | 16 | (2)Windows虚拟机的配置 17 | 18 | Windows虚拟机建议根据下表来配置: 19 | 20 | CPU 内存大小(MB) 硬盘方式 磁盘大小(G) 网卡方式 21 | 22 | Windows 2003 系列 2个 512 IDE 50GB e1000 23 | 24 | Windows 2008 系列 2个 2048 IDE 100GB Virtio 25 | 26 | Windows 2012系列 4个 2048 IDE 100GB Virtio 27 | 28 | 生成镜像的命令是: 29 | 30 | qemu-img create -f qcow2 sys.img -opreallocation=metadata 100G 31 | 32 | 为了传输管理方便,虚拟机镜像格式建议使用qcow2格式,要加上opreallocation=metadata参数。 33 | 否则使用virt-install命令安装完成后虚拟机磁盘镜像会变为raw格式。 34 | 35 | 1)关于Windows虚拟机镜像大小 36 | 37 | 直接将镜像复制,不再进行磁盘和文件系统的扩展。这样做虽然牺牲了灵活性,但好处是生成虚拟机的时候速度要快很多。并且生成的虚拟机第二次重启的时候,没有文件系统长时间检查的问题。 38 | 目前国内公有云大部分也都是通过复制镜像的方式进行部署。 39 | 40 | 2)关于Windows系统网卡驱动的说明 41 | 42 | 2014年上半年以前,我生产环境Windows虚拟机系统网卡使用e1000的网卡。因为使用Virtio的网卡,在Windows系统上一直有闪断的情况。但是到2014年底,最新发布的Virtio网卡Windows系统驱动,经过我在生产环境的检验,已经工作的非常稳定。 43 | 所以我又开始在生产环境使用Virtio网卡。 44 | 45 | 3)关于Windows虚拟机系统的磁盘驱动 46 | 47 | 开始安装系统的时候,建议磁盘驱动使用IDE方式,这样方便安装。系统安装之后,建议将驱动更换为Virtio,因为Virtio性能要好很多,具体的操作方法在后面介绍。 48 | 49 | (3)安装虚拟机 50 | 51 | 安装虚机有很多种方法,比如使用Virt-Manager、virt-install这样的工具,也可以通过事先定义xml文件来安装虚拟机。 52 | 53 | 以使用virt-install命令为例安装虚拟机: 54 | 55 | virt-install \ 56 | 57 | --hvm \ 58 | 59 | --name windows2008 \ 60 | 61 | --ram 2048 \ 62 | 63 | --file=/opt/sys.img \ 64 | 65 | --livecd \ 66 | 67 | --cdrom /opt/windows/windows2008.iso \ 68 | 69 | --vnc \ 70 | 71 | --vncport=5910 72 | 73 | 具体安装过程就不详细介绍了,但是Windows Server 2008 R2安装时候的分区需要注意。因为2008默认安装的时候会有一个100MB的隐藏分区,放一些系统引导文件,类似Linux系统的boot分区。但是这个分区在调整分区和文件系统的时候经常容易误导,如果不希望有这个分区,可以手工分区,方法如下: 74 | 75 | 在光盘引导起来之后,按shift加F10键,会出现一个命令行界面,键入diskpart命令,进入Windows的命令行分区模式。 76 | 77 | diskpart类似Linux下的partd命令。 78 | 79 | 输入list disk命令,可以看到当前的磁盘,输入select disk 0命令,选择第一块磁盘。 80 | 81 | 输入create partition primary命令,将所有磁盘空间划分为一个大的主分区,输入active命令,将这个分区激活。 82 | 83 | diskpart命令的详细使用可以输入help命令,查看帮助。 84 | 85 | 分区完成输入exit退出命令行界面,然后开始Windows系统的安装。 86 | 87 | 到磁盘分区的步骤时,直接选择刚才手工的分区安装就可以。 88 | 89 | 虚拟机安装完成后,重要的就是如何配置虚拟机系统,下面介绍如何让制作的虚拟机符合自己的需求。 90 | 91 | **2. 配置虚拟机 模版** 92 | 93 | (1)安装Virtio驱动 94 | 95 | KVM是使用硬件虚拟化辅助技术(如Intel VT-x、AMD-V)的虚拟化引擎,在CPU运行效率方面有硬件支持,效率是比较高的。KVM在I/O虚拟化方面,传统的方式是使用QEMU纯软件的方式来模拟I/O设备,其效率并不高。在KVM中,可以在虚拟机中使用半虚拟化驱动(Paravirtualized Drivers,PV Drivers)来提高I/O性能。因此在虚拟机的磁盘、网络尽量应使用Virtio设备。 96 | 97 | 1)安装硬盘Virtio驱动 98 | 99 | 首先下载硬盘Virtio驱动,下载地址: 100 | 101 | http://www.linux-kvm.org/page/WindowsGuestDrivers/Download_Drivers。 102 | 103 | 然后新增一块临时硬盘,并将其驱动更新为SCSI模式: 104 | 105 | qemu-img create -f qcow2 tmp.img 1G 106 | 107 | virsh attach-disk vm --source /kvm/tmp.img --target vdb --persistent 108 | 109 | 通过热插拔方式动态增加了一块硬盘后,会在资源管理器里提示发现新的硬盘。 110 | 111 | 此时,将下载好的virto 驱动挂载到虚拟机。打开后会发现其包括多个文件夹,其中几个文件夹对应的系统是wnet为Windows 2003 Server,wlh为Windows Server 2008 。 112 | 113 | 按照目前使用的Windows系统,安装相应目录里的驱动就行了。安装完成后,还需要更新虚拟机xml文件中有关系统盘的配置。 114 | 115 | 使用virsh edit vmname命令,进入虚拟机xml编辑模式,找到如下的行: 116 | 117 | 118 | 119 | 120 | 121 | 将其修改为: 122 | 123 | 124 | 125 | 126 | 127 | 参照上面的配置修改其他硬盘的xml部分,改完后关闭虚拟机,并启动。在设备管理器会发现原硬盘项已变成SCSI 。 128 | 129 | 2)安装网卡Virtio驱动 130 | 131 | 首先手动通过热插拔方式增加一块临时网卡: 132 | 133 | virsh attach-interface vm --type bridge --source br1 --model virtio 134 | 135 | 在设备管理器中可以看到新加的网卡,然后为新的网卡安装Virtio驱动即可,方法同Virtio磁盘的一样。 136 | 137 | 新增网卡的xml配置如下: 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 |
152 | 153 | 154 | 155 | 在安装完网卡Virtio驱动后,参照上面的配置修改其他网卡的xml文件,重启虚机后,在设备管理器里会要求重新安装驱动,安装即可。 156 | 157 | (2)取消登录任务配置及清除任务栏记录 158 | 159 | Windows Server 2008 R2安装完成后,默认会启动初始任务配置及服务器管理器。为了避免打扰用户,勾选两个界面的“登录时不显示此窗口”选项。 160 | 161 | 为了让用户得到新建的虚拟机菜单栏没有残留的程序痕迹 ,建议删除菜单的历史程序启动记录。 162 | 163 | 操作方法为,鼠标右键单机开始菜单点,选择属性,会出现“任务栏和开始菜单属性”窗口。 164 | 165 | 点击“开始菜单”按钮,将“隐私”复选框的两个选项勾取消,然后点击“应用”按钮,再勾选两个选项,在应用一次。 166 | 167 | (3)配置系统更新源 168 | 169 | 为了提高同一数据中心Windows系统补丁更新速度,节省带宽,可以统一配置所以Windows虚拟机到数据中心内部的更新源进行补丁更新。 170 | 171 | 1)配置更新策略 172 | 操作方法是,同时按Windows键和R键,在弹出的“运行”对话框中中输入gpedit.msc回车,然后会启动组策略编辑器。在组策略编辑器中依次选择“计算机配置”、“管理模板”、“Windows组件”、“Windows Update”。 173 | 174 | 右边双击配置自动更新,选择“已启用”,配置自动更新选择“2-通知下载并通知安装”,还可以根据需要定义更新的时间。 175 | 176 | 2)配置更新源 177 | 还是上一步的Windows Update组策略,双击“指定intranet microsoft更新位置”。如果选择“未配置”单选按钮,此时系统将通过连接微站点自动更新。 178 | 179 | 在生产环境中一般我都会搭建自动安装服务器(WSUS)来实现加快更新速度和节省带宽的目的: 180 | 181 | (4)配置性能计数器 182 | 183 | 在系统遇到性能问题时,可以通过性能计数器收集到的数据方便的找出瓶颈所在。 184 | 185 | 建议根据自己业务的需要,添加相应的性能计数器。 186 | 187 | 添加性能计数器的的操作方法是: 188 | 189 | 1)同时按win键加R键,在运行对话框中输入命令:“%windir%\system32\perfmon.msc /s”回车,打开“性能监视器”。 190 | 191 | 2)选择“数据收集器”中的“用户自定义”,点击鼠标右键选择新建,打开“创建新的数据收集器集”对话框。 192 | 193 | 选择“手动创建(高级)”选项。 194 | 195 | 然后点击“下一步”按钮,选择“创建数据日志”复选框中的“性能计数器”。 196 | 197 | 根据自己的需要,添加响应的计数器选项,建议CPU、磁盘、网络、内存这些基本性能选项都添加上。 198 | 199 | 然后可以根据自己的业务需要,再添加相应的性能计数器。 200 | 201 | 在下一步的“日志格式”选项中,选择“逗号分隔”的格式,即csv格式,这种格式方便脚本或者电子表格分析。 202 | 203 | (5)添加snmp组件 204 | 205 | 很多监控工具都需要通过snmp协议来获取监控数据,建议安装snmp组件。 206 | 207 | 安装方法为,在控制面板中,选择“程序和功能”,在打开的窗口中,选择“打开或关闭Windows功能”。 208 | 209 | 然后在“功能”选项中选择“添加功能”按钮,在打开的对话框中选择snmp组件,然后按照提示安装就可以。 210 | 211 | (6)计算机属性设置 212 | 213 | 1)视觉性能优化 214 | 在计算机上,单机鼠标右键,选择“属性”按钮,然后选择“高级系统设置”选项,在打开的窗口中选择“高级”选型。 215 | 216 | 在“视觉”复选框中,选择“设置”按钮,然后选择“调整为最佳性能”选项。 217 | 218 | 配置这一步的原因是因为服务器系统主要是提供服务,更注重性能。 219 | 220 | 2)配置数据保护 221 | 接上一步,选择“数据执行保护”选项,然后选择“仅为Windows程序和服务启动DEP”。 222 | 223 | 这一步的操作目的是因为有些程序和DEP有兼容问题,会造成程序不能运行。 224 | 225 | DEP (Data Execution Prevention)数据执行保护,是一套软硬件技术。能够在内存上执行额外检查以帮助防止在系统上运行恶意代码。 226 | 227 | 3)打开远程桌面 228 | 229 | 连接Windows虚拟机的主要方式是通过远程桌面,所以需要打开远程桌面。 230 | 231 | 操作方法为:在计算机上,单机鼠标右键,选择“属性”按钮,然后选择“远程设置”选项。 232 | 233 | 选择“允许允许任意版本远程桌面的计算机连接”选项,这个选项主要是兼容性比较好。 234 | 235 | 使用Linux的rdesktop套件都可以连接Windows计算机。 236 | 237 | (7)通过组策略配置计算机启动执行脚本 238 | 239 | 在初始化虚拟机的过程中,用户可能需要做一些初始化配置,比如用户程序和配置文件的个性化设置,介绍下自动配置ip的操作步骤如下: 240 | 241 | 定制脚本名称、配置文件路径规范。 242 | 243 | 在虚拟机生成的时候,通过virt-copy-in命令将程序、相关配置文件、脚本复制到虚拟机里面。 244 | 245 | 在组策略里面指定开机运行脚本,(如果是Linux系统则是通过rc.local指定开机运行脚本),脚本为"c:\windows\setnicip.vbs"。 246 | 247 | 将soft_script目录下的所以脚本拷贝到模版虚拟机的c:\windows下面。 248 | 249 | 虚拟机第一次启动执行脚本,完成ip配置。 250 | 251 | (8)配置允许系统在未登录的情况下关闭 252 | 253 | 在宿主机维护的时候,因为虚拟化管理员往往没有虚拟机系统的密码,又希望系统在未登录的情况下能正常关机。 254 | 255 | 修改组策略Windows安全选项的“关机:允许系统在未登录的情况下关闭”可以实现这个目的。 256 | 257 | (9)配置Windows防火墙 258 | Windows Server 2008 R2的防火墙,默认全部禁止数据包进入,初始配置的时候,因为用户需要远程连接。 259 | 260 | 建议开启远程桌面,为了方便判断虚拟机的状态,建议开启ICMP。 261 | 262 | 操作方法如下:在控制面板中选择“Windows防火墙”,然后选择“高级设置”,在“入站规则”中,点击鼠标右键。 263 | 264 | 选择“新建规则”,选择“自定义”: 265 | 266 | 下一步选择“TCP”,在“本地端口”中,选择“特定端口”,输入端口号“3399”,然后按照提示完成操作就可以。 267 | 268 | 同样的,在新建一个规则,选择ICMP,协议选择ICMPv4,其他按照提示操作就可以: 269 | 270 | (10)配置精确时钟和NTP服务器 271 | 272 | 虚拟机都有时间漂移的现象,Windows虚拟机需要配置精确时钟和NTP服务器。 273 | 274 | 1)精确时钟的配置方法 275 | 276 | Windows Server 2003开启精确时钟设置方法为,修改c:\boot.ini ,再启动行最后增加/usepmtimer参数。 277 | 278 | 另外,有时候需要进入安全方式进行配置,为了Windows Server 2003方便进入安全方式,在c:\boot.ini增加一行以设置进入安全方式。 279 | 280 | 修改后的boot.ini如下: 281 | 282 | [boot loader] 283 | 284 | rem 启动菜单时间为5秒钟 285 | 286 | timeout=5 287 | 288 | default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS 289 | 290 | [operating systems] 291 | 292 | rem 正常启动菜单 293 | 294 | multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Enterprise" /noexecute=optout /fastdetect /usepmtimer 295 | 296 | rem 安全方式启动菜单 297 | 298 | multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Safe Mode" /safeboot:minimal /fastdetect /usepmtimer 299 | 300 | Windows Server 2008 R2配置精确时钟的方法为,在命令行方式下运行以下命令: 301 | 302 | C:\Windows\system32>bcdedit /set {default} USEPLATFORMCLOCK on 303 | 304 | 2)NTP服务器配置 305 | 306 | 在桌面右下角的时间上,点击鼠标,选择“更改时间和日期”,在“Internet时间”选项中,输入自己的NTP服务器地址。 307 | 308 | (11)IE配置 309 | 310 | 1)IE浏览器主页设置为空白页面,IE浏览器删除历史记录。 311 | 312 | 2)关闭IE浏览器的增强安全配置。 313 | 314 | 操作方法为,在服务器管理器中选择配置“IE ESC”。 315 | 316 | 将“管理员”和“用户”的IE增强的安全配置禁用。 317 | 318 | (12)网络配置 319 | 320 | 为了安全起见,关闭Windows的网络共享和WINS解析,关闭网络配置中的IPV6、微软网络客户端、文件和打印机共享选秀。 321 | 322 | 禁用TCP/IP协议中的WINS。 323 | 324 | 16.1.2 Windows 虚拟机sysprep初始化封装 325 | 326 | 镜像制作中,一般安装好系统,并设定好所有标准化选项,之后应进行系统封装。 327 | 328 | 以便通过镜像部署的虚拟机在首次启动时自动更新SID、配置、主机名。 329 | 330 | 如果不更新SID,通过模板部署的所有虚拟机SID都一样,这些虚拟机如果要加入Windows域就会有问题。 331 | 332 | 所以为了保险起见,在制作镜像过程中,最好进行镜像的封装,下面介绍下Windows封装的方法。 333 | 334 | 提示: 335 | SID是每个Windows系统的唯一标识符,根据我的生产环境的经验,如果Windows系统不加入域,不进行系统封装也可以正常稳定的运行。 336 | 337 | 但是这样克隆出来的虚拟机会出现主机名同名的问题,解决方法是通过初始化脚本实现主机名随机修改。 338 | 339 | 另外,Windows Server 2003也可以通过newsid这个工具进行修改。 340 | 341 | Windows Server 2008 R2如果要修改SID必须使用微软的封装方法。 342 | 343 | 1.Windows Server 2003的封装 344 | 345 | Windows Server 2003的封装方法如下: 346 | 347 | (1)在Windows Server 2003系统安装光盘中找到SUPPORT目录下TOOLS文件夹,将DEPLOY.CAB内的所有文件解压到到C盘Sysprep文件夹。 348 | 349 | (2)运行其中的sysprep.exe,在下一步的封装主界面中选“重新封装”。 350 | 351 | (3)大概10-20秒封装准备完成后,系统自动关机。 352 | 353 | 通过以上步骤后,就可以把此封装后的虚拟机转化为模板,之后就可以通过此模板部署虚拟机了。 354 | 355 | 以上封装好的系统,首次启动会有对话框要求用户提供必要设定信息,如:主机名、区域语言设定等。 356 | 357 | 对于批量部署虚拟机每台都手动输入非常不方便,为了解决这个问题,微软提供自动应答文件的方案, 358 | 359 | 以便封装好的系统首次启动自动运行应对文件,不需要用户手动输入信息,具体设定步骤如下: 360 | 361 | 在运行封装之前,首先点击运行sysprep文件夹下的setupmgr.exe,安装向导会指导一步步完成自动应答文件的生成, 362 | 363 | 过程很简单,就不详细介绍了。 364 | 365 | 全部输入完毕后,结束向导,会在sysprep目录下生成一个叫sysprep.inf的应答文件, 366 | 367 | 自动应答文件生成后,再运行sysprep.exe进行封装就可以了,通过镜像克隆的系统首次运行就可以自动完成配置。 368 | 369 | 2. Windows 2008 R2封装 370 | 371 | Windows Server 2008的封装工具位于C:\Windows\System32\sysprep 下,不需要安装光盘。 372 | 373 | 双击运行其中的sysperp,选择“OOBE”和下面的“通用”,确定后开始封装,结束后会自动关机。 374 | 375 | Windows Server 2008 R2也可以制作自动应答文件,需要在微软网站下载相关的工具, 376 | 377 | 配置方法请参考微软官网的相关文档,就不作详细介绍了。 378 | -------------------------------------------------------------------------------- /first.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #write by xiaoli 3 | #version 2015 02 15 4 | 5 | # get script path 6 | selfpath=$(cd "$(dirname "$0")"; pwd) 7 | echo $selfpath 8 | cd $selfpath 9 | 10 | # install guestfish libvirt 11 | yum install libguest* -y 12 | yum install libvirt* -y 13 | yum install virt* -y 14 | 15 | # setup el6 Base and winsupport 16 | hostos=`uname -r |grep el6` 17 | if [[ $? -eq 0 ]];then 18 | yum groupinstall Base 19 | echo "host os is CentOS 6, install winsupport" 20 | rpm -ivh $selfpath/virtscript/libguestfs-winsupport-1.0-7.el6.x86_64.rpm 21 | fi 22 | 23 | 24 | #setup el7 Base and winsupport 25 | hostos=`uname -r |grep el7` 26 | if [[ $? -eq 0 ]];then 27 | yum group install Base 28 | echo "host os is CentOS 7, install lib-virtinst lib-virtcli winsupport" 29 | \cp -r -f $selfpath/virtmod/virtinst /usr/lib/python2.7/site-packages/ 30 | \cp -r -f $selfpath/virtmod/virtcli /usr/lib/python2.7/site-packages/ 31 | rpm -ivh $selfpath/virtscript/libguestfs-winsupport-7.0-2.el7.x86_64.rpm 32 | fi 33 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | edit by: yangjunjun.jerry 2 | date:2012-10-11 3 | description:add ubuntu system support 4 | 5 | ------------------------------------- 6 | edit by: xiaoli110 7 | date 2014-8-1 8 | add cponly way for vm create 9 | 10 | ------------------------------------- 11 | -------------------------------------------------------------------------------- /ser/http1.pv: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys,urllib2 4 | 5 | req = urllib2.Request(sys.argv[1]) 6 | fd = urllib2.urlopen(req) 7 | 8 | while 1: 9 | data=fd.read(1024) 10 | if not len(data): 11 | break 12 | print data 13 | 14 | -------------------------------------------------------------------------------- /ser/httpser2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Basic HTTP Server Example with Two Document - Chapter 16 3 | # basichttpdoc.py 4 | 5 | from BaseHTTPServer import HTTPServer,BaseHTTPRequestHandler 6 | import time 7 | 8 | starttime = time.time() 9 | class RequestHandler(BaseHTTPRequestHandler): 10 | """Definition of the request handler.""" 11 | def __writeheaders(self,doc): 12 | """Write te HTTP headers for the document. If there's no 13 | document, send a 404 error code; otherwise, send a 200 success code""" 14 | if doc is None: 15 | self.send_response(404) 16 | else: 17 | self.send_response(200) 18 | # Always server up HTML for now. 19 | self.send_header('Content-type','text/html') 20 | self.end_headers() 21 | 22 | def __getdoc(self,filename): 23 | """Handle a request for a document, returning one of two different 24 | pages as appropriate.""" 25 | global starttime 26 | if filename == '/': 27 | return """Sample Page 28 | This is a sample page. You can also look at the 29 | server statistics. 30 | 31 | """ 32 | elif filename == '/stats.html': 33 | return """Statistics 34 | This server has been running for %d seconds. 35 | 36 | """ %int(time.time() - starttime) 37 | else: 38 | return None 39 | def do_HEAD(self): 40 | """Handle a request for headers only""" 41 | doc = self.__getdoc(self.path) 42 | self.__writeheaders(doc) 43 | def do_GET(self): 44 | """Handle a request for header and body""" 45 | doc = self.__getdoc(self.path) 46 | self.__writeheaders(doc) 47 | if doc is None: 48 | self.wfile.write("""Not Found 49 | The requested document '%s' was not found. 50 | 51 | """ % self.path) 52 | else: 53 | self.wfile.write(doc) 54 | #Create the object and serve requests 55 | serveraddr = ('', 10501) 56 | srvr = HTTPServer(serveraddr,RequestHandler) 57 | srvr.serve_forever() 58 | -------------------------------------------------------------------------------- /ser/httpser3_with_thread.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Basic HTTP Server Example with Two Document - Chapter 16 3 | # Basic HTTP Server Example with Two Document, threading version 4 | # basichttpdoc.py 5 | 6 | from BaseHTTPServer import HTTPServer,BaseHTTPRequestHandler 7 | from SocketServer import ThreadingMixIn 8 | import time, threading 9 | 10 | starttime = time.time() 11 | 12 | class RequestHandler(BaseHTTPRequestHandler): 13 | """Definition of the request handler.""" 14 | def __writeheaders(self,doc): 15 | """Write te HTTP headers for the document. If there's no 16 | document, send a 404 error code; otherwise, send a 200 success code""" 17 | if doc is None: 18 | self.send_response(404) 19 | else: 20 | self.send_response(200) 21 | # Always server up HTML for now. 22 | self.send_header('Content-type','text/html') 23 | self.end_headers() 24 | 25 | def __getdoc(self,filename): 26 | """Handle a request for a document, returning one of two different 27 | pages as appropriate.""" 28 | global starttime 29 | if filename == '/': 30 | return """Sample Page 31 | This is a sample page. You can also look at the 32 | server statistics. 33 | 34 | """ 35 | elif filename == '/stats.html': 36 | return """Statistics 37 | This server has been running for %d seconds. 38 | 39 | """ %int(time.time() - starttime) 40 | else: 41 | return None 42 | def do_HEAD(self): 43 | """Handle a request for headers only""" 44 | doc = self.__getdoc(self.path) 45 | self.__writeheaders(doc) 46 | def do_GET(self): 47 | """Handle a request for header and body""" 48 | print "Handing with thread", threading.currentThread().getName() 49 | doc = self.__getdoc(self.path) 50 | self.__writeheaders(doc) 51 | if doc is None: 52 | self.wfile.write("""Not Found 53 | The requested document '%s' was not found. 54 | 55 | """ % self.path) 56 | else: 57 | self.wfile.write(doc) 58 | 59 | class ThreadingHTTPServer(ThreadingMixIn,HTTPServer): 60 | pass 61 | #Create the object and serve requests 62 | serveraddr = ('', 10501) 63 | srvr = ThreadingHTTPServer(serveraddr,RequestHandler) 64 | srvr.serve_forever() 65 | -------------------------------------------------------------------------------- /ser/httpser4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Basic HTTP Server Example - Chapter 16 - simplehttp.py 3 | 4 | from BaseHTTPServer import HTTPServer 5 | from SimpleHTTPServer import SimpleHTTPRequestHandler 6 | 7 | serveraddr=('',10501) 8 | srvr = HTTPServer(serveraddr,SimpleHTTPRequestHandler) 9 | srvr.serve_forever() 10 | -------------------------------------------------------------------------------- /soft_script/nicinfo.ini: -------------------------------------------------------------------------------- 1 | ipsetup:1 2 | ip:12.12.12.12 3 | mask:255.255.255.128 4 | gw:12.12.12.1 5 | mac:00:16:3e:02:79:f4 6 | ip:10.0.0.60 7 | mask:255.255.255.0 8 | gw:0.0.0.0 9 | mac:00:16:3e:a0:11:d3 10 | 11 | -------------------------------------------------------------------------------- /soft_script/nicinfo.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoli110/kvm_vm_setup/a1e4b155737bf48b5398f6921816a446ce30f597/soft_script/nicinfo.log -------------------------------------------------------------------------------- /soft_script/reboot.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoli110/kvm_vm_setup/a1e4b155737bf48b5398f6921816a446ce30f597/soft_script/reboot.exe -------------------------------------------------------------------------------- /soft_script/routeaddinnet.vbs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoli110/kvm_vm_setup/a1e4b155737bf48b5398f6921816a446ce30f597/soft_script/routeaddinnet.vbs -------------------------------------------------------------------------------- /soft_script/setnicip.vbs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoli110/kvm_vm_setup/a1e4b155737bf48b5398f6921816a446ce30f597/soft_script/setnicip.vbs -------------------------------------------------------------------------------- /test/v1.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import string 4 | mycwd=os.getcwd() 5 | modcwd=mycwd+'/virtmod' 6 | sys.path.append(modcwd) 7 | modcwd=mycwd+'/virtclass' 8 | sys.path.append(modcwd) 9 | import colpt 10 | import classvm 11 | import syncTemp 12 | 13 | global vmarray, vminfo 14 | global vminicouter 15 | 16 | syncTemp.checkTempFile("win2008ent64chs") 17 | 18 | -------------------------------------------------------------------------------- /test/v2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import time 4 | import os 5 | import string 6 | 7 | a="wget http://12.12.12.12:38601/centos56x64 -c" 8 | #os.system(a) 9 | #os.popen(a) 10 | -------------------------------------------------------------------------------- /virtauto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #scritp read , config virt1.0 xml files then run vm 3 | #write by xiaoli 4 | #version 1.0 2012 04 23 5 | #version 1.1 2012 05 11 6 | #version 1.2 2012 06 27 add format windows disk D 7 | #version 1.3 2012 07 15 add lvm support for vm,default vg is vmVG 8 | #version 1.5 2012 08 15 support multi download source 9 | #version 1.6 2012 10 11 support install ubuntu system 10 | #version 1.7 2012 12 26 check disk alignment ,fix md5 check 11 | #version 1.8 2013 03 04 support windows 2012 virt-machine create update by xiaoli 12 | #version 2.0 2014 08 01 support copy only for create vm images 13 | #version 3.0 2015 02 05 support host and vm is CentOS7,support cpu mode is host by xiaoli 14 | #1 thinking search xml file keyworks then replace it 15 | #2 create disk vda vdb 16 | #3 run virsh commond to start vm 17 | 18 | import os 19 | import sys 20 | import string 21 | mycwd=os.getcwd() 22 | modcwd=mycwd+'/virtmod' 23 | sys.path.append(modcwd) 24 | modcwd=mycwd+'/virtclass' 25 | sys.path.append(modcwd) 26 | import colpt 27 | import classvm 28 | import syncTemp 29 | import getopt 30 | 31 | global vmarray, vminfo 32 | global vminicouter 33 | global vg 34 | global vmurl1,vmurl2,urlcount 35 | vmarray=range(255) #record valid vm info into array vmarray 36 | vminfo=range(255) #record vm info 37 | vminicouter=0 #record vm num 38 | vg="vmVG" #defaulf vg name 39 | vg="datavg" 40 | vmurl1="ftp://virtftp:1qa2ws3ed4rF@211.147.0.120:38602/" 41 | vmurl2="ftp://virtftp:1qa2ws3ed4rF@116.211.20.200:38602/" 42 | urlcount=0 43 | 44 | def getopts(): 45 | helpinfo=""" 46 | -h, --help print this 47 | --vg,assige vg name,such as --vg=datavg,vg=vmVG 48 | default vg name is 'datavg' if not assige 49 | --config,assige config file name ,such as --config=vm.csv 50 | config file must in same directory and must be csv 51 | default config file name is 'vm.csv' if not assige 52 | --url,give path to download vm images,such as --url=ftp://user1:pass@172.16.1.100/ 53 | """ 54 | global vg 55 | opts,args=getopt.getopt(sys.argv[1:],"hc:",["vg=","config=","help","url="]) 56 | if opts==[]: 57 | colpt.ptgreen(helpinfo) 58 | colpt.ptgreen("Will run in default!") 59 | for o,a in opts: 60 | if o in ("-h","--help"): 61 | colpt.ptgreen(helpinfo) 62 | sys.exit(12) 63 | elif o=="--vg": 64 | vg=a 65 | b="vg name is "+a 66 | colpt.ptgreen(b) 67 | elif o=="--config": 68 | pass 69 | elif o=="--url": 70 | vmurl=a 71 | b="url is "+a 72 | colpt.ptgreen(b) 73 | else: 74 | print "wrong argument ,pleale check again" 75 | sys.exit(11) 76 | assert False,"unhand option" 77 | def checkinifile(): 78 | """check config file exist!""" 79 | global vmarray, vminfo 80 | global vminicouter 81 | colpt.ptgreen_no_enter("check config file") 82 | if os.path.isfile("vm.csv"): 83 | colpt.ptgreen("..................config file exists ok!") 84 | else: 85 | colpt.ptred("config file not exists,please check!!!") 86 | sys.exit(1) 87 | def readinifile(): 88 | """read config file and find valid value,assign value to vm array""" 89 | global vmarray, vminfo 90 | global vminicouter,vmurl1,vmurl2,urlcount 91 | f=open("vm.csv","r") 92 | i=0 93 | for line in f: 94 | #print line.strip() 95 | line=line.strip() 96 | if (line.find("vm")==0): 97 | vmarray[i]=line 98 | i=i+1 99 | vminicouter=i 100 | if (line.find("url:")==0): 101 | temurl=line.split(":",1) 102 | if (urlcount==0): 103 | vmurl1=temurl[1] 104 | urlcount=1 105 | elif (urlcount==1): 106 | vmurl2=temurl[1] 107 | urlcount=2 108 | else: 109 | print "url more count error!" 110 | f.close() 111 | def vm_ct(): 112 | """ split vm info and assign to vm object; 113 | and create vm inst """ 114 | global vmarray, vminfo 115 | global vminicouter 116 | global vg 117 | global vmurl 118 | j=0 119 | vminfo=range(vminicouter) 120 | print "vm config info is:" 121 | while j < vminicouter: 122 | #print vmarray[j],j 123 | #vminfo[j]=vmarray[j].split 124 | a=vmarray[j] 125 | vminfo=string.split(a,",") 126 | colpt.ptred("vm "+str(j)+" info") 127 | colpt.ptyellow(str(vminfo)) 128 | vmtmp=classvm.vm() 129 | ifvg=vminfo[0] 130 | if (ifvg.find("Lvm")>0): 131 | vmtmp.vgname="vg" 132 | elif (ifvg.find("CpOnly")>0): 133 | vmtmp.vgname="cp" 134 | else: 135 | vmtmp.vgname="none" 136 | vmtmp.temp=vminfo[1] 137 | c=syncTemp.checkTempFile(vmtmp.temp,vmurl1,vmurl2) 138 | print str(c)+" is check vm iamges error status" 139 | if (c != 0 ): 140 | colpt.ptred(" vm images errors Please check!!!") 141 | sys.exit(5) 142 | colpt.ptgreen(" vm images check is ok!") 143 | vmtmp.name=vminfo[2] 144 | vmtmp.define_vda_vdb() 145 | vmtmp.disk1_size=vminfo[3] 146 | vmtmp.disk2_size=vminfo[4] 147 | vmtmp.mem=vminfo[5] 148 | vmtmp.cpu=vminfo[6] 149 | vmtmp.out_type=vminfo[7] 150 | vmtmp.out_bridge=vminfo[8] 151 | vmtmp.in_bridge=vminfo[9] 152 | vmtmp.vnc_port=vminfo[10] 153 | vmtmp.outip=vminfo[11] 154 | vmtmp.outmask=vminfo[12] 155 | vmtmp.outgw=vminfo[13] 156 | vmtmp.in_type=vminfo[7] 157 | vmtmp.inip=vminfo[14] 158 | vmtmp.inmask=vminfo[15] 159 | vmtmp.ingw=vminfo[16] 160 | if vmtmp.vm_xmlfile_exist()=="1": 161 | colpt.ptred("xml or vda vdb file exist skip vm create!") 162 | elif vmtmp.vm_host_exist()=="1": 163 | colpt.ptred("vm allready exist skip vm create!") 164 | else: 165 | vmtmp.vm_os_check() 166 | if (vmtmp.vgname=="none"): 167 | vmtmp.vm_resize_disk1() 168 | vmtmp.vm_resize_disk2() 169 | elif (vmtmp.vgname=="cp"): 170 | vmtmp.vm_cp_disk1() 171 | vmtmp.vm_resize_disk2() 172 | elif (vmtmp.vgname=="vg"): 173 | vmtmp.vm_lvm_disk1() 174 | vmtmp.vm_lvm_disk2() 175 | vmtmp.vm_xmlfile_create2() 176 | vmtmp.vm_nicinfo_create() 177 | vmtmp.vm_nicinfo_copy_in() 178 | if vmtmp.vm_define()=="1": 179 | colpt.ptred("define failed skip vm create!") 180 | else: 181 | vmtmp.vm_run() 182 | vmtmp.vm_autostart() 183 | j=j+1 184 | getopts() 185 | checkinifile() 186 | readinifile() 187 | vm_ct() 188 | colpt.ptgreen("Done") 189 | -------------------------------------------------------------------------------- /virtdb/data.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #_*_encoding:UTF-8_*_ 3 | """ 4 | ..MySQL...... 5 | """ 6 | 7 | import MySQLdb 8 | 9 | connstring="host='localhost',user='root'" 10 | try: 11 | #conn=MySQLdb.Connect(host='127.0.0.1',user='root') 12 | conn=MySQLdb.Connect(connstring) 13 | except Exception ,e: 14 | print e 15 | #break 16 | -------------------------------------------------------------------------------- /virtgetopt/v1.py: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/env python 2 | 3 | import getopt 4 | import sys 5 | 6 | opts,args=getopt.getopt(sys.argv[1:],"d:h",["start","stop","restart","debug","help"]) 7 | print opts 8 | if opts==[]: 9 | print "oooo" 10 | print args 11 | for o,a in opts: 12 | if o=="--start": 13 | print "statrt..."+a 14 | elif o=="--stop": 15 | print "stop..."+a 16 | elif o=="restart": 17 | print "stop...start..."+a 18 | elif o in ("-d","--debug"): 19 | print "debug..."+a 20 | elif o in("-h","--help"): 21 | print "usage()..."+a 22 | else: 23 | print "ttt" 24 | assert False,"unhandled option" 25 | -------------------------------------------------------------------------------- /virtmod/colpt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | #"""print color mod,print red green yellow""" 3 | #write by xiaoli 4 | #version 1.0 2012 05 09 5 | version='1.0' 6 | def ptyellow(str): 7 | print '\x1b[0;33m'+str+'\x1b[0m' 8 | def ptred(str): 9 | print '\x1b[0;31m'+str+'\x1b[0m' 10 | def ptgreen(str): 11 | print '\x1b[0;32m'+str+'\x1b[0m' 12 | def ptyellow_no_enter(str): 13 | print '\x1b[0;33m'+str+'\x1b[0m', 14 | def ptred_no_enter(str): 15 | print '\x1b[0;31m'+str+'\x1b[0m', 16 | def ptgreen_no_enter(str): 17 | print '\x1b[0;32m'+str+'\x1b[0m', 18 | #ptyellow("testyellow") 19 | #ptred("testred") 20 | #ptgreen("testgreen") 21 | -------------------------------------------------------------------------------- /virtmod/osprobe.py: -------------------------------------------------------------------------------- 1 | import platform 2 | import string 3 | def virt_os_probe(): 4 | tmp_virt_os=platform.uname() 5 | virt_os=tmp_virt_os[2] 6 | #print virt_os 7 | #print string.find(virt_os,"3.10") 8 | if (string.find(virt_os,"3.10")>=0): 9 | hostos="c7" 10 | elif(string.find(virt_os,"2.6.32")>=0): 11 | hostos="c6" 12 | elif(string.find(virt_os,"2.6.18")>=0): 13 | hostos="c5" 14 | else: 15 | hostos="unknow" 16 | return hostos 17 | #print virt_os_probe() 18 | -------------------------------------------------------------------------------- /virtmod/syncTemp.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python 2 | 3 | 4 | import os 5 | import sys 6 | import string 7 | import commands 8 | import time 9 | #status, output = commands.getstatusoutput('ls -l') 10 | mycwd=os.getcwd() 11 | modcwd=mycwd+'/virtmod' 12 | sys.path.append(modcwd) 13 | modcwd=mycwd+'/virtclass' 14 | sys.path.append(modcwd) 15 | import colpt 16 | 17 | def chang_md5_file(filename): 18 | c=filename 19 | a="/datapool/"+filename 20 | b=c.split(".") 21 | d=b[0] 22 | f = open(a) 23 | readtext = f.read( ) 24 | f.close( ) 25 | var_md5 = readtext.split() 26 | f = open(a,"w") 27 | f.write(var_md5[0]+" /datapool/"+d+"\n") 28 | f.close 29 | 30 | def getTemp(filename,url): 31 | a=filename 32 | md5_file=a+".md5" 33 | b=url 34 | dlcmd="wget "+b+a+" -O /datapool/"+a+" -c " 35 | dlcmdmd5="wget "+b+a+".md5 -O /datapool/"+a+".md5 -c " 36 | #print dlcmd 37 | colpt.ptred("vm images not exists,Will download it ,Please wait a moment") 38 | #sys.exit(1) 39 | #p=os.popen(dlcmd).read() 40 | #status, output = commands.getstatusoutput(dlcmd) 41 | #statusmd5, outputmd5 = commands.getstatusoutput(dlcmdmd5) 42 | os.popen(dlcmd) 43 | os.popen(dlcmdmd5) 44 | colpt.ptgreen("**********************************************") 45 | i=1 46 | chang_md5_file(md5_file) 47 | #print str(status)+" is wget status !" 48 | #while (status != 0): 49 | # status, output = commands.getstatusoutput(dlcmd) 50 | # print str(status)+" is wget status ! and times is "+str(i) 51 | # i=i+1 52 | # if (i > 5): 53 | # print "vm images download failed" 54 | # return 10 55 | # break 56 | return 0 57 | #end 58 | def urlTest(url): 59 | urlTestCmd="wget -c "+url+"ratetest -O /datapool/ratetest" 60 | rmTestFile="rm -f /datapool/ratetest*" 61 | a=time.time() 62 | os.popen(urlTestCmd) 63 | os.popen(rmTestFile) 64 | b=time.time() 65 | c=b-a 66 | return c 67 | def geturl(url1,url2): 68 | c1=urlTest(url1) 69 | c2=urlTest(url2) 70 | if ( c2 < c1): 71 | return url2 72 | else: 73 | return url1 74 | #end 75 | def checkTempFile(filename,url1,url2): 76 | a=filename 77 | colpt.ptgreen("check vm images "+a) 78 | checkmd5="md5sum -c /datapool/"+a+".md5" 79 | #print checkmd5 80 | if os.path.isfile("/datapool/"+a): 81 | colpt.ptgreen("vm images "+a+" exists ok!") 82 | return 0 83 | else: 84 | colpt.ptyellow("vm images not exists ,Will download "+a) 85 | vmgeturl=geturl(url1,url2) 86 | b=getTemp(a,vmgeturl) 87 | if (b != 0): 88 | colpt.ptred("Download errors Please check !") 89 | return 11 90 | j=1 91 | statusCheckMd5, outputCheckMd5 = commands.getstatusoutput(checkmd5) 92 | print str(statusCheckMd5)+" md5 status is!" 93 | print "outputCheckMd5 is "+outputCheckMd5 94 | if (string.find(outputCheckMd5,"OK")>0): 95 | statusCheckMd5=0 96 | else: 97 | statusCheckMd5=1 98 | while (statusCheckMd5 != 0): 99 | os.system("rm /datapool/"+a+" -f") 100 | os.system("rm /datapool/"+a+"md5 -f") 101 | getTemp(a) 102 | statusCheckMd5, outputCheckMd5 = commands.getstatusoutput(checkmd5) 103 | j=j+1 104 | print str(statusCheckMd5)+" md5 status is!" 105 | if (j > 6): 106 | print "images sync filed" 107 | return 12 108 | colpt.ptgreen("Temp is ok!") 109 | return 0 110 | #end 111 | -------------------------------------------------------------------------------- /virtmod/virtcli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoli110/kvm_vm_setup/a1e4b155737bf48b5398f6921816a446ce30f597/virtmod/virtcli/__init__.py -------------------------------------------------------------------------------- /virtmod/virtcli/cli.cfg: -------------------------------------------------------------------------------- 1 | [config] 2 | prefix = /usr 3 | pkgversion = 0.10.0 4 | default_qemu_user = qemu 5 | libvirt_packages = libvirt-daemon-kvm,libvirt-daemon-config-network 6 | hv_packages = qemu-kvm 7 | askpass_packages = openssh-askpass 8 | preferred_distros = rhel,fedora 9 | stable_defaults = 1 10 | default_graphics = spice 11 | -------------------------------------------------------------------------------- /virtmod/virtcli/cliconfig.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2013, 2014 Red Hat, Inc. 3 | # 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 2 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | # MA 02110-1301 USA. 18 | # 19 | 20 | """ 21 | Configuration variables that can be set at build time 22 | """ 23 | 24 | import ConfigParser 25 | import os 26 | 27 | 28 | cfg = ConfigParser.ConfigParser() 29 | _filepath = os.path.abspath(__file__) 30 | _srcdir = os.path.abspath(os.path.join(os.path.dirname(_filepath), "..")) 31 | cfgpath = os.path.join(os.path.dirname(_filepath), "cli.cfg") 32 | if os.path.exists(cfgpath): 33 | cfg.read(cfgpath) 34 | 35 | 36 | def _split_list(commastr): 37 | return [d for d in commastr.split(",") if d] 38 | 39 | 40 | def _get_param(name, default): 41 | if not cfg.sections(): 42 | return default 43 | return cfg.get("config", name) 44 | 45 | 46 | def _setup_gsettings_path(schemadir): 47 | """ 48 | If running from the virt-manager.git srcdir, compile our gsettings 49 | schema and use it directly 50 | """ 51 | import subprocess 52 | 53 | os.environ["GSETTINGS_SCHEMA_DIR"] = schemadir 54 | ret = subprocess.call(["glib-compile-schemas", "--strict", schemadir]) 55 | if ret != 0: 56 | raise RuntimeError("Failed to compile local gsettings schemas") 57 | 58 | 59 | __version__ = "0.10.0" 60 | 61 | __snapshot__ = 0 62 | 63 | _usr_version = _get_param("pkgversion", "") 64 | if _usr_version is not None and _usr_version != "": 65 | __version__ = _usr_version 66 | 67 | # We should map this into the config somehow but I question if anyone cares 68 | prefix = _get_param("prefix", "/usr") 69 | gettext_dir = os.path.join(prefix, "share", "locale") 70 | install_asset_dir = os.path.join(prefix, "share", "virt-manager") 71 | if os.getcwd() == _srcdir: 72 | asset_dir = _srcdir 73 | icon_dir = os.path.join(_srcdir, "data") 74 | _setup_gsettings_path(icon_dir) 75 | else: 76 | asset_dir = install_asset_dir 77 | icon_dir = os.path.join(asset_dir, "icons") 78 | 79 | default_qemu_user = _get_param("default_qemu_user", "root") 80 | stable_defaults = bool(int(_get_param("stable_defaults", "0"))) 81 | 82 | preferred_distros = _split_list(_get_param("preferred_distros", "")) 83 | hv_packages = _split_list(_get_param("hv_packages", "")) 84 | askpass_package = _split_list(_get_param("askpass_packages", "")) 85 | libvirt_packages = _split_list(_get_param("libvirt_packages", "")) 86 | default_graphics = _get_param("default_graphics", "spice") 87 | -------------------------------------------------------------------------------- /virtmod/virtcli/cliutils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2011 Red Hat, Inc. 3 | # Copyright (C) 2011 Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | # 20 | 21 | import gettext 22 | import locale 23 | import logging 24 | import logging.handlers 25 | import os 26 | import sys 27 | import traceback 28 | 29 | import libvirt 30 | 31 | from virtcli import cliconfig 32 | 33 | 34 | 35 | def setup_logging(appname, debug_stdout): 36 | # Configure python logging to capture all logs we generate 37 | # to $HOME/.virt-manager/${app}.log This file has 38 | # proved invaluable for debugging 39 | MAX_LOGSIZE = 1024 * 1024 # 1MB 40 | ROTATE_NUM = 5 41 | DIR_NAME = ".virt-manager" 42 | FILE_NAME = "%s.log" % appname 43 | FILE_MODE = 'ae' 44 | FILE_FORMAT = ("[%(asctime)s virt-manager %(process)d] " 45 | "%(levelname)s (%(module)s:%(lineno)d) %(message)s") 46 | DATEFMT = "%a, %d %b %Y %H:%M:%S" 47 | 48 | # set up logging 49 | vm_dir = os.path.expanduser("~/%s" % DIR_NAME) 50 | if not os.access(vm_dir, os.W_OK): 51 | if os.path.exists(vm_dir): 52 | raise RuntimeError("No write access to %s" % vm_dir) 53 | 54 | try: 55 | os.mkdir(vm_dir, 0751) 56 | except IOError, e: 57 | raise RuntimeError("Could not create directory %s: %s" % 58 | (vm_dir, e)) 59 | 60 | filename = "%s/%s" % (vm_dir, FILE_NAME) 61 | rootLogger = logging.getLogger() 62 | rootLogger.setLevel(logging.DEBUG) 63 | fileHandler = logging.handlers.RotatingFileHandler(filename, 64 | FILE_MODE, MAX_LOGSIZE, ROTATE_NUM) 65 | fileHandler.setFormatter(logging.Formatter(FILE_FORMAT, DATEFMT)) 66 | rootLogger.addHandler(fileHandler) 67 | 68 | if debug_stdout: 69 | streamHandler = logging.StreamHandler(sys.stderr) 70 | streamHandler.setLevel(logging.DEBUG) 71 | streamHandler.setFormatter(logging.Formatter( 72 | "%(asctime)s (%(module)s:%(lineno)d): %(message)s")) 73 | rootLogger.addHandler(streamHandler) 74 | 75 | logging.info("%s startup", appname) 76 | 77 | # Register libvirt handler 78 | def libvirt_callback(ctx_ignore, err): 79 | if err[3] != libvirt.VIR_ERR_ERROR: 80 | # Don't log libvirt errors: global error handler will do that 81 | logging.warn("Non-error from libvirt: '%s'", err[2]) 82 | libvirt.registerErrorHandler(f=libvirt_callback, ctx=None) 83 | 84 | # Log uncaught exceptions 85 | def exception_log(typ, val, tb): 86 | s = traceback.format_exception(typ, val, tb) 87 | logging.debug("Uncaught exception:\n" + "".join(s)) 88 | sys.__excepthook__(typ, val, tb) 89 | sys.excepthook = exception_log 90 | 91 | 92 | def setup_i18n(): 93 | try: 94 | locale.setlocale(locale.LC_ALL, '') 95 | except: 96 | # Can happen if user passed a bogus LANG 97 | pass 98 | 99 | gettext.install("virt-manager", cliconfig.gettext_dir) 100 | gettext.bindtextdomain("virt-manager", cliconfig.gettext_dir) 101 | -------------------------------------------------------------------------------- /virtmod/virtinst/Boot.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Red Hat, Inc. 3 | # Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst import util 21 | from virtinst import XMLBuilderDomain 22 | from virtinst.XMLBuilderDomain import _xml_property 23 | 24 | 25 | class Boot(XMLBuilderDomain.XMLBuilderDomain): 26 | """ 27 | Class for generating boot device related XML 28 | """ 29 | 30 | BOOT_DEVICE_HARDDISK = "hd" 31 | BOOT_DEVICE_CDROM = "cdrom" 32 | BOOT_DEVICE_FLOPPY = "fd" 33 | BOOT_DEVICE_NETWORK = "network" 34 | boot_devices = [BOOT_DEVICE_HARDDISK, BOOT_DEVICE_CDROM, 35 | BOOT_DEVICE_FLOPPY, BOOT_DEVICE_NETWORK] 36 | 37 | _dumpxml_xpath = "/domain/os" 38 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 39 | XMLBuilderDomain.XMLBuilderDomain.__init__(self, conn, parsexml, 40 | parsexmlnode, caps) 41 | 42 | self._bootorder = [] 43 | self._enable_bootmenu = None 44 | self._kernel = None 45 | self._initrd = None 46 | self._kernel_args = None 47 | 48 | def _get_enable_bootmenu(self): 49 | return self._enable_bootmenu 50 | def _set_enable_bootmenu(self, val): 51 | self._enable_bootmenu = val 52 | def _get_menu_converter(self, val): 53 | ignore = self 54 | if val is None: 55 | return None 56 | return bool(val == "yes") 57 | enable_bootmenu = _xml_property(_get_enable_bootmenu, _set_enable_bootmenu, 58 | get_converter=_get_menu_converter, 59 | set_converter=lambda s, x: x and "yes" or "no", 60 | xpath="./os/bootmenu/@enable") 61 | 62 | def _get_bootorder(self): 63 | return self._bootorder 64 | def _set_bootorder(self, val): 65 | self._bootorder = val 66 | def _bootorder_xpath_list(self): 67 | l = [] 68 | for idx in range(len(self._get_bootorder())): 69 | l.append("./os/boot[%d]/@dev" % (idx + 1)) 70 | return l 71 | bootorder = _xml_property(_get_bootorder, _set_bootorder, 72 | is_multi=True, 73 | xml_set_list=_bootorder_xpath_list, 74 | xpath="./os/boot/@dev") 75 | 76 | def _get_kernel(self): 77 | return self._kernel 78 | def _set_kernel(self, val): 79 | self._kernel = val 80 | kernel = _xml_property(_get_kernel, _set_kernel, 81 | xpath="./os/kernel") 82 | 83 | def _get_initrd(self): 84 | return self._initrd 85 | def _set_initrd(self, val): 86 | self._initrd = val 87 | initrd = _xml_property(_get_initrd, _set_initrd, 88 | xpath="./os/initrd") 89 | 90 | def _get_kernel_args(self): 91 | return self._kernel_args 92 | def _set_kernel_args(self, val): 93 | self._kernel_args = val 94 | kernel_args = _xml_property(_get_kernel_args, _set_kernel_args, 95 | xpath="./os/cmdline") 96 | 97 | def _get_xml_config(self): 98 | xml = "" 99 | 100 | if self.kernel: 101 | xml = util.xml_append(xml, " %s" % 102 | util.xml_escape(self.kernel)) 103 | if self.initrd: 104 | xml = util.xml_append(xml, " %s" % 105 | util.xml_escape(self.initrd)) 106 | if self.kernel_args: 107 | xml = util.xml_append(xml, " %s" % 108 | util.xml_escape(self.kernel_args)) 109 | 110 | else: 111 | for dev in self.bootorder: 112 | xml = util.xml_append(xml, " " % dev) 113 | 114 | if self.enable_bootmenu in [True, False]: 115 | val = self.enable_bootmenu and "yes" or "no" 116 | xml = util.xml_append(xml, 117 | " " % val) 118 | 119 | return xml 120 | -------------------------------------------------------------------------------- /virtmod/virtinst/CPU.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Red Hat, Inc. 3 | # Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst import XMLBuilderDomain 21 | from virtinst.XMLBuilderDomain import _xml_property 22 | 23 | import libxml2 24 | 25 | 26 | def _int_or_none(val): 27 | return val and int(val) or val 28 | 29 | 30 | class CPUFeature(XMLBuilderDomain.XMLBuilderDomain): 31 | """ 32 | Class for generating child XML 33 | """ 34 | 35 | POLICIES = ["force", "require", "optional", "disable", "forbid"] 36 | 37 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 38 | XMLBuilderDomain.XMLBuilderDomain.__init__(self, conn, parsexml, 39 | parsexmlnode, caps) 40 | 41 | self._name = None 42 | self._policy = None 43 | 44 | if self._is_parse(): 45 | return 46 | 47 | def _get_name(self): 48 | return self._name 49 | def _set_name(self, val): 50 | self._name = val 51 | name = _xml_property(_get_name, _set_name, 52 | xpath="./@name") 53 | 54 | def _get_policy(self): 55 | return self._policy 56 | def _set_policy(self, val): 57 | self._policy = val 58 | policy = _xml_property(_get_policy, _set_policy, 59 | xpath="./@policy") 60 | 61 | def _get_xml_config(self): 62 | if not self.name: 63 | return "" 64 | 65 | xml = " XML 76 | """ 77 | 78 | _dumpxml_xpath = "/domain/cpu" 79 | 80 | MATCHS = ["minimum", "exact", "strict"] 81 | 82 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 83 | self._model = None 84 | self._match = None 85 | self._vendor = None 86 | self._mode = None 87 | self._features = [] 88 | 89 | self._sockets = None 90 | self._cores = None 91 | self._threads = None 92 | 93 | XMLBuilderDomain.XMLBuilderDomain.__init__(self, conn, parsexml, 94 | parsexmlnode, caps) 95 | if self._is_parse(): 96 | return 97 | 98 | def _parsexml(self, xml, node): 99 | XMLBuilderDomain.XMLBuilderDomain._parsexml(self, xml, node) 100 | 101 | for node in self._xml_node.children: 102 | if node.name != "feature": 103 | continue 104 | feature = CPUFeature(self.conn, parsexmlnode=node) 105 | self._features.append(feature) 106 | 107 | def _get_features(self): 108 | return self._features[:] 109 | features = _xml_property(_get_features) 110 | 111 | def add_feature(self, name, policy="require"): 112 | feature = CPUFeature(self.conn) 113 | feature.name = name 114 | feature.policy = policy 115 | 116 | if self._is_parse(): 117 | xml = feature.get_xml_config() 118 | node = libxml2.parseDoc(xml).children 119 | feature.set_xml_node(node) 120 | self._add_child_node("./cpu", node) 121 | 122 | self._features.append(feature) 123 | 124 | def remove_feature(self, feature): 125 | if self._is_parse() and feature in self._features: 126 | xpath = feature.get_xml_node_path() 127 | if xpath: 128 | self._remove_child_xpath(xpath) 129 | 130 | self._features.remove(feature) 131 | 132 | 133 | def _get_model(self): 134 | return self._model 135 | def _set_model(self, val): 136 | if val: 137 | self.mode = "custom" 138 | if val and not self.match: 139 | self.match = "exact" 140 | self._model = val 141 | model = _xml_property(_get_model, _set_model, 142 | xpath="./cpu/model") 143 | 144 | def _get_match(self): 145 | return self._match 146 | def _set_match(self, val): 147 | self._match = val 148 | match = _xml_property(_get_match, _set_match, 149 | xpath="./cpu/@match") 150 | 151 | def _get_vendor(self): 152 | return self._vendor 153 | def _set_vendor(self, val): 154 | self._vendor = val 155 | vendor = _xml_property(_get_vendor, _set_vendor, 156 | xpath="./cpu/vendor") 157 | 158 | def _get_mode(self): 159 | return self._mode 160 | def _set_mode(self, val): 161 | self._mode = val 162 | mode = _xml_property(_get_mode, _set_mode, 163 | xpath="./cpu/@mode") 164 | 165 | # Topology properties 166 | def _get_sockets(self): 167 | return self._sockets 168 | def _set_sockets(self, val): 169 | self._sockets = _int_or_none(val) 170 | sockets = _xml_property(_get_sockets, _set_sockets, 171 | get_converter=lambda s, x: _int_or_none(x), 172 | xpath="./cpu/topology/@sockets") 173 | 174 | def _get_cores(self): 175 | return self._cores 176 | def _set_cores(self, val): 177 | self._cores = _int_or_none(val) 178 | cores = _xml_property(_get_cores, _set_cores, 179 | get_converter=lambda s, x: _int_or_none(x), 180 | xpath="./cpu/topology/@cores") 181 | 182 | def _get_threads(self): 183 | return self._threads 184 | def _set_threads(self, val): 185 | self._threads = _int_or_none(val) 186 | threads = _xml_property(_get_threads, _set_threads, 187 | get_converter=lambda s, x: _int_or_none(x), 188 | xpath="./cpu/topology/@threads") 189 | 190 | def clear_attrs(self): 191 | self.match = None 192 | self.mode = None 193 | self.vendor = None 194 | self.model = None 195 | 196 | for feature in self.features: 197 | self.remove_feature(feature) 198 | 199 | def copy_host_cpu(self): 200 | """ 201 | Enact the equivalent of qemu -cpu host, pulling all info 202 | from capabilities about the host CPU 203 | """ 204 | cpu = self._get_caps().host.cpu 205 | if not cpu.model: 206 | raise ValueError(_("No host CPU reported in capabilities")) 207 | 208 | self.mode = "custom" 209 | self.match = "exact" 210 | self.model = cpu.model 211 | self.vendor = cpu.vendor 212 | 213 | for feature in self.features: 214 | self.remove_feature(feature) 215 | for name in cpu.features.names(): 216 | self.add_feature(name) 217 | 218 | def vcpus_from_topology(self): 219 | """ 220 | Determine the CPU count represented by topology, or 1 if 221 | no topology is set 222 | """ 223 | self.set_topology_defaults() 224 | if self.sockets: 225 | return self.sockets * self.cores * self.threads 226 | return 1 227 | 228 | def set_topology_defaults(self, vcpus=None): 229 | """ 230 | Fill in unset topology values, using the passed vcpus count if 231 | required 232 | """ 233 | if (self.sockets is None and 234 | self.cores is None and 235 | self.threads is None): 236 | return 237 | 238 | if vcpus is None: 239 | if self.sockets is None: 240 | self.sockets = 1 241 | if self.threads is None: 242 | self.threads = 1 243 | if self.cores is None: 244 | self.cores = 1 245 | 246 | vcpus = int(vcpus or 0) 247 | if not self.sockets: 248 | if not self.cores: 249 | self.sockets = vcpus / self.threads 250 | else: 251 | self.sockets = vcpus / self.cores 252 | 253 | if not self.cores: 254 | if not self.threads: 255 | self.cores = vcpus / self.sockets 256 | else: 257 | self.cores = vcpus / (self.sockets * self.threads) 258 | 259 | if not self.threads: 260 | self.threads = vcpus / (self.sockets * self.cores) 261 | 262 | return 263 | 264 | def _get_topology_xml(self): 265 | xml = "" 266 | if self.sockets: 267 | xml += " sockets='%s'" % self.sockets 268 | if self.cores: 269 | xml += " cores='%s'" % self.cores 270 | if self.threads: 271 | xml += " threads='%s'" % self.threads 272 | 273 | if not xml: 274 | return "" 275 | return " \n" % xml 276 | 277 | def _get_feature_xml(self): 278 | xml = "" 279 | for feature in self._features: 280 | xml += feature.get_xml_config() + "\n" 281 | return xml 282 | 283 | def _get_xml_config(self): 284 | top_xml = self._get_topology_xml() 285 | feature_xml = self._get_feature_xml() 286 | mode_xml = "" 287 | match_xml = "" 288 | if self.match: 289 | match_xml = " match='%s'" % self.match 290 | xml = "" 291 | 292 | if self.model == "host-passthrough": 293 | self.mode = "host-passthrough" 294 | mode_xml = " mode='%s'" % self.mode 295 | xml += " " % mode_xml 296 | return xml 297 | else: 298 | self.mode = "custom" 299 | mode_xml = " mode='%s'" % self.mode 300 | 301 | if not (self.model or top_xml or feature_xml): 302 | return "" 303 | 304 | # Simple topology XML mode 305 | xml += " \n" % (mode_xml, match_xml) 306 | if self.model: 307 | xml += " %s\n" % self.model 308 | if self.vendor: 309 | xml += " %s\n" % self.vendor 310 | if top_xml: 311 | xml += top_xml 312 | if feature_xml: 313 | xml += feature_xml 314 | 315 | xml += " " 316 | return xml 317 | -------------------------------------------------------------------------------- /virtmod/virtinst/Clock.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Red Hat, Inc. 3 | # Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst import XMLBuilderDomain 21 | from virtinst.XMLBuilderDomain import _xml_property 22 | 23 | 24 | class Clock(XMLBuilderDomain.XMLBuilderDomain): 25 | """ 26 | Class for generating XML 27 | """ 28 | 29 | _dumpxml_xpath = "/domain/clock" 30 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 31 | XMLBuilderDomain.XMLBuilderDomain.__init__(self, conn, parsexml, 32 | parsexmlnode, caps) 33 | 34 | self._offset = None 35 | 36 | def get_offset(self): 37 | return self._offset 38 | def set_offset(self, val): 39 | self._offset = val 40 | offset = _xml_property(get_offset, set_offset, 41 | xpath="./clock/@offset") 42 | 43 | def _get_xml_config(self): 44 | if not self.offset: 45 | return "" 46 | 47 | return """ """ % self.offset 48 | -------------------------------------------------------------------------------- /virtmod/virtinst/DomainFeatures.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Red Hat, Inc. 3 | # Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst import XMLBuilderDomain 21 | from virtinst.XMLBuilderDomain import _xml_property 22 | 23 | 24 | def _none_or_bool(val): 25 | if val is None: 26 | return val 27 | return bool(val) 28 | 29 | 30 | class DomainFeatures(XMLBuilderDomain.XMLBuilderDomain): 31 | """ 32 | Class for generating XML 33 | """ 34 | 35 | _dumpxml_xpath = "/domain/features" 36 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 37 | XMLBuilderDomain.XMLBuilderDomain.__init__(self, conn, parsexml, 38 | parsexmlnode, caps) 39 | 40 | self._acpi = None 41 | self._apic = None 42 | self._pae = None 43 | 44 | def get_acpi(self): 45 | return self._acpi 46 | def set_acpi(self, val): 47 | self._acpi = _none_or_bool(val) 48 | acpi = _xml_property(get_acpi, set_acpi, 49 | xpath="./features/acpi", is_bool=True) 50 | 51 | def get_apic(self): 52 | return self._apic 53 | def set_apic(self, val): 54 | self._apic = _none_or_bool(val) 55 | apic = _xml_property(get_apic, set_apic, 56 | xpath="./features/apic", is_bool=True) 57 | 58 | def get_pae(self): 59 | return self._pae 60 | def set_pae(self, val): 61 | self._pae = _none_or_bool(val) 62 | pae = _xml_property(get_pae, set_pae, 63 | xpath="./features/pae", is_bool=True) 64 | 65 | def __setitem__(self, attr, val): 66 | return setattr(self, attr, val) 67 | def __getitem__(self, attr): 68 | return getattr(self, attr) 69 | def __delitem__(self, attr): 70 | return setattr(self, attr, None) 71 | 72 | 73 | def _get_xml_config(self, defaults=None): 74 | # pylint: disable=W0221 75 | # Argument number differs from overridden method 76 | 77 | if not defaults: 78 | defaults = {} 79 | ret = "" 80 | 81 | feature_xml = "" 82 | if self.acpi or (self.acpi is None and defaults.get("acpi")): 83 | feature_xml += "" 84 | if self.apic or (self.apic is None and defaults.get("apic")): 85 | feature_xml += "" 86 | if self.pae or (self.pae is None and defaults.get("pae")): 87 | feature_xml += "" 88 | 89 | if feature_xml: 90 | ret += " \n" 91 | ret += " %s\n" % feature_xml 92 | ret += " " 93 | 94 | return ret 95 | -------------------------------------------------------------------------------- /virtmod/virtinst/DomainNumatune.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Red Hat, Inc. 3 | # Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | import re 21 | 22 | from virtinst import XMLBuilderDomain 23 | from virtinst.XMLBuilderDomain import _xml_property 24 | 25 | 26 | def get_phy_cpus(conn): 27 | """ 28 | Get number of physical CPUs. 29 | """ 30 | hostinfo = conn.getInfo() 31 | pcpus = hostinfo[4] * hostinfo[5] * hostinfo[6] * hostinfo[7] 32 | return pcpus 33 | 34 | 35 | class DomainNumatune(XMLBuilderDomain.XMLBuilderDomain): 36 | """ 37 | Class for generating XML 38 | """ 39 | 40 | @staticmethod 41 | def validate_cpuset(conn, val): 42 | if val is None or val == "": 43 | return 44 | 45 | if not isinstance(val, str) or len(val) == 0: 46 | raise ValueError(_("cpuset must be string")) 47 | if re.match("^[0-9,-^]*$", val) is None: 48 | raise ValueError(_("cpuset can only contain numeric, ',', '^', or " 49 | "'-' characters")) 50 | 51 | pcpus = get_phy_cpus(conn) 52 | for c in val.split(','): 53 | # Redundant commas 54 | if not c: 55 | continue 56 | 57 | if "-" in c: 58 | (x, y) = c.split('-', 1) 59 | x = int(x) 60 | y = int(y) 61 | if x > y: 62 | raise ValueError(_("cpuset contains invalid format.")) 63 | if x >= pcpus or y >= pcpus: 64 | raise ValueError(_("cpuset's pCPU numbers must be less " 65 | "than pCPUs.")) 66 | else: 67 | if c.startswith("^"): 68 | c = c[1:] 69 | c = int(c) 70 | 71 | if c >= pcpus: 72 | raise ValueError(_("cpuset's pCPU numbers must be less " 73 | "than pCPUs.")) 74 | 75 | @staticmethod 76 | def cpuset_str_to_tuple(conn, cpuset): 77 | DomainNumatune.validate_cpuset(conn, cpuset) 78 | pinlist = [False] * get_phy_cpus(conn) 79 | 80 | entries = cpuset.split(",") 81 | for e in entries: 82 | series = e.split("-", 1) 83 | 84 | if len(series) == 1: 85 | pinlist[int(series[0])] = True 86 | continue 87 | 88 | start = int(series[0]) 89 | end = int(series[1]) 90 | 91 | for i in range(start, end + 1): 92 | pinlist[i] = True 93 | 94 | return tuple(pinlist) 95 | 96 | _dumpxml_xpath = "/domain/numatune" 97 | 98 | MEMORY_MODES = ["interleave", "strict", "preferred"] 99 | 100 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 101 | self._memory_nodeset = None 102 | self._memory_mode = None 103 | 104 | XMLBuilderDomain.XMLBuilderDomain.__init__(self, conn, parsexml, 105 | parsexmlnode, caps) 106 | if self._is_parse(): 107 | return 108 | 109 | def _get_memory_nodeset(self): 110 | return self._memory_nodeset 111 | def _set_memory_nodeset(self, val): 112 | self._memory_nodeset = val 113 | memory_nodeset = _xml_property(_get_memory_nodeset, 114 | _set_memory_nodeset, 115 | xpath="./numatune/memory/@nodeset") 116 | 117 | def _get_memory_mode(self): 118 | return self._memory_mode 119 | def _set_memory_mode(self, val): 120 | self._memory_mode = val 121 | memory_mode = _xml_property(_get_memory_mode, 122 | _set_memory_mode, 123 | xpath="./numatune/memory/@mode") 124 | 125 | def _get_memory_xml(self): 126 | if not self.memory_nodeset: 127 | return "" 128 | 129 | xml = " 6 | # 7 | # This program is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 20 | # MA 02110-1301 USA. 21 | 22 | import logging 23 | import os 24 | import stat 25 | import subprocess 26 | import urlgrabber.grabber as grabber 27 | import urllib2 28 | import urlparse 29 | import ftplib 30 | import tempfile 31 | 32 | 33 | # This is a generic base class for fetching/extracting files from 34 | # a media source, such as CD ISO, NFS server, or HTTP/FTP server 35 | class ImageFetcher: 36 | 37 | def __init__(self, location, scratchdir): 38 | self.location = location 39 | self.scratchdir = scratchdir 40 | 41 | def _make_path(self, filename): 42 | if hasattr(self, "srcdir"): 43 | path = getattr(self, "srcdir") 44 | else: 45 | path = self.location 46 | 47 | if filename: 48 | if not path.endswith("/"): 49 | path += "/" 50 | path += filename 51 | 52 | return path 53 | 54 | def saveTemp(self, fileobj, prefix): 55 | if not os.path.exists(self.scratchdir): 56 | os.makedirs(self.scratchdir, 0750) 57 | (fd, fn) = tempfile.mkstemp(prefix="virtinst-" + prefix, 58 | dir=self.scratchdir) 59 | block_size = 16384 60 | try: 61 | while 1: 62 | buff = fileobj.read(block_size) 63 | if not buff: 64 | break 65 | os.write(fd, buff) 66 | finally: 67 | os.close(fd) 68 | return fn 69 | 70 | def prepareLocation(self): 71 | return True 72 | 73 | def cleanupLocation(self): 74 | pass 75 | 76 | def acquireFile(self, filename, progresscb): 77 | # URLGrabber works for all network and local cases 78 | 79 | f = None 80 | try: 81 | path = self._make_path(filename) 82 | base = os.path.basename(filename) 83 | logging.debug("Fetching URI: %s", path) 84 | 85 | try: 86 | f = grabber.urlopen(path, 87 | progress_obj=progresscb, 88 | text=_("Retrieving file %s...") % base) 89 | except Exception, e: 90 | raise ValueError(_("Couldn't acquire file %s: %s") % 91 | (path, str(e))) 92 | 93 | tmpname = self.saveTemp(f, prefix=base + ".") 94 | logging.debug("Saved file to " + tmpname) 95 | return tmpname 96 | finally: 97 | if f: 98 | f.close() 99 | 100 | 101 | def hasFile(self, src): 102 | raise NotImplementedError("Must be implemented in subclass") 103 | 104 | # Base class for downloading from FTP / HTTP 105 | 106 | 107 | class URIImageFetcher(ImageFetcher): 108 | 109 | def hasFile(self, filename): 110 | raise NotImplementedError 111 | 112 | def prepareLocation(self): 113 | if not self.hasFile(""): 114 | raise ValueError(_("Opening URL %s failed.") % 115 | (self.location)) 116 | 117 | 118 | class HTTPImageFetcher(URIImageFetcher): 119 | 120 | def hasFile(self, filename): 121 | try: 122 | path = self._make_path(filename) 123 | request = urllib2.Request(path) 124 | request.get_method = lambda: "HEAD" 125 | urllib2.urlopen(request) 126 | except Exception, e: 127 | logging.debug("HTTP hasFile: didn't find %s: %s", path, str(e)) 128 | return False 129 | return True 130 | 131 | 132 | class FTPImageFetcher(URIImageFetcher): 133 | 134 | def __init__(self, location, scratchdir): 135 | URIImageFetcher.__init__(self, location, scratchdir) 136 | 137 | self.ftp = None 138 | 139 | def prepareLocation(self): 140 | url = urlparse.urlparse(self._make_path("")) 141 | self.ftp = ftplib.FTP(url[1]) 142 | self.ftp.login() 143 | 144 | def hasFile(self, filename): 145 | path = self._make_path(filename) 146 | url = urlparse.urlparse(path) 147 | 148 | try: 149 | try: 150 | # If it's a file 151 | self.ftp.size(url[2]) 152 | except ftplib.all_errors: 153 | # If it's a dir 154 | self.ftp.cwd(url[2]) 155 | except ftplib.all_errors, e: 156 | logging.debug("FTP hasFile: couldn't access %s: %s", 157 | path, str(e)) 158 | return False 159 | 160 | return True 161 | 162 | 163 | class LocalImageFetcher(ImageFetcher): 164 | 165 | def __init__(self, location, scratchdir, srcdir=None): 166 | ImageFetcher.__init__(self, location, scratchdir) 167 | self.srcdir = srcdir 168 | 169 | def hasFile(self, filename): 170 | src = self._make_path(filename) 171 | if os.path.exists(src): 172 | return True 173 | else: 174 | logging.debug("local hasFile: Couldn't find %s", src) 175 | return False 176 | 177 | # This is a fetcher capable of extracting files from a NFS server 178 | # or loopback mounted file, or local CDROM device 179 | 180 | 181 | class MountedImageFetcher(LocalImageFetcher): 182 | 183 | def prepareLocation(self): 184 | cmd = None 185 | self.srcdir = tempfile.mkdtemp(prefix="virtinstmnt.", 186 | dir=self.scratchdir) 187 | mountcmd = "/bin/mount" 188 | if os.uname()[0] == "SunOS": 189 | mountcmd = "/usr/sbin/mount" 190 | 191 | logging.debug("Preparing mount at " + self.srcdir) 192 | if self.location.startswith("nfs:"): 193 | cmd = [mountcmd, "-o", "ro", self.location[4:], self.srcdir] 194 | else: 195 | if stat.S_ISBLK(os.stat(self.location)[stat.ST_MODE]): 196 | mountopt = "ro" 197 | else: 198 | mountopt = "ro,loop" 199 | if os.uname()[0] == 'SunOS': 200 | cmd = [mountcmd, "-F", "hsfs", "-o", 201 | mountopt, self.location, self.srcdir] 202 | else: 203 | cmd = [mountcmd, "-o", mountopt, self.location, self.srcdir] 204 | ret = subprocess.call(cmd) 205 | if ret != 0: 206 | self.cleanupLocation() 207 | raise ValueError(_("Mounting location '%s' failed") % 208 | (self.location)) 209 | return True 210 | 211 | def cleanupLocation(self): 212 | logging.debug("Cleaning up mount at " + self.srcdir) 213 | if os.uname()[0] == "SunOS": 214 | cmd = ["/usr/sbin/umount", self.srcdir] 215 | else: 216 | cmd = ["/bin/umount", self.srcdir] 217 | subprocess.call(cmd) 218 | try: 219 | os.rmdir(self.srcdir) 220 | except: 221 | pass 222 | 223 | 224 | class DirectImageFetcher(LocalImageFetcher): 225 | 226 | def prepareLocation(self): 227 | self.srcdir = self.location 228 | -------------------------------------------------------------------------------- /virtmod/virtinst/ImageInstaller.py: -------------------------------------------------------------------------------- 1 | # Installer for images 2 | # 3 | # Copyright 2007 Red Hat, Inc. 4 | # David Lutterkort 5 | # 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | # MA 02110-1301 USA. 20 | 21 | import os 22 | 23 | from virtinst import Installer 24 | from virtinst import ImageParser 25 | from virtinst import CapabilitiesParser as Cap 26 | from virtinst.VirtualDisk import VirtualDisk 27 | 28 | 29 | class ImageInstallerException(Exception): 30 | def __init__(self, msg): 31 | Exception.__init__(self, msg) 32 | 33 | 34 | class ImageInstaller(Installer.Installer): 35 | """ 36 | Installer for virt-image-based guests 37 | """ 38 | _has_install_phase = False 39 | 40 | def __init__(self, image, capabilities=None, boot_index=None, conn=None): 41 | Installer.Installer.__init__(self, conn=conn, caps=capabilities) 42 | 43 | self._arch = None 44 | self._image = image 45 | 46 | if not (self.conn or self._get_caps()): 47 | raise ValueError(_("'conn' or 'capabilities' must be specified.")) 48 | 49 | # Set boot _boot_caps/_boot_parameters 50 | if boot_index is None: 51 | self._boot_caps = match_boots(self._get_caps(), 52 | self.image.domain.boots) 53 | if self._boot_caps is None: 54 | raise ImageInstallerException(_("Could not find suitable boot " 55 | "descriptor for this host")) 56 | else: 57 | if (boot_index < 0 or 58 | (boot_index + 1) > len(image.domain.boots)): 59 | raise ValueError(_("boot_index out of range.")) 60 | self._boot_caps = image.domain.boots[boot_index] 61 | 62 | # Set up internal caps.guest object 63 | self._guest = self._get_caps().guestForOSType(self.boot_caps.type, 64 | self.boot_caps.arch) 65 | if self._guest is None: 66 | raise PlatformMatchException(_("Unsupported virtualization type: " 67 | "%s %s" % (self.boot_caps.type, 68 | self.boot_caps.arch))) 69 | 70 | self.os_type = self.boot_caps.type 71 | self._domain = self._guest.bestDomainType() 72 | self.type = self._domain.hypervisor_type 73 | self.arch = self._guest.arch 74 | 75 | 76 | # Custom ImageInstaller methods 77 | 78 | def is_hvm(self): 79 | if self._boot_caps.type == "hvm": 80 | return True 81 | return False 82 | 83 | def get_image(self): 84 | return self._image 85 | image = property(get_image) 86 | 87 | def get_boot_caps(self): 88 | return self._boot_caps 89 | boot_caps = property(get_boot_caps) 90 | 91 | 92 | # General Installer methods 93 | 94 | def prepare(self, guest, meter): 95 | self.cleanup() 96 | 97 | self._make_disks() 98 | 99 | for f in ['pae', 'acpi', 'apic']: 100 | if self.boot_caps.features[f] & Cap.FEATURE_ON: 101 | guest.features[f] = True 102 | elif self.boot_caps.features[f] & Cap.FEATURE_OFF: 103 | guest.features[f] = False 104 | 105 | self.bootconfig.kernel = self.boot_caps.kernel 106 | self.bootconfig.initrd = self.boot_caps.initrd 107 | self.bootconfig.kernel_args = self.boot_caps.cmdline 108 | 109 | # Private methods 110 | def _get_bootdev(self, isinstall, guest): 111 | return self.boot_caps.bootdev 112 | 113 | def _make_disks(self): 114 | for drive in self.boot_caps.drives: 115 | path = self._abspath(drive.disk.file) 116 | size = None 117 | if drive.disk.size is not None: 118 | size = float(drive.disk.size) / 1024 119 | 120 | # FIXME: This is awkward; the image should be able to express 121 | # whether the disk is expected to be there or not independently 122 | # of its classification, especially for user disks 123 | # FIXME: We ignore the target for the mapping in m.target 124 | if (drive.disk.use == ImageParser.Disk.USE_SYSTEM and 125 | not os.path.exists(path)): 126 | raise ImageInstallerException(_("System disk %s does not exist") 127 | % path) 128 | 129 | device = VirtualDisk.DEVICE_DISK 130 | if drive.disk.format == ImageParser.Disk.FORMAT_ISO: 131 | device = VirtualDisk.DEVICE_CDROM 132 | 133 | 134 | disk = VirtualDisk(conn=self.conn, 135 | path=path, 136 | size=size, 137 | device=device, 138 | format=drive.disk.format) 139 | disk.target = drive.target 140 | 141 | self.install_devices.append(disk) 142 | 143 | def _abspath(self, p): 144 | return self.image.abspath(p) 145 | 146 | 147 | class PlatformMatchException(Exception): 148 | def __init__(self, msg): 149 | Exception.__init__(self, msg) 150 | 151 | 152 | def match_boots(capabilities, boots): 153 | for b in boots: 154 | for g in capabilities.guests: 155 | if b.type == g.os_type and b.arch == g.arch: 156 | found = True 157 | for bf in b.features.names(): 158 | if not b.features[bf] & g.features[bf]: 159 | found = False 160 | break 161 | if found: 162 | return b 163 | return None 164 | -------------------------------------------------------------------------------- /virtmod/virtinst/ImageParser.py: -------------------------------------------------------------------------------- 1 | # Sample code to parse an image XML description and 2 | # spit out libvirt XML; will be hooked into virt-install 3 | # 4 | # Copyright 2007, 2013 Red Hat, Inc. 5 | # David Lutterkort 6 | # 7 | # This program is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 20 | # MA 02110-1301 USA. 21 | 22 | import logging 23 | import os 24 | 25 | import libxml2 26 | import urlgrabber 27 | 28 | from virtinst import CapabilitiesParser 29 | from virtinst import util 30 | 31 | 32 | class ParserException(Exception): 33 | def __init__(self, msg): 34 | Exception.__init__(self, msg) 35 | 36 | 37 | class Image: 38 | """The toplevel object representing a VM image""" 39 | def __init__(self, node=None, base=None, filename=None): 40 | self.storage = {} 41 | self.domain = None 42 | if filename is None: 43 | self.filename = None 44 | else: 45 | self.filename = os.path.abspath(filename) 46 | if base is None: 47 | if filename is not None: 48 | self.base = os.path.dirname(filename) 49 | if self.base == '': 50 | self.base = "." 51 | else: 52 | self.base = "." 53 | else: 54 | self.base = base 55 | self.name = None 56 | self.label = None 57 | self.descr = None 58 | self.version = None 59 | self.release = None 60 | if not node is None: 61 | self.parseXML(node) 62 | 63 | def abspath(self, p): 64 | """Turn P into an absolute path. Relative paths are taken relative 65 | to self.BASE""" 66 | return os.path.abspath(os.path.join(self.base, p)) 67 | 68 | def parseXML(self, node): 69 | self.name = xpathString(node, "name") 70 | self.label = xpathString(node, "label") 71 | self.descr = xpathString(node, "description") 72 | self.version = xpathString(node, "name/@version") 73 | self.release = xpathString(node, "name/@release") 74 | for d in node.xpathEval("storage/disk"): 75 | disk = Disk(d) 76 | if disk.file is None: 77 | disk.id = "disk%d.img" % len(self.storage) 78 | disk.file = "disk%d.img" % (len(self.storage) + 1) 79 | if disk.id in self.storage: 80 | raise ParserException("Disk file '%s' defined twice" 81 | % disk.file) 82 | self.storage[disk.id] = disk 83 | lm = node.xpathEval("domain") 84 | if len(lm) == 1: 85 | self.domain = Domain(lm[0]) 86 | else: 87 | raise ParserException(_("Expected exactly one 'domain' element")) 88 | # Connect the disk maps to the disk definitions 89 | for boot in self.domain.boots: 90 | for d in boot.drives: 91 | if d.disk_id not in self.storage: 92 | raise ParserException(_("Disk entry for '%s' not found") 93 | % d.disk_id) 94 | d.disk = self.storage[d.disk_id] 95 | 96 | 97 | class Domain: 98 | """The description of a virtual domain as part of an image""" 99 | def __init__(self, node=None): 100 | self.boots = [] 101 | self.vcpu = None 102 | self.memory = None 103 | self.interface = 0 104 | self.graphics = None 105 | if not node is None: 106 | self.parseXML(node) 107 | 108 | def parseXML(self, node): 109 | self.boots = [Boot(b) for b in node.xpathEval("boot")] 110 | self.vcpu = xpathString(node, "devices/vcpu", 1) 111 | tmpmem = xpathString(node, "devices/memory") 112 | self.interface = int(node.xpathEval("count(devices/interface)")) 113 | self.graphics = node.xpathEval("count(devices/graphics)") > 0 114 | 115 | if tmpmem is not None: 116 | try: 117 | self.memory = int(tmpmem) 118 | except ValueError: 119 | raise ParserException(_("Memory must be an integer, " 120 | "but is '%s'") % self.memory) 121 | else: 122 | tmpmem = 0 123 | 124 | 125 | class ImageFeatures(CapabilitiesParser.Features): 126 | def __init__(self, node=None): 127 | CapabilitiesParser.Features.__init__(self, node) 128 | 129 | def _extractFeature(self, feature, d, n): 130 | state = xpathString(n, "@state", "on") 131 | 132 | if state == "on": 133 | d[feature] = CapabilitiesParser.FEATURE_ON 134 | elif state == "off": 135 | d[feature] = CapabilitiesParser.FEATURE_OFF 136 | else: 137 | raise ParserException("The state for feature %s must be either 'on' or 'off', but is '%s'" % (feature, state)) 138 | 139 | 140 | class Boot: 141 | """The overall description of how the image can be booted, including 142 | required capabilities of the host and mapping of disks into the VM""" 143 | def __init__(self, node=None): 144 | # 'xen' or 'hvm' 145 | self.type = None 146 | # Either 'pygrub' or nothing; might have others in the future 147 | # For HVM, figure outhte right loader based on the guest 148 | self.loader = None 149 | # Only used for hvm 150 | self.bootdev = None 151 | self.kernel = None 152 | self.initrd = None 153 | self.cmdline = None 154 | self.drives = [] 155 | self.arch = None 156 | self.features = ImageFeatures() 157 | if not node is None: 158 | self.parseXML(node) 159 | 160 | def parseXML(self, node): 161 | self.type = xpathString(node, "@type") 162 | self.loader = xpathString(node, "os/loader") 163 | self.bootdev = xpathString(node, "os/loader/@dev") 164 | self.kernel = xpathString(node, "os/kernel") 165 | self.initrd = xpathString(node, "os/initrd") 166 | self.cmdline = xpathString(node, "os/cmdline") 167 | self.arch = util.sanitize_arch(xpathString(node, "guest/arch")) 168 | 169 | fl = node.xpathEval("guest/features") 170 | if len(fl) > 1: 171 | raise ParserException("Expected at most one element in %s boot descriptor for %s" % (self.type, self.arch)) 172 | elif len(fl) == 1: 173 | self.features = ImageFeatures(fl[0]) 174 | 175 | for d in node.xpathEval("drive"): 176 | self.drives.append(Drive(d)) 177 | 178 | validate(self.type is not None, 179 | "The boot type must be provided") 180 | validate(self.type == "hvm" or self.type == "xen", 181 | "Boot type must be 'xen' or 'hvm', but is %s" % self.type) 182 | validate(self.arch is not None, "Missing guest arch") 183 | validate(self.loader is None or self.loader == "pygrub", 184 | "Invalid loader %s" % self.loader) 185 | validate([None, "hd", "cdrom"].count(self.bootdev) > 0, 186 | "Invalid bootdev %s" % self.bootdev) 187 | # We should make sure that kernel/initrd/cmdline are only used for pv 188 | # and without a loader 189 | 190 | 191 | class Drive: 192 | """The mapping of a disk from the storage section to a virtual drive 193 | in a guest""" 194 | def __init__(self, node=None): 195 | self.disk_id = None 196 | self.target = None 197 | self.disk = None # Will point to the underlying Disk object 198 | if node: 199 | self.parseXML(node) 200 | 201 | def parseXML(self, node): 202 | self.disk_id = xpathString(node, "@disk") 203 | self.target = xpathString(node, "@target") 204 | 205 | 206 | class Disk: 207 | FORMAT_RAW = "raw" 208 | FORMAT_ISO = "iso" 209 | FORMAT_QCOW = "qcow" 210 | FORMAT_QCOW2 = "qcow2" 211 | FORMAT_VMDK = "vmdk" 212 | FORMAT_VDI = "vdi" 213 | 214 | USE_SYSTEM = "system" 215 | USE_USER = "user" 216 | USE_SCRATCH = "scratch" 217 | 218 | def __init__(self, node=None): 219 | self.id = None 220 | self.file = None 221 | self.format = None 222 | self.size = None 223 | self.use = None 224 | self.csum = {} 225 | if not node is None: 226 | self.parseXML(node) 227 | 228 | def parseXML(self, node): 229 | self.file = xpathString(node, "@file") 230 | self.id = xpathString(node, "@id", self.file) 231 | self.format = xpathString(node, "@format", Disk.FORMAT_RAW) 232 | self.size = xpathString(node, "@size") 233 | self.use = xpathString(node, "@use", Disk.USE_SYSTEM) 234 | 235 | for d in node.xpathEval("checksum"): 236 | csumtype = xpathString(d, "@type") 237 | csumvalue = xpathString(d, "") 238 | self.csum[csumtype] = csumvalue 239 | formats = [Disk.FORMAT_RAW, 240 | Disk.FORMAT_QCOW, 241 | Disk.FORMAT_QCOW2, 242 | Disk.FORMAT_VMDK, 243 | Disk.FORMAT_ISO, 244 | Disk.FORMAT_VDI] 245 | validate(formats.count(self.format) > 0, 246 | _("The format for disk %s must be one of %s") % 247 | (self.file, ",".join(formats))) 248 | 249 | def check_disk_signature(self, meter=None): 250 | try: 251 | import hashlib 252 | sha = None 253 | except: 254 | import sha 255 | hashlib = None 256 | 257 | if meter is None: 258 | meter = urlgrabber.progress.BaseMeter() 259 | 260 | m = None 261 | if hashlib: 262 | if "sha256" in self.csum: 263 | csumvalue = self.csum["sha256"] 264 | m = hashlib.sha256() 265 | 266 | elif "sha1" in self.csum: 267 | csumvalue = self.csum["sha1"] 268 | m = hashlib.sha1() 269 | else: 270 | if "sha1" in self.csum: 271 | csumvalue = self.csum["sha1"] 272 | m = sha.new() 273 | 274 | if not m: 275 | return 276 | 277 | meter_ct = 0 278 | disk_size = os.path.getsize(self.file) 279 | meter.start(size=disk_size, 280 | text=_("Checking disk signature for %s" % self.file)) 281 | 282 | f = file(self.file) 283 | while 1: 284 | chunk = f.read(65536) 285 | if not chunk: 286 | break 287 | meter.update(meter_ct) 288 | meter_ct = meter_ct + 65536 289 | m.update(chunk) 290 | checksum = m.hexdigest() 291 | if checksum != csumvalue: 292 | logging.debug(_("Disk signature for %s does not match " 293 | "Expected: %s Received: %s" % (self.file, 294 | csumvalue, checksum))) 295 | raise ValueError(_("Disk signature for %s does not " 296 | "match" % self.file)) 297 | 298 | 299 | def validate(cond, msg): 300 | if not cond: 301 | raise ParserException(msg) 302 | 303 | 304 | def xpathString(node, path, default=None): 305 | result = node.xpathEval("string(%s)" % path) 306 | if len(result) == 0: 307 | result = default 308 | return result 309 | 310 | 311 | def parse(xml, filename): 312 | """Parse the XML description of a VM image into a data structure. Returns 313 | an object of class Image. BASE should be the directory where the disk 314 | image files for this image can be found""" 315 | 316 | class ErrorHandler: 317 | def __init__(self): 318 | self.msg = "" 319 | def handler(self, ignore, s): 320 | self.msg += s 321 | error = ErrorHandler() 322 | libxml2.registerErrorHandler(error.handler, None) 323 | 324 | try: 325 | try: 326 | doc = libxml2.readMemory(xml, len(xml), 327 | None, None, 328 | libxml2.XML_PARSE_NOBLANKS) 329 | except (libxml2.parserError, libxml2.treeError), e: 330 | raise ParserException("%s\n%s" % (e, error.msg)) 331 | finally: 332 | libxml2.registerErrorHandler(None, None) 333 | 334 | try: 335 | root = doc.getRootElement() 336 | if root.name != "image": 337 | raise ParserException(_("Root element is not 'image'")) 338 | 339 | image = Image(root, filename=filename) 340 | finally: 341 | doc.freeDoc() 342 | 343 | return image 344 | 345 | 346 | def parse_file(filename): 347 | f = open(filename, "r") 348 | xml = f.read() 349 | f.close() 350 | return parse(xml, filename=filename) 351 | -------------------------------------------------------------------------------- /virtmod/virtinst/ImportInstaller.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009 Red Hat, Inc. 3 | # Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst import Installer 21 | from virtinst.VirtualDisk import VirtualDisk 22 | 23 | 24 | class ImportInstaller(Installer.Installer): 25 | """ 26 | Create a Guest around an existing disk device, and perform no 'install' 27 | stage. 28 | 29 | ImportInstaller sets the Guest's boot device to that of the first disk 30 | attached to the Guest (so, one of 'hd', 'cdrom', or 'fd'). All the 31 | user has to do is fill in the Guest object with the desired parameters. 32 | """ 33 | _has_install_phase = False 34 | 35 | # General Installer methods 36 | def prepare(self, guest, meter): 37 | pass 38 | 39 | # Private methods 40 | def _get_bootdev(self, isinstall, guest): 41 | disks = guest.get_devices("disk") 42 | if not disks: 43 | return self.bootconfig.BOOT_DEVICE_HARDDISK 44 | return self._disk_to_bootdev(disks[0]) 45 | 46 | def _disk_to_bootdev(self, disk): 47 | if disk.device == VirtualDisk.DEVICE_DISK: 48 | return self.bootconfig.BOOT_DEVICE_HARDDISK 49 | elif disk.device == VirtualDisk.DEVICE_CDROM: 50 | return self.bootconfig.BOOT_DEVICE_CDROM 51 | elif disk.device == VirtualDisk.DEVICE_FLOPPY: 52 | return self.bootconfig.BOOT_DEVICE_FLOPPY 53 | else: 54 | return self.bootconfig.BOOT_DEVICE_HARDDISK 55 | -------------------------------------------------------------------------------- /virtmod/virtinst/LiveCDInstaller.py: -------------------------------------------------------------------------------- 1 | # 2 | # An installer class for LiveCD images 3 | # 4 | # Copyright 2007 Red Hat, Inc. 5 | # Mark McLoughlin 6 | # 7 | # This program is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 20 | # MA 02110-1301 USA. 21 | 22 | from virtinst import Installer 23 | from virtinst.VirtualDisk import VirtualDisk 24 | 25 | 26 | class LiveCDInstallerException(Exception): 27 | def __init__(self, msg): 28 | Exception.__init__(self, msg) 29 | 30 | 31 | class LiveCDInstaller(Installer.Installer): 32 | _has_install_phase = False 33 | 34 | # LiveCD specific methods/overwrites 35 | def _validate_location(self, val): 36 | path = None 37 | vol_tuple = None 38 | if type(val) is tuple: 39 | vol_tuple = val 40 | else: 41 | path = val 42 | 43 | disk = None 44 | if path or vol_tuple: 45 | disk = VirtualDisk(path=path, 46 | conn=self.conn, 47 | volName=vol_tuple, 48 | device=VirtualDisk.DEVICE_CDROM, 49 | readOnly=True) 50 | return disk 51 | def _get_location(self): 52 | return self._location 53 | def _set_location(self, val): 54 | self._validate_location(val) 55 | self._location = val 56 | self.cdrom = True 57 | location = property(_get_location, _set_location) 58 | 59 | 60 | # General Installer methods 61 | def prepare(self, guest, meter): 62 | self.cleanup() 63 | 64 | disk = self._validate_location(self.location) 65 | 66 | if not disk: 67 | raise ValueError(_("CDROM media must be specified for the live " 68 | "CD installer.")) 69 | 70 | self.install_devices.append(disk) 71 | 72 | # Internal methods 73 | def _get_bootdev(self, isinstall, guest): 74 | return self.bootconfig.BOOT_DEVICE_CDROM 75 | -------------------------------------------------------------------------------- /virtmod/virtinst/PXEInstaller.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2006-2009 Red Hat, Inc. 3 | # Daniel P. Berrange 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst import Installer 21 | 22 | 23 | class PXEInstaller(Installer.Installer): 24 | 25 | # General Installer methods 26 | def prepare(self, guest, meter): 27 | pass 28 | 29 | # Internal methods 30 | def _get_bootdev(self, isinstall, guest): 31 | bootdev = self.bootconfig.BOOT_DEVICE_NETWORK 32 | 33 | if (not isinstall and 34 | [d for d in guest.get_devices("disk") if 35 | d.device == d.DEVICE_DISK]): 36 | # If doing post-install boot and guest has an HD attached 37 | bootdev = self.bootconfig.BOOT_DEVICE_HARDDISK 38 | 39 | return bootdev 40 | -------------------------------------------------------------------------------- /virtmod/virtinst/Seclabel.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010, 2012 Red Hat, Inc. 3 | # Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst import XMLBuilderDomain 21 | from virtinst.XMLBuilderDomain import _xml_property 22 | 23 | 24 | class Seclabel(XMLBuilderDomain.XMLBuilderDomain): 25 | """ 26 | Class for generating XML 27 | """ 28 | 29 | SECLABEL_TYPE_DYNAMIC = "dynamic" 30 | SECLABEL_TYPE_STATIC = "static" 31 | SECLABEL_TYPE_DEFAULT = "default" 32 | SECLABEL_TYPES = [SECLABEL_TYPE_DYNAMIC, SECLABEL_TYPE_STATIC] 33 | 34 | MODEL_DEFAULT = "default" 35 | 36 | SECLABEL_MODEL_TEST = "testSecurity" 37 | SECLABEL_MODEL_SELINUX = "selinux" 38 | SECLABEL_MODEL_DAC = "dac" 39 | SECLABEL_MODEL_NONE = "none" 40 | SECLABEL_MODELS = [SECLABEL_MODEL_SELINUX, 41 | SECLABEL_MODEL_DAC, 42 | SECLABEL_MODEL_NONE] 43 | 44 | _dumpxml_xpath = "/domain/seclabel" 45 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 46 | XMLBuilderDomain.XMLBuilderDomain.__init__(self, conn, parsexml, 47 | parsexmlnode, caps) 48 | 49 | self._type = None 50 | self._model = None 51 | self._label = None 52 | self._imagelabel = None 53 | self._relabel = None 54 | 55 | if self._is_parse(): 56 | return 57 | 58 | self.model = self.MODEL_DEFAULT 59 | self.type = self.SECLABEL_TYPE_DEFAULT 60 | 61 | def _get_default_model(self): 62 | caps = self._get_caps() 63 | if caps: 64 | if (self.SECLABEL_MODEL_TEST in 65 | [x.model for x in caps.host.secmodels]): 66 | return self.SECLABEL_MODEL_TEST 67 | 68 | for model in self.SECLABEL_MODELS: 69 | if model in [x.model for x in caps.host.secmodels]: 70 | return model 71 | raise RuntimeError("No supported model found in capabilities") 72 | 73 | def _guess_secmodel(self, label, imagelabel): 74 | # We always want the testSecurity model when running tests 75 | caps = self._get_caps() 76 | if (caps and 77 | self.SECLABEL_MODEL_TEST in 78 | [x.model for x in caps.host.secmodels]): 79 | return self.SECLABEL_MODEL_TEST 80 | 81 | if not label and not imagelabel: 82 | return self._get_default_model() 83 | 84 | lab_len = imglab_len = None 85 | if label: 86 | lab_len = min(3, len(label.split(':'))) 87 | if imagelabel: 88 | imglab_len = min(3, len(imagelabel.split(':'))) 89 | if lab_len and imglab_len and lab_len != imglab_len: 90 | raise ValueError("Label and Imagelabel are incompatible") 91 | 92 | lab_len = lab_len or imglab_len 93 | if lab_len == 3: 94 | return self.SECLABEL_MODEL_SELINUX 95 | elif lab_len == 2: 96 | return self.SECLABEL_MODEL_DAC 97 | else: 98 | raise ValueError("Unknown model type for label '%s'" % self.label) 99 | 100 | def get_type(self): 101 | return self._type 102 | def set_type(self, val): 103 | if (val not in self.SECLABEL_TYPES and 104 | val != self.SECLABEL_TYPE_DEFAULT): 105 | raise ValueError("Unknown security type '%s'" % val) 106 | self._type = val 107 | type = _xml_property(get_type, set_type, 108 | xpath="./seclabel/@type") 109 | 110 | def get_model(self): 111 | return self._model 112 | def set_model(self, val): 113 | self._model = val 114 | model = _xml_property(get_model, set_model, 115 | xpath="./seclabel/@model", 116 | default_converter=_get_default_model) 117 | 118 | def get_label(self): 119 | return self._label 120 | def set_label(self, val): 121 | self._label = val 122 | label = _xml_property(get_label, set_label, 123 | xpath="./seclabel/label") 124 | 125 | def _get_relabel(self): 126 | return self._relabel 127 | def _set_relabel(self, val): 128 | self._relabel = val 129 | relabel = _xml_property(_get_relabel, _set_relabel, 130 | xpath="./seclabel/@relabel") 131 | 132 | def get_imagelabel(self): 133 | return self._imagelabel 134 | def set_imagelabel(self, val): 135 | self._imagelabel = val 136 | imagelabel = _xml_property(get_imagelabel, set_imagelabel, 137 | xpath="./seclabel/imagelabel") 138 | 139 | def _get_xml_config(self): 140 | if (self.model == self.MODEL_DEFAULT and 141 | self.type == self.SECLABEL_TYPE_DEFAULT): 142 | return "" 143 | 144 | model = self.model 145 | typ = self.type 146 | relabel = self.relabel 147 | 148 | if typ == self.SECLABEL_TYPE_DEFAULT: 149 | typ = self.SECLABEL_TYPE_DYNAMIC 150 | 151 | if not typ: 152 | raise RuntimeError("Security type and model must be specified") 153 | 154 | if typ == self.SECLABEL_TYPE_STATIC: 155 | if not self.label: 156 | raise RuntimeError("A label must be specified for static " 157 | "security type.") 158 | 159 | if model == self.MODEL_DEFAULT: 160 | model = self._guess_secmodel(self.label, self.imagelabel) 161 | 162 | label_xml = "" 163 | xml = " 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst.VirtualDevice import VirtualDevice 21 | from virtinst.XMLBuilderDomain import _xml_property 22 | 23 | 24 | class VirtualAudio(VirtualDevice): 25 | 26 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_AUDIO 27 | 28 | MODEL_DEFAULT = "default" 29 | MODELS = ["es1370", "sb16", "pcspk", "ac97", "ich6", MODEL_DEFAULT] 30 | 31 | def __init__(self, model=None, conn=None, 32 | parsexml=None, parsexmlnode=None, caps=None): 33 | VirtualDevice.__init__(self, conn, 34 | parsexml, parsexmlnode, caps) 35 | 36 | self._model = None 37 | if self._is_parse(): 38 | return 39 | 40 | if model is None: 41 | model = self.MODEL_DEFAULT 42 | self.model = model 43 | 44 | def get_model(self): 45 | return self._model 46 | def set_model(self, new_model): 47 | if type(new_model) != str: 48 | raise ValueError(_("'model' must be a string, " 49 | " was '%s'." % type(new_model))) 50 | if not self.MODELS.count(new_model): 51 | raise ValueError(_("Unsupported sound model '%s'" % new_model)) 52 | self._model = new_model 53 | model = _xml_property(get_model, set_model, 54 | xpath="./@model") 55 | 56 | def _get_xml_config(self): 57 | model = self.model 58 | if model == self.MODEL_DEFAULT: 59 | model = "es1370" 60 | 61 | return " " % model 62 | -------------------------------------------------------------------------------- /virtmod/virtinst/VirtualController.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Red Hat, Inc. 3 | # Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst.VirtualDevice import VirtualDevice 21 | from virtinst.XMLBuilderDomain import XMLBuilderDomain, _xml_property 22 | import logging 23 | 24 | 25 | class VirtualController(VirtualDevice): 26 | 27 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_CONTROLLER 28 | 29 | CONTROLLER_TYPE_IDE = "ide" 30 | CONTROLLER_TYPE_FDC = "fdc" 31 | CONTROLLER_TYPE_SCSI = "scsi" 32 | CONTROLLER_TYPE_SATA = "sata" 33 | CONTROLLER_TYPE_VIRTIOSERIAL = "virtio-serial" 34 | CONTROLLER_TYPE_USB = "usb" 35 | CONTROLLER_TYPE_PCI = "pci" 36 | CONTROLLER_TYPE_CCID = "ccid" 37 | CONTROLLER_TYPES = [CONTROLLER_TYPE_IDE, CONTROLLER_TYPE_FDC, 38 | CONTROLLER_TYPE_SCSI, CONTROLLER_TYPE_SATA, 39 | CONTROLLER_TYPE_VIRTIOSERIAL, CONTROLLER_TYPE_USB, 40 | CONTROLLER_TYPE_PCI, CONTROLLER_TYPE_CCID] 41 | 42 | @staticmethod 43 | def pretty_type(ctype): 44 | pretty_mappings = { 45 | VirtualController.CONTROLLER_TYPE_IDE : "IDE", 46 | VirtualController.CONTROLLER_TYPE_FDC : "Floppy", 47 | VirtualController.CONTROLLER_TYPE_SCSI : "SCSI", 48 | VirtualController.CONTROLLER_TYPE_SATA : "SATA", 49 | VirtualController.CONTROLLER_TYPE_VIRTIOSERIAL : "Virtio Serial", 50 | VirtualController.CONTROLLER_TYPE_USB : "USB", 51 | VirtualController.CONTROLLER_TYPE_PCI : "PCI", 52 | VirtualController.CONTROLLER_TYPE_CCID : "CCID", 53 | } 54 | 55 | if ctype not in pretty_mappings: 56 | return ctype 57 | return pretty_mappings[ctype] 58 | 59 | @staticmethod 60 | def get_class_for_type(ctype): 61 | if ctype not in VirtualController.CONTROLLER_TYPES: 62 | raise ValueError("Unknown controller type '%s'" % ctype) 63 | 64 | if ctype == VirtualController.CONTROLLER_TYPE_IDE: 65 | return VirtualControllerIDE 66 | elif ctype == VirtualController.CONTROLLER_TYPE_FDC: 67 | return VirtualControllerFDC 68 | elif ctype == VirtualController.CONTROLLER_TYPE_SCSI: 69 | return VirtualControllerSCSI 70 | elif ctype == VirtualController.CONTROLLER_TYPE_SATA: 71 | return VirtualControllerSATA 72 | elif ctype == VirtualController.CONTROLLER_TYPE_VIRTIOSERIAL: 73 | return VirtualControllerVirtioSerial 74 | elif ctype == VirtualController.CONTROLLER_TYPE_USB: 75 | return VirtualControllerUSB 76 | 77 | _controller_type = None 78 | 79 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None, 80 | model=None): 81 | VirtualDevice.__init__(self, conn, 82 | parsexml, parsexmlnode, caps) 83 | 84 | self._index = 0 85 | self._ports = None 86 | self._vectors = None 87 | self._model = None 88 | self._master = VirtualDeviceMaster(conn, 89 | parsexml=parsexml, 90 | parsexmlnode=parsexmlnode, 91 | caps=caps) 92 | 93 | if self._is_parse(): 94 | return 95 | 96 | self.model = model 97 | 98 | def get_type(self): 99 | return self._controller_type 100 | type = _xml_property(get_type, 101 | xpath="./@type") 102 | 103 | def get_model(self): 104 | return self._model 105 | def set_model(self, model): 106 | self._model = model 107 | model = _xml_property(get_model, set_model, 108 | xpath="./@model") 109 | 110 | def get_index(self): 111 | return self._index 112 | def set_index(self, val): 113 | self._index = int(val) 114 | index = _xml_property(get_index, set_index, 115 | xpath="./@index") 116 | 117 | def get_vectors(self): 118 | return self._vectors 119 | def set_vectors(self, val): 120 | self._vectors = val 121 | vectors = _xml_property(get_vectors, set_vectors, 122 | xpath="./@vectors") 123 | 124 | def get_ports(self): 125 | return self._ports 126 | def set_ports(self, val): 127 | self._ports = val 128 | ports = _xml_property(get_ports, set_ports, 129 | xpath="./@ports") 130 | 131 | def set_master(self, masterstr): 132 | self._master.parse_friendly_master(masterstr) 133 | def get_master(self): 134 | return self._master 135 | 136 | def _extra_config(self): 137 | return "" 138 | 139 | def _get_xml_config(self): 140 | extra = self._extra_config() 141 | 142 | xml = " " 150 | xml += ">\n" 151 | xml += childxml 152 | xml += " " 153 | return xml 154 | 155 | 156 | class VirtualControllerIDE(VirtualController): 157 | _controller_type = VirtualController.CONTROLLER_TYPE_IDE 158 | 159 | 160 | class VirtualControllerFDC(VirtualController): 161 | _controller_type = VirtualController.CONTROLLER_TYPE_FDC 162 | 163 | 164 | class VirtualControllerSCSI(VirtualController): 165 | _controller_type = VirtualController.CONTROLLER_TYPE_SCSI 166 | 167 | 168 | class VirtualControllerSATA(VirtualController): 169 | _controller_type = VirtualController.CONTROLLER_TYPE_SATA 170 | 171 | 172 | class VirtualControllerVirtioSerial(VirtualController): 173 | _controller_type = VirtualController.CONTROLLER_TYPE_VIRTIOSERIAL 174 | 175 | def _extra_config(self): 176 | xml = "" 177 | if self.ports is not None: 178 | xml += " ports='%s'" % self.ports 179 | if self.vectors is not None: 180 | xml += " vectors='%s'" % self.vectors 181 | 182 | return xml 183 | 184 | 185 | class VirtualControllerUSB(VirtualController): 186 | _controller_type = VirtualController.CONTROLLER_TYPE_USB 187 | 188 | 189 | class VirtualDeviceMaster(XMLBuilderDomain): 190 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 191 | XMLBuilderDomain.__init__(self, conn, parsexml, parsexmlnode, 192 | caps=caps) 193 | 194 | self._startport = None 195 | 196 | def parse_friendly_master(self, masterstr): 197 | try: 198 | int(masterstr) 199 | self._startport = masterstr 200 | except: 201 | logging.exception("Error parsing device master.") 202 | return None 203 | 204 | def _get_startport(self): 205 | return self._startport 206 | def _set_startport(self, val): 207 | self._startport = val 208 | startport = _xml_property(_get_startport, _set_startport, xpath="./master/@startport") 209 | 210 | def _get_xml_config(self): 211 | if self.startport is None: 212 | return 213 | 214 | return "" % self.startport 215 | -------------------------------------------------------------------------------- /virtmod/virtinst/VirtualDevice.py: -------------------------------------------------------------------------------- 1 | # 2 | # Base class for all VM devices 3 | # 4 | # Copyright 2008, 2013 Red Hat, Inc. 5 | # Cole Robinson 6 | # 7 | # This program is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 20 | # MA 02110-1301 USA. 21 | 22 | from virtinst.XMLBuilderDomain import XMLBuilderDomain, _xml_property 23 | import logging 24 | 25 | 26 | class VirtualDevice(XMLBuilderDomain): 27 | """ 28 | Base class for all domain xml device objects. 29 | """ 30 | 31 | VIRTUAL_DEV_DISK = "disk" 32 | VIRTUAL_DEV_NET = "interface" 33 | VIRTUAL_DEV_INPUT = "input" 34 | VIRTUAL_DEV_GRAPHICS = "graphics" 35 | VIRTUAL_DEV_AUDIO = "sound" 36 | VIRTUAL_DEV_HOSTDEV = "hostdev" 37 | VIRTUAL_DEV_SERIAL = "serial" 38 | VIRTUAL_DEV_PARALLEL = "parallel" 39 | VIRTUAL_DEV_CHANNEL = "channel" 40 | VIRTUAL_DEV_CONSOLE = "console" 41 | VIRTUAL_DEV_VIDEO = "video" 42 | VIRTUAL_DEV_CONTROLLER = "controller" 43 | VIRTUAL_DEV_WATCHDOG = "watchdog" 44 | VIRTUAL_DEV_FILESYSTEM = "filesystem" 45 | VIRTUAL_DEV_SMARTCARD = "smartcard" 46 | VIRTUAL_DEV_REDIRDEV = "redirdev" 47 | VIRTUAL_DEV_MEMBALLOON = "memballoon" 48 | VIRTUAL_DEV_RNG = "rng" 49 | 50 | # Ordering in this list is important: it will be the order the 51 | # Guest class outputs XML. So changing this may upset the test suite 52 | virtual_device_types = [VIRTUAL_DEV_DISK, 53 | VIRTUAL_DEV_CONTROLLER, 54 | VIRTUAL_DEV_FILESYSTEM, 55 | VIRTUAL_DEV_NET, 56 | VIRTUAL_DEV_INPUT, 57 | VIRTUAL_DEV_GRAPHICS, 58 | VIRTUAL_DEV_SERIAL, 59 | VIRTUAL_DEV_PARALLEL, 60 | VIRTUAL_DEV_CONSOLE, 61 | VIRTUAL_DEV_CHANNEL, 62 | VIRTUAL_DEV_AUDIO, 63 | VIRTUAL_DEV_VIDEO, 64 | VIRTUAL_DEV_HOSTDEV, 65 | VIRTUAL_DEV_WATCHDOG, 66 | VIRTUAL_DEV_SMARTCARD, 67 | VIRTUAL_DEV_REDIRDEV, 68 | VIRTUAL_DEV_MEMBALLOON, 69 | VIRTUAL_DEV_RNG] 70 | 71 | # General device type (disk, interface, etc.) 72 | _virtual_device_type = None 73 | 74 | def __init__(self, conn=None, parsexml=None, parsexmlnode=None, caps=None): 75 | """ 76 | Initialize device state 77 | 78 | @param conn: libvirt connection to validate device against 79 | @type conn: virConnect 80 | """ 81 | XMLBuilderDomain.__init__(self, conn, parsexml, parsexmlnode, 82 | caps=caps) 83 | 84 | self.alias = VirtualDeviceAlias(conn, 85 | parsexml=parsexml, 86 | parsexmlnode=parsexmlnode, 87 | caps=caps) 88 | self.address = VirtualDeviceAddress(conn, 89 | parsexml=parsexml, 90 | parsexmlnode=parsexmlnode, 91 | caps=caps) 92 | 93 | if not self._virtual_device_type: 94 | raise ValueError(_("Virtual device type must be set in subclass.")) 95 | 96 | if self._virtual_device_type not in self.virtual_device_types: 97 | raise ValueError(_("Unknown virtual device type '%s'.") % 98 | self._virtual_device_type) 99 | 100 | 101 | def get_virtual_device_type(self): 102 | return self._virtual_device_type 103 | virtual_device_type = property(get_virtual_device_type) 104 | 105 | def _get_xml_config(self): 106 | # See XMLBuilderDomain for docs 107 | raise NotImplementedError() 108 | 109 | def setup_dev(self, conn=None, meter=None): 110 | """ 111 | Perform potentially hazardous device initialization, like 112 | storage creation or host device reset 113 | 114 | @param conn: Optional connection to use if neccessary. If not 115 | specified, device's 'conn' will be used 116 | @param meter: Optional progress meter to use 117 | """ 118 | # Will be overwritten by subclasses if necessary. 119 | ignore = conn 120 | ignore = meter 121 | return 122 | 123 | def set_address(self, addrstr): 124 | self.address = VirtualDeviceAddress(self.conn, addrstr=addrstr) 125 | 126 | 127 | class VirtualDeviceAlias(XMLBuilderDomain): 128 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 129 | XMLBuilderDomain.__init__(self, conn, parsexml, parsexmlnode, 130 | caps=caps) 131 | 132 | self._name = None 133 | 134 | 135 | def _get_name(self): 136 | return self._name 137 | def _set_name(self, val): 138 | self._name = val 139 | name = _xml_property(_get_name, _set_name, xpath="./alias/@name") 140 | 141 | def _get_xml_config(self): 142 | return "" 143 | 144 | 145 | class VirtualDeviceAddress(XMLBuilderDomain): 146 | 147 | ADDRESS_TYPE_PCI = "pci" 148 | ADDRESS_TYPE_DRIVE = "drive" 149 | ADDRESS_TYPE_VIRTIO_SERIAL = "virtio-serial" 150 | ADDRESS_TYPE_CCID = "ccid" 151 | ADDRESS_TYPE_SPAPR_VIO = "spapr-vio" 152 | 153 | TYPES = [ADDRESS_TYPE_PCI, ADDRESS_TYPE_DRIVE, 154 | ADDRESS_TYPE_VIRTIO_SERIAL, ADDRESS_TYPE_CCID, 155 | ADDRESS_TYPE_SPAPR_VIO] 156 | 157 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None, 158 | addrstr=None): 159 | XMLBuilderDomain.__init__(self, conn, parsexml, parsexmlnode, 160 | caps=caps) 161 | 162 | self._type = None 163 | 164 | # PCI address: 165 | #
167 | self._bus = None 168 | self._domain = None 169 | self._slot = None 170 | self._function = None 171 | 172 | self._multifunction = None 173 | 174 | # Drive address: 175 | #
176 | self._controller = None 177 | self._target = None 178 | self._unit = None 179 | 180 | # VirtioSerial address: 181 | #
182 | self._port = None 183 | 184 | # CCID address: 185 | #
186 | 187 | if addrstr: 188 | self.parse_friendly_address(addrstr) 189 | 190 | def parse_friendly_address(self, addrstr): 191 | try: 192 | if addrstr.count(":") in [1, 2] and addrstr.count("."): 193 | self.type = self.ADDRESS_TYPE_PCI 194 | addrstr, self.function = addrstr.split(".", 1) 195 | addrstr, self.slot = addrstr.rsplit(":", 1) 196 | self.domain = "0" 197 | if addrstr.count(":"): 198 | self.domain, self.bus = addrstr.split(":", 1) 199 | elif addrstr == "spapr-vio": 200 | self.type = self.ADDRESS_TYPE_SPAPR_VIO 201 | else: 202 | raise ValueError(_("Could not determine or unsupported format of '%s'") % addrstr) 203 | except: 204 | logging.exception("Error parsing address.") 205 | return None 206 | 207 | 208 | def clear(self): 209 | self._type = None 210 | self._bus = None 211 | self._domain = None 212 | self._slot = None 213 | self._function = None 214 | self._controller = None 215 | self._target = None 216 | self._unit = None 217 | self._port = None 218 | self._multifunction = None 219 | 220 | if self._is_parse(): 221 | self._remove_child_xpath("./address") 222 | 223 | def _get_type(self): 224 | return self._type 225 | def _set_type(self, val): 226 | self._type = val 227 | type = _xml_property(_get_type, _set_type, xpath="./address/@type") 228 | 229 | def _get_domain(self): 230 | return self._domain 231 | def _set_domain(self, val): 232 | self._domain = val 233 | domain = _xml_property(_get_domain, _set_domain, xpath="./address/@domain") 234 | 235 | def _get_bus(self): 236 | return self._bus 237 | def _set_bus(self, val): 238 | self._bus = val 239 | bus = _xml_property(_get_bus, _set_bus, xpath="./address/@bus") 240 | 241 | def _get_slot(self): 242 | return self._slot 243 | def _set_slot(self, val): 244 | self._slot = val 245 | slot = _xml_property(_get_slot, _set_slot, xpath="./address/@slot") 246 | 247 | def _get_function(self): 248 | return self._function 249 | def _set_function(self, val): 250 | self._function = val 251 | function = _xml_property(_get_function, _set_function, 252 | xpath="./address/@function") 253 | 254 | def _get_controller(self): 255 | return self._controller 256 | def _set_controller(self, val): 257 | self._controller = val 258 | controller = _xml_property(_get_controller, _set_controller, 259 | xpath="./address/@controller") 260 | 261 | def _get_target(self): 262 | return self._target 263 | def _set_target(self, val): 264 | self._target = val 265 | target = _xml_property(_get_target, _set_target, xpath="./address/@target") 266 | 267 | def _get_unit(self): 268 | return self._unit 269 | def _set_unit(self, val): 270 | self._unit = val 271 | unit = _xml_property(_get_unit, _set_unit, xpath="./address/@unit") 272 | 273 | def _get_port(self): 274 | return self._port 275 | def _set_port(self, val): 276 | self._port = val 277 | port = _xml_property(_get_port, _set_port, xpath="./address/@port") 278 | 279 | def _get_multifunction(self): 280 | return self._multifunction 281 | def _set_multifunction(self, val): 282 | self._multifunction = val 283 | multifunction = _xml_property(_get_multifunction, 284 | _set_multifunction, 285 | xpath="./address/@multifunction") 286 | 287 | def _get_xml_config(self): 288 | if not self.type: 289 | return 290 | 291 | def format_props(*args): 292 | return "".join([" %s='%s'" % (k, getattr(self, k)) for k in args if getattr(self, k, None) is not None]) 293 | 294 | xml = "
4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | import os 21 | 22 | from virtinst.VirtualDevice import VirtualDevice 23 | from virtinst.XMLBuilderDomain import _xml_property 24 | 25 | 26 | class VirtualFilesystem(VirtualDevice): 27 | 28 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_FILESYSTEM 29 | 30 | _target_props = ["dir", "name", "file", "dev"] 31 | 32 | TYPE_MOUNT = "mount" 33 | TYPE_TEMPLATE = "template" 34 | TYPE_FILE = "file" 35 | TYPE_BLOCK = "block" 36 | TYPE_DEFAULT = "default" 37 | TYPES = [TYPE_MOUNT, TYPE_TEMPLATE, TYPE_FILE, TYPE_BLOCK, TYPE_DEFAULT] 38 | 39 | MODE_PASSTHROUGH = "passthrough" 40 | MODE_MAPPED = "mapped" 41 | MODE_SQUASH = "squash" 42 | MODE_DEFAULT = "default" 43 | MOUNT_MODES = [MODE_PASSTHROUGH, MODE_MAPPED, MODE_SQUASH, MODE_DEFAULT] 44 | 45 | WRPOLICY_IMM = "immediate" 46 | WRPOLICY_DEFAULT = "default" 47 | WRPOLICIES = [WRPOLICY_IMM, WRPOLICY_DEFAULT] 48 | 49 | DRIVER_PATH = "path" 50 | DRIVER_HANDLE = "handle" 51 | DRIVER_PROXY = "proxy" 52 | DRIVER_DEFAULT = "default" 53 | DRIVER_TYPES = [DRIVER_PATH, DRIVER_HANDLE, DRIVER_PROXY, DRIVER_DEFAULT] 54 | 55 | @staticmethod 56 | def type_to_source_prop(fs_type): 57 | """ 58 | Convert a value of VirtualFilesystem.type to it's associated XML 59 | source @prop name 60 | """ 61 | if (fs_type == VirtualFilesystem.TYPE_MOUNT or 62 | fs_type == VirtualFilesystem.TYPE_DEFAULT or 63 | fs_type is None): 64 | return "dir" 65 | elif fs_type == VirtualFilesystem.TYPE_TEMPLATE: 66 | return "name" 67 | elif fs_type == VirtualFilesystem.TYPE_FILE: 68 | return "file" 69 | elif fs_type == VirtualFilesystem.TYPE_BLOCK: 70 | return "dev" 71 | return "dir" 72 | 73 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 74 | VirtualDevice.__init__(self, conn, parsexml, 75 | parsexmlnode, caps) 76 | 77 | self._type = None 78 | self._mode = None 79 | self._driver = None 80 | self._target = None 81 | self._source = None 82 | self._readonly = None 83 | self._wrpolicy = None 84 | 85 | if self._is_parse(): 86 | return 87 | 88 | self.mode = self.MODE_DEFAULT 89 | self.type = self.TYPE_DEFAULT 90 | self.driver = self.DRIVER_DEFAULT 91 | self.wrpolicy = self.WRPOLICY_DEFAULT 92 | 93 | def _get_type(self): 94 | return self._type 95 | def _set_type(self, val): 96 | if val is not None and not self.TYPES.count(val): 97 | raise ValueError(_("Unsupported filesystem type '%s'" % val)) 98 | self._type = val 99 | type = _xml_property(_get_type, _set_type, xpath="./@type") 100 | 101 | def _get_mode(self): 102 | return self._mode 103 | def _set_mode(self, val): 104 | if val is not None and not self.MOUNT_MODES.count(val): 105 | raise ValueError(_("Unsupported filesystem mode '%s'" % val)) 106 | self._mode = val 107 | mode = _xml_property(_get_mode, _set_mode, xpath="./@accessmode") 108 | 109 | def _get_wrpolicy(self): 110 | return self._wrpolicy 111 | def _set_wrpolicy(self, val): 112 | if val is not None and not self.WRPOLICIES.count(val): 113 | raise ValueError(_("Unsupported filesystem write policy '%s'" % val)) 114 | self._wrpolicy = val 115 | wrpolicy = _xml_property(_get_wrpolicy, _set_wrpolicy, xpath="./driver/@wrpolicy") 116 | 117 | def _get_readonly(self): 118 | return self._readonly 119 | def _set_readonly(self, val): 120 | self._readonly = val 121 | readonly = _xml_property(_get_readonly, _set_readonly, 122 | xpath="./readonly", is_bool=True) 123 | 124 | def _get_driver(self): 125 | return self._driver 126 | def _set_driver(self, val): 127 | if val is not None and not self.DRIVER_TYPES.count(val): 128 | raise ValueError(_("Unsupported filesystem driver '%s'" % val)) 129 | self._driver = val 130 | driver = _xml_property(_get_driver, _set_driver, xpath="./driver/@type") 131 | 132 | def _get_source(self): 133 | return self._source 134 | def _set_source(self, val): 135 | if self.type != self.TYPE_TEMPLATE: 136 | val = os.path.abspath(val) 137 | self._source = val 138 | def _xml_get_source_xpath(self): 139 | xpath = None 140 | ret = "./source/@dir" 141 | for prop in self._target_props: 142 | xpath = "./source/@" + prop 143 | if self._xml_ctx.xpathEval(xpath): 144 | ret = xpath 145 | 146 | return ret 147 | def _xml_set_source_xpath(self): 148 | ret = "./source/@" + self.type_to_source_prop(self.type) 149 | return ret 150 | source = _xml_property(_get_source, _set_source, 151 | xml_get_xpath=_xml_get_source_xpath, 152 | xml_set_xpath=_xml_set_source_xpath) 153 | 154 | def _get_target(self): 155 | return self._target 156 | def _set_target(self, val): 157 | is_qemu = self.is_qemu() 158 | 159 | # In case of qemu for default fs type (mount) target is not 160 | # actually a directory, it is merely a arbitrary string tag 161 | # that is exported to the guest as a hint for where to mount 162 | if (is_qemu and 163 | (self.type == self.TYPE_DEFAULT or 164 | self.type == self.TYPE_MOUNT)): 165 | pass 166 | elif not os.path.isabs(val): 167 | raise ValueError(_("Filesystem target '%s' must be an absolute " 168 | "path") % val) 169 | self._target = val 170 | target = _xml_property(_get_target, _set_target, xpath="./target/@dir") 171 | 172 | 173 | def _get_xml_config(self): 174 | mode = self.mode 175 | ftype = self.type 176 | driver = self.driver 177 | source = self.source 178 | target = self.target 179 | readonly = self.readonly 180 | wrpolicy = self.wrpolicy 181 | 182 | if mode == self.MODE_DEFAULT: 183 | mode = None 184 | if ftype == self.TYPE_DEFAULT: 185 | ftype = None 186 | if driver == self.DRIVER_DEFAULT: 187 | driver = None 188 | wrpolicy = None 189 | if wrpolicy == self.WRPOLICY_DEFAULT: 190 | wrpolicy = None 191 | 192 | if not source or not target: 193 | raise ValueError( 194 | _("A filesystem source and target must be specified")) 195 | 196 | fsxml = " 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst.VirtualDevice import VirtualDevice 21 | from virtinst import NodeDeviceParser 22 | import logging 23 | 24 | from virtinst.XMLBuilderDomain import _xml_property 25 | 26 | 27 | class VirtualHostDevice(VirtualDevice): 28 | 29 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_HOSTDEV 30 | 31 | def device_from_node(conn, name=None, nodedev=None, is_dup=False): 32 | """ 33 | Convert the passed device name to a VirtualHostDevice 34 | instance, with proper error reporting. Name can be any of the 35 | values accepted by NodeDeviceParser.lookupNodeName. If a node 36 | device name is not specified, a virtinst.NodeDevice instance can 37 | be passed in to create a dev from. 38 | 39 | @param conn: libvirt.virConnect instance to perform the lookup on 40 | @param name: optional libvirt node device name to lookup 41 | @param nodedev: optional L{virtinst.NodeDevice} instance to use 42 | 43 | @rtype: L{virtinst.VirtualHostDevice} instance 44 | """ 45 | 46 | if not name and not nodedev: 47 | raise ValueError(_("'name' or 'nodedev' required.")) 48 | 49 | if nodedev: 50 | nodeinst = nodedev 51 | else: 52 | nodeinst, addr_type = NodeDeviceParser.lookupNodeName(conn, name) 53 | if addr_type == NodeDeviceParser.HOSTDEV_ADDR_TYPE_USB_BUSADDR: 54 | is_dup = True 55 | 56 | if isinstance(nodeinst, NodeDeviceParser.PCIDevice): 57 | return VirtualHostDevicePCI(conn, nodedev=nodeinst) 58 | elif isinstance(nodeinst, NodeDeviceParser.USBDevice): 59 | return VirtualHostDeviceUSB(conn, nodedev=nodeinst, is_dup=is_dup) 60 | elif isinstance(nodeinst, NodeDeviceParser.NetDevice): 61 | parentname = nodeinst.parent 62 | try: 63 | return VirtualHostDevice.device_from_node(conn, 64 | name=parentname) 65 | except: 66 | logging.exception("Fetching net parent device failed.") 67 | 68 | raise ValueError(_("Node device type '%s' cannot be attached to " 69 | " guest.") % nodeinst.device_type) 70 | 71 | device_from_node = staticmethod(device_from_node) 72 | 73 | def __init__(self, conn, nodedev=None, 74 | parsexml=None, parsexmlnode=None, caps=None): 75 | """ 76 | @param conn: Connection the device/guest will be installed on 77 | @type conn: libvirt.virConnect 78 | @param nodedev: Optional NodeDevice instance for device being 79 | attached to the guest 80 | @type nodedev: L{virtinst.NodeDeviceParser.NodeDevice} 81 | """ 82 | VirtualDevice.__init__(self, conn, parsexml, 83 | parsexmlnode, caps) 84 | 85 | self._mode = None 86 | self._type = None 87 | self._managed = None 88 | self._nodedev = nodedev 89 | self._vendor = None 90 | self._product = None 91 | self._bus = None 92 | self._device = None 93 | self._domain = "0x0" 94 | self._slot = None 95 | self._function = None 96 | 97 | if self._is_parse(): 98 | return 99 | 100 | self.managed = True 101 | if self.is_xen(): 102 | self.managed = False 103 | 104 | 105 | def get_mode(self): 106 | return self._mode 107 | def set_mode(self, val): 108 | self._mode = val 109 | mode = _xml_property(get_mode, set_mode, 110 | xpath="./@mode") 111 | 112 | def get_type(self): 113 | return self._type 114 | def set_type(self, val): 115 | self._type = val 116 | type = _xml_property(get_type, set_type, 117 | xpath="./@type") 118 | 119 | def get_managed(self): 120 | return self._managed 121 | def set_managed(self, val): 122 | self._managed = bool(val) 123 | managed = _xml_property(get_managed, set_managed, 124 | get_converter=lambda s, x: bool(x == "yes"), 125 | set_converter=lambda s, x: x and "yes" or "no", 126 | xpath="./@managed") 127 | 128 | def get_vendor(self): 129 | return self._vendor 130 | def set_vendor(self, val): 131 | self._vendor = val 132 | vendor = _xml_property(get_vendor, set_vendor, 133 | xpath="./source/vendor/@id") 134 | 135 | def get_product(self): 136 | return self._product 137 | def set_product(self, val): 138 | self._product = val 139 | product = _xml_property(get_product, set_product, 140 | xpath="./source/product/@id") 141 | 142 | def get_device(self): 143 | return self._device 144 | def set_device(self, val): 145 | self._device = val 146 | device = _xml_property(get_device, set_device, 147 | xpath="./source/address/@device") 148 | 149 | def get_bus(self): 150 | return self._bus 151 | def set_bus(self, val): 152 | self._bus = val 153 | bus = _xml_property(get_bus, set_bus, 154 | xpath="./source/address/@bus") 155 | 156 | def get_function(self): 157 | return self._function 158 | def set_function(self, val): 159 | self._function = val 160 | function = _xml_property(get_function, set_function, 161 | xpath="./source/address/@function") 162 | 163 | def get_domain(self): 164 | return self._domain 165 | def set_domain(self, val): 166 | self._domain = val 167 | domain = _xml_property(get_domain, set_domain, 168 | xpath="./source/address/@domain") 169 | 170 | def get_slot(self): 171 | return self._slot 172 | def set_slot(self, val): 173 | self._slot = val 174 | slot = _xml_property(get_slot, set_slot, 175 | xpath="./source/address/@slot") 176 | 177 | def _get_source_xml(self): 178 | raise NotImplementedError("Must be implemented in subclass") 179 | 180 | def setup(self, conn=None): 181 | """ 182 | Unused 183 | 184 | @param conn: libvirt virConnect instance to use (defaults to devices 185 | connection) 186 | """ 187 | ignore = conn 188 | 189 | def _get_xml_config(self): 190 | xml = (" \n" % 191 | (self.mode, self.type, self.managed and "yes" or "no")) 192 | xml += " \n" 193 | xml += self._get_source_xml() 194 | xml += " \n" 195 | xml += " " 196 | return xml 197 | 198 | 199 | class VirtualHostDeviceUSB(VirtualHostDevice): 200 | 201 | def __init__(self, conn, nodedev=None, is_dup=False): 202 | VirtualHostDevice.__init__(self, conn, nodedev) 203 | 204 | self.mode = "subsystem" 205 | self.type = "usb" 206 | self.is_dup = is_dup 207 | 208 | self._set_from_nodedev(self._nodedev) 209 | 210 | 211 | def _set_from_nodedev(self, nodedev): 212 | if not nodedev: 213 | return 214 | 215 | if not isinstance(nodedev, NodeDeviceParser.USBDevice): 216 | raise ValueError(_("'nodedev' must be a USBDevice instance.")) 217 | 218 | self.vendor = nodedev.vendor_id 219 | self.product = nodedev.product_id 220 | 221 | if self.is_dup: 222 | self.bus = nodedev.bus 223 | self.device = nodedev.device 224 | 225 | def _get_source_xml(self): 226 | xml = "" 227 | found = False 228 | 229 | if self.vendor and self.product: 230 | xml += " \n" % self.vendor 231 | xml += " \n" % self.product 232 | found = True 233 | 234 | if self.bus and self.device: 235 | xml += "
\n" % (self.bus, 236 | self.device) 237 | found = True 238 | 239 | if not found: 240 | raise RuntimeError(_("'vendor' and 'product', or 'bus' and " 241 | " 'device' are required.")) 242 | return xml 243 | 244 | 245 | class VirtualHostDevicePCI(VirtualHostDevice): 246 | 247 | def __init__(self, conn, nodedev=None): 248 | VirtualHostDevice.__init__(self, conn, nodedev) 249 | 250 | self.mode = "subsystem" 251 | self.type = "pci" 252 | 253 | self._set_from_nodedev(self._nodedev) 254 | 255 | 256 | def _set_from_nodedev(self, nodedev): 257 | if not nodedev: 258 | return 259 | 260 | if not isinstance(nodedev, NodeDeviceParser.PCIDevice): 261 | raise ValueError(_("'nodedev' must be a PCIDevice instance.")) 262 | 263 | self.domain = nodedev.domain 264 | self.bus = nodedev.bus 265 | self.slot = nodedev.slot 266 | self.function = nodedev.function 267 | 268 | def _get_source_xml(self): 269 | if not (self.domain and self.bus and self.slot and self.function): 270 | raise RuntimeError(_("'domain', 'bus', 'slot', and 'function' " 271 | "must be specified.")) 272 | 273 | xml = "
\n" 274 | return xml % (self.domain, self.bus, self.slot, self.function) 275 | -------------------------------------------------------------------------------- /virtmod/virtinst/VirtualInputDevice.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009 Red Hat, Inc. 3 | # Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst.VirtualDevice import VirtualDevice 21 | from virtinst.XMLBuilderDomain import _xml_property 22 | 23 | 24 | class VirtualInputDevice(VirtualDevice): 25 | 26 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_INPUT 27 | 28 | INPUT_TYPE_MOUSE = "mouse" 29 | INPUT_TYPE_TABLET = "tablet" 30 | INPUT_TYPE_DEFAULT = "default" 31 | input_types = [INPUT_TYPE_MOUSE, INPUT_TYPE_TABLET, INPUT_TYPE_DEFAULT] 32 | 33 | INPUT_BUS_PS2 = "ps2" 34 | INPUT_BUS_USB = "usb" 35 | INPUT_BUS_XEN = "xen" 36 | INPUT_BUS_DEFAULT = "default" 37 | input_buses = [INPUT_BUS_PS2, INPUT_BUS_USB, INPUT_BUS_XEN, 38 | INPUT_BUS_DEFAULT] 39 | 40 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 41 | VirtualDevice.__init__(self, conn, parsexml, 42 | parsexmlnode, caps) 43 | 44 | self._type = None 45 | self._bus = None 46 | 47 | if self._is_parse(): 48 | return 49 | 50 | self.type = self.INPUT_TYPE_DEFAULT 51 | self.bus = self.INPUT_BUS_DEFAULT 52 | 53 | def _convert_default_bus(self, val): 54 | if val == self.INPUT_BUS_DEFAULT: 55 | return self.INPUT_BUS_XEN 56 | return val 57 | def _convert_default_type(self, val): 58 | if val == self.INPUT_TYPE_DEFAULT: 59 | return self.INPUT_TYPE_MOUSE 60 | return val 61 | 62 | def get_type(self): 63 | return self._type 64 | def set_type(self, val): 65 | if val not in self.input_types: 66 | raise ValueError(_("Unknown input type '%s'.") % val) 67 | self._type = val 68 | type = _xml_property(get_type, set_type, 69 | xpath="./@type") 70 | 71 | def get_bus(self): 72 | return self._bus 73 | def set_bus(self, val): 74 | if val not in self.input_buses: 75 | raise ValueError(_("Unknown input bus '%s'.") % val) 76 | self._bus = val 77 | bus = _xml_property(get_bus, set_bus, 78 | xpath="./@bus") 79 | 80 | def _get_xml_config(self): 81 | typ = self._convert_default_type(self.type) 82 | bus = self._convert_default_bus(self.bus) 83 | 84 | return " " % (typ, bus) 85 | -------------------------------------------------------------------------------- /virtmod/virtinst/VirtualMemballoon.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012 3 | # Eiichi Tsukata 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst.VirtualDevice import VirtualDevice 21 | from virtinst.XMLBuilderDomain import _xml_property 22 | 23 | 24 | class VirtualMemballoon(VirtualDevice): 25 | 26 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_MEMBALLOON 27 | 28 | MODEL_DEFAULT = "virtio" 29 | MODELS = ["xen", "none", MODEL_DEFAULT] 30 | 31 | def __init__(self, conn=None, model=MODEL_DEFAULT, 32 | parsexml=None, parsexmlnode=None, caps=None): 33 | VirtualDevice.__init__(self, conn, parsexml, 34 | parsexmlnode, caps) 35 | 36 | self._model = None 37 | 38 | if self._is_parse(): 39 | return 40 | 41 | self.model = model 42 | 43 | def get_model(self): 44 | return self._model 45 | def set_model(self, new_model): 46 | if type(new_model) != str: 47 | raise ValueError(_("'model' must be a string, " 48 | " was '%s'." % type(new_model))) 49 | if not self.MODELS.count(new_model): 50 | raise ValueError(_("Unsupported memballoon model '%s'" % new_model)) 51 | self._model = new_model 52 | model = _xml_property(get_model, set_model, 53 | xpath="./@model") 54 | 55 | def _get_xml_config(self): 56 | xml = " 5 | # 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | # MA 02110-1301 USA. 20 | 21 | from virtinst.VirtualDevice import VirtualDevice 22 | from virtinst.XMLBuilderDomain import _xml_property 23 | 24 | 25 | class VirtualRNGDevice(VirtualDevice): 26 | 27 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_RNG 28 | 29 | TYPE_RANDOM = "random" 30 | TYPE_EGD = "egd" 31 | TYPES = [TYPE_RANDOM, TYPE_EGD] 32 | 33 | BACKEND_TYPE_UDP = "udp" 34 | BACKEND_TYPE_TCP = "tcp" 35 | BACKEND_TYPES = [BACKEND_TYPE_UDP, BACKEND_TYPE_TCP] 36 | 37 | BACKEND_MODE_BIND = "bind" 38 | BACKEND_MODE_CONNECT = "connect" 39 | BACKEND_MODES = [BACKEND_MODE_BIND, BACKEND_MODE_CONNECT] 40 | 41 | def __init__(self, conn=None, parsexml=None, parsexmlnode=None, caps=None): 42 | VirtualDevice.__init__(self, conn, parsexml, parsexmlnode, caps) 43 | self._type = None 44 | self._model = None 45 | self._backend_type = None 46 | self._bind_host = None 47 | self._bind_service = None 48 | self._connect_host = None 49 | self._connect_service = None 50 | self._rate_bytes = None 51 | self._rate_period = None 52 | 53 | self._device = None 54 | if self._is_parse(): 55 | return 56 | 57 | @staticmethod 58 | def get_pretty_type(rng_type): 59 | if rng_type == VirtualRNGDevice.TYPE_RANDOM: 60 | return _("Random") 61 | if rng_type == VirtualRNGDevice.TYPE_EGD: 62 | return _("Entropy Gathering Daemon") 63 | return rng_type 64 | 65 | @staticmethod 66 | def get_pretty_backend_type(backend_type): 67 | return {"udp" : "UDP", 68 | "tcp": "TCP"}.get(backend_type) or backend_type 69 | 70 | @staticmethod 71 | def get_pretty_mode(mode): 72 | return {"bind" : "Bind", 73 | "connect": "Connect"}.get(mode) or mode 74 | 75 | 76 | def backend_mode(self): 77 | ret = [] 78 | if self.bind_host or self.bind_service: 79 | ret.append(VirtualRNGDevice.BACKEND_MODE_BIND) 80 | if self.connect_host or self.connect_service: 81 | ret.append(VirtualRNGDevice.BACKEND_MODE_CONNECT) 82 | return ret 83 | 84 | def supports_property(self, propname): 85 | """ 86 | Whether the rng dev type supports the passed property name 87 | """ 88 | users = { 89 | "type" : [self.TYPE_EGD, self.TYPE_RANDOM], 90 | 91 | "model" : [self.TYPE_EGD, self.TYPE_RANDOM], 92 | "bind_host" : [self.TYPE_EGD], 93 | "bind_service" : [self.TYPE_EGD], 94 | "connect_host" : [self.TYPE_EGD], 95 | "connect_service" : [self.TYPE_EGD], 96 | "backend_type" : [self.TYPE_EGD], 97 | "device" : [self.TYPE_RANDOM], 98 | "rate_bytes" : [self.TYPE_EGD, self.TYPE_RANDOM], 99 | "rate_period" : [self.TYPE_EGD, self.TYPE_RANDOM], 100 | } 101 | if users.get(propname): 102 | return self.type in users[propname] 103 | 104 | return hasattr(self, propname) 105 | 106 | def _get_type(self): 107 | return self._type 108 | def _set_type(self, m): 109 | self._type = m 110 | type = _xml_property(_get_type, _set_type, xpath="./backend/@model") 111 | 112 | def _get_model(self): 113 | return self._model 114 | def _set_model(self, m): 115 | self._model = m 116 | model = _xml_property(_get_model, _set_model, xpath="./@model") 117 | 118 | def _get_backend_type(self): 119 | return self._backend_type 120 | def _set_backend_type(self, t): 121 | self._backend_type = t 122 | backend_type = _xml_property(_get_backend_type, 123 | _set_backend_type, 124 | xpath="./backend/@type") 125 | 126 | def _get_bind_host(self): 127 | return self._bind_host 128 | def _set_bind_host(self, m): 129 | self._bind_host = m 130 | bind_host = _xml_property(_get_bind_host, 131 | _set_bind_host, 132 | xpath="./backend/source[@mode='bind']/@host") 133 | 134 | def _get_connect_host(self): 135 | return self._connect_host 136 | def _set_connect_host(self, m): 137 | self._connect_host = m 138 | connect_host = _xml_property(_get_connect_host, 139 | _set_connect_host, 140 | xpath="./backend/source[@mode='connect']/@host") 141 | 142 | def _get_bind_service(self): 143 | return self._bind_service 144 | def _set_bind_service(self, m): 145 | self._bind_service = m 146 | bind_service = _xml_property(_get_bind_service, 147 | _set_bind_service, 148 | xpath="./backend/source[@mode='bind']/@service") 149 | def _get_connect_service(self): 150 | return self._connect_service 151 | def _set_connect_service(self, m): 152 | self._connect_service = m 153 | connect_service = _xml_property(_get_connect_service, 154 | _set_connect_service, 155 | xpath="./backend/source[@mode='connect']/@service") 156 | 157 | def _get_rate_bytes(self): 158 | return self._rate_bytes 159 | def _set_rate_bytes(self, b): 160 | self._rate_bytes = b 161 | rate_bytes = _xml_property(_get_rate_bytes, 162 | _set_rate_bytes, 163 | xpath="./rate/@bytes") 164 | 165 | def _get_rate_period(self): 166 | return self._rate_period 167 | def _set_rate_period(self, p): 168 | self._rate_period = p 169 | rate_period = _xml_property(_get_rate_period, 170 | _set_rate_period, 171 | xpath="./rate/@period") 172 | 173 | def _get_device(self): 174 | if self._type == self.TYPE_RANDOM: 175 | return self._device 176 | return None 177 | def _set_device(self, d): 178 | self._device = d 179 | device = _xml_property(_get_device, _set_device, xpath="./backend") 180 | 181 | def _get_xml_config(self): 182 | rng_model = self.model or "virtio" 183 | xml = (" \n" % rng_model) 184 | 185 | if self.rate_bytes or self.rate_period: 186 | xml += " \n" 207 | 208 | if self.bind_host or self.bind_service: 209 | xml += add_source("bind", self.bind_host, self.bind_service) 210 | if self.connect_host or self.connect_service: 211 | xml += add_source("connect", self.connect_host, \ 212 | self.connect_service) 213 | xml += " \n" 214 | 215 | xml += " " 216 | return xml 217 | -------------------------------------------------------------------------------- /virtmod/virtinst/VirtualRedirDevice.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2011 Red Hat, Inc. 4 | # Cole Robinson 5 | # Marc-André Lureau 6 | # 7 | # This program is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 20 | # MA 02110-1301 USA. 21 | 22 | from virtinst.VirtualDevice import VirtualDevice 23 | 24 | from virtinst.XMLBuilderDomain import _xml_property 25 | 26 | 27 | class VirtualRedirDevice(VirtualDevice): 28 | 29 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_REDIRDEV 30 | 31 | BUS_DEFAULT = "usb" 32 | _buses = ["usb"] 33 | 34 | TYPE_DEFAULT = "spicevmc" 35 | _types = ["tcp", "spicevmc", None] 36 | 37 | def __init__(self, bus=BUS_DEFAULT, stype=TYPE_DEFAULT, 38 | conn=None, parsexml=None, parsexmlnode=None, caps=None): 39 | """ 40 | @param conn: Connection the device/guest will be installed on 41 | @type conn: libvirt.virConnect 42 | """ 43 | VirtualDevice.__init__(self, conn, parsexml, 44 | parsexmlnode, caps) 45 | 46 | self._type = None 47 | self._bus = None 48 | self._host = None 49 | self._service = None 50 | if self._is_parse(): 51 | return 52 | 53 | self.bus = bus 54 | self.type = stype 55 | 56 | def get_buses(self): 57 | return self._buses[:] 58 | buses = property(get_buses) 59 | 60 | def get_bus(self): 61 | return self._bus 62 | def set_bus(self, new_val): 63 | if new_val not in self.buses: 64 | raise ValueError(_("Unsupported bus '%s'" % new_val)) 65 | self._bus = new_val 66 | bus = _xml_property(get_bus, set_bus, 67 | xpath="./@bus") 68 | 69 | def get_types(self): 70 | return self._types[:] 71 | types = property(get_types) 72 | 73 | def get_type(self): 74 | return self._type 75 | def set_type(self, new_val): 76 | if new_val not in self.types: 77 | raise ValueError(_("Unsupported redirection type '%s'" % new_val)) 78 | self._type = new_val 79 | type = _xml_property(get_type, set_type, 80 | xpath="./@type") 81 | 82 | def get_host(self): 83 | return self._host 84 | def set_host(self, val): 85 | if len(val) == 0: 86 | raise ValueError(_("Invalid host value")) 87 | self._host = val 88 | host = _xml_property(get_host, set_host, 89 | xpath="./source/@host") 90 | 91 | def get_service(self): 92 | return self._service 93 | def set_service(self, val): 94 | int(val) 95 | self._service = val 96 | service = _xml_property(get_service, set_service, 97 | xpath="./source/@service") 98 | 99 | def parse_friendly_server(self, serverstr): 100 | if serverstr.count(":") == 1: 101 | self.host, self.service = serverstr.split(":") 102 | else: 103 | raise ValueError(_("Could not determine or unsupported format of '%s'") % serverstr) 104 | 105 | def _get_xml_config(self): 106 | xml = (" \n" % 113 | (self.host, self.service)) 114 | xml += " " 115 | return xml 116 | -------------------------------------------------------------------------------- /virtmod/virtinst/VirtualSmartCardDevice.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | # 3 | # Copyright 2011 Red Hat, Inc. 4 | # Cole Robinson 5 | # Marc-André Lureau 6 | # 7 | # This program is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 20 | # MA 02110-1301 USA. 21 | 22 | from virtinst.VirtualDevice import VirtualDevice 23 | from virtinst.XMLBuilderDomain import _xml_property 24 | 25 | 26 | class VirtualSmartCardDevice(VirtualDevice): 27 | 28 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_SMARTCARD 29 | 30 | # Default models list 31 | MODE_DEFAULT = "passthrough" 32 | _modes = ["passthrough", "host-certificates", "host"] 33 | 34 | TYPE_DEFAULT = "tcp" 35 | _types = ["tcp", "spicevmc", None] 36 | 37 | def __init__(self, conn, mode=MODE_DEFAULT, 38 | parsexml=None, parsexmlnode=None, caps=None): 39 | VirtualDevice.__init__(self, conn, 40 | parsexml, parsexmlnode, caps) 41 | 42 | self._mode = None 43 | self._type = None 44 | 45 | if self._is_parse(): 46 | return 47 | 48 | self.mode = mode 49 | 50 | def get_modes(self): 51 | return self._modes[:] 52 | modes = property(get_modes) 53 | 54 | def get_mode(self): 55 | return self._mode 56 | def set_mode(self, val): 57 | if val not in self.modes: 58 | raise ValueError(_("Unknown smartcard mode '%s'") % val) 59 | self._mode = val 60 | mode = _xml_property(get_mode, set_mode, 61 | xpath="./@mode") 62 | 63 | def get_types(self): 64 | return self._types[:] 65 | types = property(get_types) 66 | 67 | def get_type(self): 68 | if self._type is None and self.mode == "passthrough": 69 | return "spicevmc" 70 | return self._type 71 | def set_type(self, val): 72 | if val not in self.types: 73 | raise ValueError(_("Unknown smartcard type '%s'") % val) 74 | self._type = val 75 | type = _xml_property(get_type, set_type, 76 | xpath="./@type") 77 | 78 | def _get_xml_config(self): 79 | mode = self.mode 80 | 81 | xml = " 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst.VirtualDevice import VirtualDevice 21 | from virtinst.XMLBuilderDomain import _xml_property 22 | 23 | 24 | class VirtualVideoDevice(VirtualDevice): 25 | 26 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_VIDEO 27 | 28 | # Default models list 29 | MODEL_DEFAULT = "default" 30 | _model_types = ["cirrus", "vga", "vmvga", "xen", "qxl", MODEL_DEFAULT] 31 | 32 | @staticmethod 33 | def pretty_model(model): 34 | if model in ["qxl", "vmvga"]: 35 | return model.upper() 36 | return model.capitalize() 37 | 38 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 39 | VirtualDevice.__init__(self, conn, 40 | parsexml, parsexmlnode, caps) 41 | 42 | self._model_type = None 43 | self._vram = None 44 | self._heads = None 45 | 46 | if self._is_parse(): 47 | return 48 | 49 | self.model_type = self.MODEL_DEFAULT 50 | 51 | def get_model_types(self): 52 | return self._model_types[:] 53 | model_types = property(get_model_types) 54 | 55 | def get_model_type(self): 56 | return self._model_type 57 | def set_model_type(self, val): 58 | self._model_type = val 59 | model_type = _xml_property(get_model_type, set_model_type, 60 | xpath="./model/@type") 61 | 62 | def get_vram(self): 63 | return self._vram 64 | def set_vram(self, val): 65 | self._vram = val 66 | vram = _xml_property(get_vram, set_vram, 67 | xpath="./model/@vram") 68 | ram = _xml_property(lambda o: None, lambda o, v: None, 69 | xpath="./model/@ram") 70 | 71 | 72 | def get_heads(self): 73 | return self._heads 74 | def set_heads(self, val): 75 | self._heads = val 76 | heads = _xml_property(get_heads, set_heads, 77 | xpath="./model/@heads") 78 | 79 | def _get_xml_config(self): 80 | model = self.model_type 81 | if self.model_type == self.MODEL_DEFAULT: 82 | model = "cirrus" 83 | 84 | model_xml = " \n" + 94 | model_xml + 95 | " ") 96 | return xml 97 | -------------------------------------------------------------------------------- /virtmod/virtinst/VirtualWatchdog.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Red Hat, Inc. 3 | # Cole Robinson 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 | # MA 02110-1301 USA. 19 | 20 | from virtinst.VirtualDevice import VirtualDevice 21 | from virtinst.XMLBuilderDomain import _xml_property 22 | 23 | 24 | class VirtualWatchdog(VirtualDevice): 25 | 26 | _virtual_device_type = VirtualDevice.VIRTUAL_DEV_WATCHDOG 27 | 28 | MODEL_DEFAULT = "default" 29 | MODELS = ["i6300esb", "ib700", MODEL_DEFAULT] 30 | 31 | ACTION_DEFAULT = "default" 32 | ACTION_SHUTDOWN = "shutdown" 33 | ACTION_RESET = "reset" 34 | ACTION_POWEROFF = "poweroff" 35 | ACTION_PAUSE = "pause" 36 | ACTION_NONE = "none" 37 | ACTIONS = [ACTION_RESET, ACTION_SHUTDOWN, 38 | ACTION_POWEROFF, ACTION_PAUSE, 39 | ACTION_NONE, ACTION_DEFAULT] 40 | 41 | @staticmethod 42 | def get_action_desc(action): 43 | if action == VirtualWatchdog.ACTION_RESET: 44 | return _("Forcefully reset the guest") 45 | if action == VirtualWatchdog.ACTION_SHUTDOWN: 46 | return _("Gracefully shutdown the guest") 47 | if action == VirtualWatchdog.ACTION_POWEROFF: 48 | return _("Forcefully power off the guest") 49 | if action == VirtualWatchdog.ACTION_PAUSE: 50 | return _("Pause the guest") 51 | if action == VirtualWatchdog.ACTION_NONE: 52 | return _("No action") 53 | if action == VirtualWatchdog.ACTION_DEFAULT: 54 | return _("Hypervisor default") 55 | else: 56 | return action 57 | 58 | def __init__(self, conn, parsexml=None, parsexmlnode=None, caps=None): 59 | VirtualDevice.__init__(self, conn, parsexml, 60 | parsexmlnode, caps) 61 | 62 | self._model = None 63 | self._action = None 64 | 65 | if self._is_parse(): 66 | return 67 | 68 | self.model = self.MODEL_DEFAULT 69 | self.action = self.ACTION_DEFAULT 70 | 71 | def get_model(self): 72 | return self._model 73 | def set_model(self, new_model): 74 | if type(new_model) != str: 75 | raise ValueError(_("'model' must be a string, " 76 | " was '%s'." % type(new_model))) 77 | if not self.MODELS.count(new_model): 78 | raise ValueError(_("Unsupported watchdog model '%s'" % new_model)) 79 | self._model = new_model 80 | model = _xml_property(get_model, set_model, 81 | xpath="./@model") 82 | 83 | def get_action(self): 84 | return self._action 85 | def set_action(self, val): 86 | if val not in self.ACTIONS: 87 | raise ValueError("Unknown watchdog action '%s'." % val) 88 | self._action = val 89 | action = _xml_property(get_action, set_action, 90 | xpath="./@action") 91 | 92 | def _get_xml_config(self): 93 | model = self.model 94 | if model == self.MODEL_DEFAULT: 95 | model = "i6300esb" 96 | 97 | action = self.action 98 | if action == self.ACTION_DEFAULT: 99 | action = self.ACTION_RESET 100 | 101 | xml = " [a-z-]+)"') 81 | for line in f: 82 | m = keymap_re.match(line) 83 | if m: 84 | kt = m.group('kt') 85 | break 86 | else: 87 | logging.debug("Didn't find keymap in '%s'!", path) 88 | f.close() 89 | return kt 90 | 91 | 92 | def _find_keymap_from_etc_default(): 93 | """ 94 | Look under /etc/default for the host machine's keymap. 95 | 96 | This checks both /etc/default/keyboard and /etc/default/console-setup. 97 | The former is used by Debian 6.0 (Squeeze) and later. The latter is 98 | used by older versions of Debian, and Ubuntu. 99 | """ 100 | 101 | KEYBOARD_DEFAULT = "/etc/default/keyboard" 102 | paths = [KEYBOARD_DEFAULT, CONSOLE_SETUP_CONF] 103 | for path in paths: 104 | kt = find_xkblayout(path) 105 | if kt is not None: 106 | break 107 | return kt 108 | 109 | 110 | def _xorg_keymap(): 111 | """Look in /etc/X11/xorg.conf for the host machine's keymap, and attempt to 112 | map it to a keymap supported by qemu""" 113 | 114 | kt = None 115 | try: 116 | f = open(XORG_CONF, "r") 117 | except IOError, e: 118 | logging.debug('Could not open "%s": %s ', XORG_CONF, str(e)) 119 | else: 120 | keymap_re = re.compile(r'\s*Option\s+"XkbLayout"\s+"(?P[a-z-]+)"') 121 | for line in f: 122 | m = keymap_re.match(line) 123 | if m: 124 | kt = m.group('kt') 125 | break 126 | else: 127 | logging.debug("Didn't find keymap in '%s'!", XORG_CONF) 128 | f.close() 129 | return kt 130 | 131 | 132 | def default_keymap(): 133 | """ 134 | Look in various config files for the host machine's keymap, and attempt 135 | to map it to a keymap supported by qemu 136 | """ 137 | # Set keymap to same as hosts 138 | default = "en-us" 139 | keymap = None 140 | 141 | kt = None 142 | try: 143 | f = open(KEYBOARD_DIR, "r") 144 | except IOError, e: 145 | logging.debug('Could not open "/etc/sysconfig/keyboard" ' + str(e)) 146 | kt = _xorg_keymap() 147 | if not kt: 148 | kt = _find_keymap_from_etc_default() 149 | else: 150 | while 1: 151 | s = f.readline() 152 | if s == "": 153 | break 154 | if re.search("KEYTABLE", s) is not None or \ 155 | (re.search("KEYBOARD", s) is not None and 156 | re.search("KEYBOARDTYPE", s) is None): 157 | if s.count('"'): 158 | delim = '"' 159 | elif s.count('='): 160 | delim = '=' 161 | else: 162 | continue 163 | kt = s.split(delim)[1].strip() 164 | f.close() 165 | 166 | if kt is None: 167 | logging.debug("Did not parse any usable keymapping.") 168 | return default 169 | 170 | kt = kt.lower() 171 | 172 | keymap = sanitize_keymap(kt) 173 | 174 | if not keymap: 175 | logging.debug("Didn't match keymap '%s' in keytable!", kt) 176 | return default 177 | 178 | return keymap 179 | 180 | 181 | def sanitize_keymap(kt): 182 | """ 183 | Make sure the passed keymap roughly matches something in keytable 184 | """ 185 | if kt.lower() in keytable: 186 | return keytable[kt] 187 | 188 | # Try a more intelligent lookup: strip out all '-' and '_', sort 189 | # the keytable keys putting the longest first, then compare 190 | # by string prefix 191 | def len_cmp(a, b): 192 | return len(b) - len(a) 193 | 194 | clean_kt = kt.replace("-", "").replace("_", "") 195 | sorted_keys = sorted(keytable.keys(), len_cmp) 196 | 197 | for key in sorted_keys: 198 | origkey = key 199 | key = key.replace("-", "").replace("_", "") 200 | 201 | if clean_kt.startswith(key): 202 | return keytable[origkey] 203 | 204 | return None 205 | -------------------------------------------------------------------------------- /virtmod/virtinst/uriutil.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2006-2013 Red Hat, Inc. 3 | # 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 2 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | # MA 02110-1301 USA. 18 | # 19 | 20 | import logging 21 | 22 | 23 | def uri_split(uri): 24 | """ 25 | Parse a libvirt hypervisor uri into it's individual parts 26 | @returns: tuple of the form (scheme (ex. 'qemu', 'xen+ssh'), username, 27 | hostname, path (ex. '/system'), query, 28 | fragment) 29 | """ 30 | def splitnetloc(url, start=0): 31 | for c in '/?#': # the order is important! 32 | delim = url.find(c, start) 33 | if delim >= 0: 34 | break 35 | else: 36 | delim = len(url) 37 | return url[start:delim], url[delim:] 38 | 39 | username = netloc = query = fragment = '' 40 | i = uri.find(":") 41 | if i > 0: 42 | scheme, uri = uri[:i].lower(), uri[i + 1:] 43 | if uri[:2] == '//': 44 | netloc, uri = splitnetloc(uri, 2) 45 | offset = netloc.find("@") 46 | if offset > 0: 47 | username = netloc[0:offset] 48 | netloc = netloc[offset + 1:] 49 | if '#' in uri: 50 | uri, fragment = uri.split('#', 1) 51 | if '?' in uri: 52 | uri, query = uri.split('?', 1) 53 | else: 54 | scheme = uri.lower() 55 | return scheme, username, netloc, uri, query, fragment 56 | 57 | 58 | def is_uri_remote(uri, conn=None): 59 | if conn and hasattr(conn, "_virtinst__fake_conn_remote"): 60 | # Testing hack 61 | return True 62 | 63 | try: 64 | split_uri = uri_split(uri) 65 | netloc = split_uri[2] 66 | 67 | if netloc == "": 68 | return False 69 | return True 70 | except Exception, e: 71 | logging.exception("Error parsing URI in is_remote: %s", e) 72 | return True 73 | 74 | 75 | def get_uri_hostname(uri): 76 | try: 77 | split_uri = uri_split(uri) 78 | netloc = split_uri[2] 79 | 80 | if netloc != "": 81 | return netloc 82 | except Exception, e: 83 | logging.warning("Cannot parse URI %s: %s", uri, str(e)) 84 | return "localhost" 85 | 86 | 87 | def get_uri_transport(uri): 88 | try: 89 | split_uri = uri_split(uri) 90 | scheme = split_uri[0] 91 | username = split_uri[1] 92 | 93 | if scheme: 94 | offset = scheme.index("+") 95 | if offset > 0: 96 | return [scheme[offset + 1:], username] 97 | except: 98 | pass 99 | return [None, None] 100 | 101 | 102 | def get_uri_driver(uri): 103 | try: 104 | split_uri = uri_split(uri) 105 | scheme = split_uri[0] 106 | 107 | if scheme: 108 | offset = scheme.find("+") 109 | if offset > 0: 110 | return scheme[:offset] 111 | return scheme 112 | except Exception: 113 | pass 114 | return "xen" 115 | 116 | 117 | def _get_uri_to_split(conn, uri): 118 | if not conn and not uri: 119 | return None 120 | 121 | if type(conn) is str: 122 | uri = conn 123 | elif uri is None: 124 | uri = conn.getURI() 125 | return uri 126 | 127 | 128 | def is_qemu_system(conn, uri=None): 129 | uri = _get_uri_to_split(conn, uri) 130 | if not uri: 131 | return False 132 | 133 | (scheme, ignore, ignore, 134 | path, ignore, ignore) = uri_split(uri) 135 | if path == "/system" and scheme.startswith("qemu"): 136 | return True 137 | return False 138 | 139 | 140 | def is_session_uri(conn, uri=None): 141 | uri = _get_uri_to_split(conn, uri) 142 | if not uri: 143 | return False 144 | 145 | (ignore, ignore, ignore, 146 | path, ignore, ignore) = uri_split(uri) 147 | return bool(path and path == "/session") 148 | 149 | 150 | def is_qemu(conn, uri=None): 151 | uri = _get_uri_to_split(conn, uri) 152 | if not uri: 153 | return False 154 | 155 | scheme = uri_split(uri)[0] 156 | return scheme.startswith("qemu") 157 | 158 | 159 | def is_xen(conn, uri=None): 160 | uri = _get_uri_to_split(conn, uri) 161 | if not uri: 162 | return False 163 | 164 | scheme = uri_split(uri)[0] 165 | return scheme.startswith("xen") 166 | -------------------------------------------------------------------------------- /virtscript/libguestfs-winsupport-1.0-7.el6.x86_64.rpm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoli110/kvm_vm_setup/a1e4b155737bf48b5398f6921816a446ce30f597/virtscript/libguestfs-winsupport-1.0-7.el6.x86_64.rpm -------------------------------------------------------------------------------- /virtscript/libguestfs-winsupport-7.0-2.el7.x86_64.rpm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoli110/kvm_vm_setup/a1e4b155737bf48b5398f6921816a446ce30f597/virtscript/libguestfs-winsupport-7.0-2.el7.x86_64.rpm -------------------------------------------------------------------------------- /virtscript/setipbymac-ubuntu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #version 2012 10 11 3 | #write by yangjunjun 4 | #set hostname and nic ip 5 | #get all if and mac and counter 6 | 7 | #function create network config file 8 | if_one(){ 9 | interface_name=$1 10 | nic1_ip=$2 11 | nic1_netmask=$3 12 | nic1_gateway=$4 13 | interface_file=$5 14 | #interface 1 15 | echo "# The primary network interface">>$interface_file 16 | echo "auto "$interface_name>>$interface_file 17 | echo "iface $interface_name inet static">>$interface_file 18 | echo " address "$nic1_ip>>$interface_file 19 | echo " netmask "$nic1_netmask>>$interface_file 20 | echo " gateway "$nic1_gateway>>$interface_file 21 | echo " dns-nameservers 8.8.8.8">>$interface_file 22 | } 23 | if_two(){ 24 | interface1_name=$1 25 | nic1_ip=$2 26 | nic1_netmask=$3 27 | nic1_gateway=$4 28 | interface_file=$5 29 | interface2_name=$6 30 | nic2_ip=$7 31 | nic2_netmask=$8 32 | 33 | #interface 1 34 | echo "# The primary network interface">>$interface_file 35 | echo "auto "$interface1_name>>$interface_file 36 | echo "iface $interface1_name inet static">>$interface_file 37 | echo " address "$nic1_ip>>$interface_file 38 | echo " netmask "$nic1_netmask>>$interface_file 39 | echo " gateway "$nic1_gateway>>$interface_file 40 | echo " dns-nameservers 8.8.8.8">>$interface_file 41 | 42 | #interface 2 43 | echo "# The secondary network interface">>$interface_file 44 | echo "auto "$interface2_name>>$interface_file 45 | echo "iface ${ifname[1]} inet static">>$interface_file 46 | echo " address "$nic2_ip>>$interface_file 47 | echo " netmask "$nic2_netmask>>$interface_file 48 | 49 | } 50 | 51 | #************************get variable********* 52 | get_host_name=$1 53 | get_gateway=$2 54 | get_nic1_ip=$3 55 | get_nic1_netmask=$4 56 | get_nic1_mac=$5 57 | get_nic2_ip=$6 58 | get_nic2_netmask=$7 59 | get_nic2_mac=$8 60 | #************************get variable********* 61 | 62 | ###################set interface########################## 63 | 64 | #backup interface configure file 65 | nic_name_file="/etc/network/interfaces" 66 | nic_name_file_bak="/etc/network/interfaces.bak" 67 | 68 | if [ -f "$nic_name_file" ];then 69 | echo "nic file exist! backup it" 70 | rm $nic_name_file_bak -f 71 | mv $nic_name_file $nic_name_file_bak 72 | else 73 | echo " nic file not exist create it " 74 | fi 75 | touch $nic_name_file 76 | 77 | #set commem 78 | 79 | echo "# This file describes the network interfaces available on your system 80 | # and how to activate them. For more information, see interfaces(5). 81 | 82 | # The loopback network interface">>$nic_name_file 83 | echo "auto lo">>$nic_name_file 84 | echo "iface lo inet loopback">>$nic_name_file 85 | 86 | 87 | ##############set hostname##################### 88 | echo "host name is "$get_host_name 89 | if [ -z "$get_host_name" ];then 90 | echo "please give host name!" 91 | echo "variable order by hostname gateway nic1 ip nic1 netmask nic1 mac nic2 ip nic2 netmask nic2 mac" 92 | exit 6 93 | else 94 | echo $get_host_name > /etc/hostname 95 | echo "host name set OK!" 96 | fi 97 | ################################################ 98 | 99 | #######################get interface name################### 100 | ifname=(`/sbin/ifconfig -a |grep Link |awk '{print $1}'|grep -vE "lo|inet6|sit0"`) 101 | ifcounter=`/sbin/ifconfig -a |grep Link|grep -vE "lo|inet6|sit0" |wc -l` 102 | echo This VM have $ifcounter interfaces 103 | ########################################################### 104 | 105 | 106 | ######################set network config file ####### 107 | #push if and mac to array 108 | if [ $ifcounter == 1 ];then 109 | echo "This VM have one network" 110 | if_one ${ifname[0]} $get_nic1_ip $get_nic1_netmask $get_gateway $nic_name_file 111 | elif [ $ifcounter == 2 ];then 112 | echo "This VM have two network" 113 | if_two ${ifname[0]} $get_nic1_ip $get_nic1_netmask $get_gateway $nic_name_file ${ifname[1]} $get_nic2_ip $get_nic2_netmask 114 | else 115 | echo "this VM don't have network interface" 116 | exit 0 117 | fi 118 | 119 | 120 | ###############function set nic info############ 121 | /etc/init.d/networking stop 122 | /etc/init.d/networking start 123 | 124 | echo "++++++++++++++++++++++++++++++++++++++++++++++++" 125 | cat $nic_name_file 126 | echo "++++++++++++++++++++++++++++++++++++++++++++++++" 127 | ############################################## 128 | #-----------------disable rc.local----------------------- 129 | sed -i '/^\/bin\/bash\ \/bin\/setipbymac-ubuntu/s/^/#/' /etc/rc.local 130 | sed -i 's/\(127.*\)/\1 "'$get_host_name'" /' /etc/hosts 131 | sed -i 's/"/\ /g' /etc/hosts 132 | reboot 133 | -------------------------------------------------------------------------------- /virtscript/setipbymac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #version 2012 05 18 3 | #version 2015 02 14 add suport for CentOS7 4 | #write by xiaoli 5 | #set hostname and nic ip 6 | #get all if and mac and counter 7 | 8 | ################function set nic info############ 9 | set_nic_ip(){ 10 | nic_name=$1 11 | nic_ip=$2 12 | nic_netmask=$3 13 | nic_name_file="/etc/sysconfig/network-scripts/ifcfg-"$nic_name 14 | nic_name_file_bak="/etc/sysconfig/network-scripts/ifcfg-"$nic_name".bak" 15 | if [ -z "$nic_name" ];then 16 | echo "no nic name give!" 17 | exit 5 18 | else 19 | echo " nic name check ok " 20 | fi 21 | echo "nic_name is" $nic_name 22 | echo "nic_ip is" $nic_ip 23 | echo "nic_netmask is " $nic_netmask 24 | echo "nic file name is " $nic_name_file 25 | if [ -f "$nic_name_file" ];then 26 | echo "nic file exist! backup it" 27 | rm $nic_name_file_bak -f 28 | mv $nic_name_file $nic_name_file_bak 29 | else 30 | echo " nic file not exist create it " 31 | fi 32 | touch $nic_name_file 33 | echo "DEVICE="$nic_name >>$nic_name_file 34 | echo "BOOTPROTO=none" >>$nic_name_file 35 | echo "ONBOOT=yes" >>$nic_name_file 36 | echo "TYPE=Ethernet" >>$nic_name_file 37 | echo "IPADDR="$nic_ip >>$nic_name_file 38 | echo "NETMASK="$nic_netmask >>$nic_name_file 39 | /sbin/ifdown $nic_name 40 | /sbin/ifup $nic_name 41 | echo "++++++++++++++++++++++++++++++++++++++++++++++++" 42 | cat $nic_name_file 43 | echo "++++++++++++++++++++++++++++++++++++++++++++++++" 44 | } 45 | ############################################## 46 | 47 | 48 | #************************get variable********* 49 | mac1=$5 50 | mac2=$8 51 | uname -r |grep el7 52 | if [[ $? -eq 0 ]];then 53 | #typeset -i get_nic1_mac 54 | #get_nic1_mac="${mac1}" 55 | get_nic1_mac=$(echo $mac1 | tr '[A-Z]' '[a-z]') 56 | get_nic2_mac=$(echo $mac2 | tr '[A-Z]' '[a-z]') 57 | else 58 | get_nic1_mac="${mac1}" 59 | get_nic2_mac="${mac2}" 60 | fi 61 | get_host_name=$1 62 | get_gateway=$2 63 | get_nic1_ip=$3 64 | get_nic1_netmask=$4 65 | #get_nic1_mac=$5 66 | get_nic2_ip=$6 67 | get_nic2_netmask=$7 68 | #get_nic2_mac=$8 69 | echo "test" >>/root/setmac.txt 70 | #************************get variable********* 71 | 72 | ##############set hostname##################### 73 | echo "host name is "$get_host_name 74 | if [ -z "$get_host_name" ];then 75 | echo "please give host name!" 76 | echo "variable order by hostname gateway nic1 ip nic1 netmask nic1 mac nic2 ip nic2 netmask nic2 mac" 77 | exit 6 78 | else 79 | sed -i 's/.*HOSTNAME.*/HOSTNAME\="'$get_host_name'"/g' /etc/sysconfig/network 80 | hostnamectl set-hostname $get_host_name 81 | echo "host name set OK!" 82 | fi 83 | ################################################ 84 | 85 | ##############set gateway##################### 86 | echo "gate way is"$get_gateway 87 | if [ -z "$get_gateway" ];then 88 | echo "please give gateway!" 89 | echo "variable order by hostname gateway nic1 ip nic1 netmask nic1 mac nic2 ip nic2 netmask nic2 mac" 90 | exit 7 91 | else 92 | if [ `cat /etc/sysconfig/network |grep GATEWAY |wc -l` -eq 1 ];then 93 | sed -i 's/.*GATEWAY.*/GATEWAY\="'$get_gateway'"/g' /etc/sysconfig/network 94 | else 95 | echo "GATEWAY="$get_gateway >> /etc/sysconfig/network 96 | fi 97 | echo "gate way set OK!" 98 | fi 99 | echo "-----------------------------------------------" 100 | cat /etc/sysconfig/network 101 | echo "-----------------------------------------------" 102 | ################################################ 103 | 104 | temp001=`/sbin/ifconfig -a |grep Link` 105 | 106 | if [[ $? -eq 0 ]];then 107 | allif=`/sbin/ifconfig -a |grep Link |awk '{print $1}'|grep -vE "lo|inet6|sit0"` 108 | allmac=`/sbin/ifconfig -a |grep Link |awk '{print $5}'|grep -vE "lo|inet6|sit0"` 109 | ifcounter=`/sbin/ifconfig -a |grep Link|grep -vE "lo|inet6|sit0" |wc -l` 110 | else 111 | if [[ $? -eq 1 ]];then 112 | allif=`/sbin/ifconfig -a |grep mtu |awk -F : '{print $1}'|grep -vE "lo|inet6|sit0"` 113 | allmac=`/sbin/ifconfig -a |grep ether |awk '{print $2}'|grep -vE "lo|inet6|sit0"` 114 | ifcounter=`/sbin/ifconfig -a |grep mtu|grep -vE "lo|inet6|sit0" |wc -l` 115 | fi 116 | fi 117 | echo "ifname is " $allif 118 | echo "mac add is " $allmac 119 | echo "ifcounter is " $ifcounter 120 | 121 | #push if and mac to array 122 | x=1 123 | while [ $x -le $ifcounter ]; 124 | 125 | do 126 | #STR_TEMP=`printf "%s%s" "$STR_TEMP" "$1"` 127 | ifname[$x]=`echo $allif|awk '{print $'$x'}'` 128 | ifmac[$x]=`echo $allmac|awk '{print $'$x'}'` 129 | echo "x" $x 130 | echo "ifname" ${ifname[$x]} 131 | echo "ifmac" ${ifmac[$x]} 132 | if [ "${ifmac[$x]}" = "$get_nic1_mac" ];then 133 | set_nic_ip ${ifname[$x]} $get_nic1_ip $get_nic2_netmask 134 | else 135 | echo "not nic1" 136 | fi 137 | if [ "${ifmac[$x]}" = "$get_nic2_mac" ];then 138 | set_nic_ip ${ifname[$x]} $get_nic2_ip $get_nic2_netmask 139 | else 140 | echo "not nic2" 141 | fi 142 | x=`expr $x + 1` 143 | done 144 | #b[0]=`echo $a |awk '{print $1}'` 145 | #b[1]=`echo $a |awk '{print $2}'` 146 | #echo ${b[0]} 147 | #echo ${b[1]} 148 | #-----------------disable rc.local----------------------- 149 | sed -i '/^sh\ \/bin\/setipbymac/s/^/#/' /etc/rc.local 150 | sed -i '/^sh\ \/bin\/setipbymac/s/^/#/' /etc/rc.d/rc.local 151 | sed -i 's/\(127.*\)/\1 "'$get_host_name'"/' /etc/hosts 152 | sed -i 's/"/\ /g' /etc/hosts 153 | reboot 154 | -------------------------------------------------------------------------------- /virtscript/setipbymac.sh.bak: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #version 2012 05 18 3 | #write by xiaoli 4 | #set hostname and nic ip 5 | #get all if and mac and counter 6 | 7 | ################function set nic info############ 8 | set_nic_ip(){ 9 | nic_name=$1 10 | nic_ip=$2 11 | nic_netmask=$3 12 | nic_name_file="/etc/sysconfig/network-scripts/ifcfg-"$nic_name 13 | nic_name_file_bak="/etc/sysconfig/network-scripts/ifcfg-"$nic_name".bak" 14 | if [ -z "$nic_name" ];then 15 | echo "no nic name give!" 16 | exit 5 17 | else 18 | echo " nic name check ok " 19 | fi 20 | echo "nic_name is" $nic_name 21 | echo "nic_ip is" $nic_ip 22 | echo "nic_netmask is " $nic_netmask 23 | echo "nic file name is " $nic_name_file 24 | if [ -f "$nic_name_file" ];then 25 | echo "nic file exist! backup it" 26 | rm $nic_name_file_bak -f 27 | mv $nic_name_file $nic_name_file_bak 28 | else 29 | echo " nic file not exist create it " 30 | fi 31 | touch $nic_name_file 32 | echo "DEVICE="$nic_name >>$nic_name_file 33 | echo "BOOTPROTO=none" >>$nic_name_file 34 | echo "ONBOOT=yes" >>$nic_name_file 35 | echo "TYPE=Ethernet" >>$nic_name_file 36 | echo "IPADDR="$nic_ip >>$nic_name_file 37 | echo "NETMASK="$nic_netmask >>$nic_name_file 38 | /sbin/ifdown $nic_name 39 | /sbin/ifup $nic_name 40 | echo "++++++++++++++++++++++++++++++++++++++++++++++++" 41 | cat $nic_name_file 42 | echo "++++++++++++++++++++++++++++++++++++++++++++++++" 43 | } 44 | ############################################## 45 | 46 | #************************get variable********* 47 | get_host_name=$1 48 | get_gateway=$2 49 | get_nic1_ip=$3 50 | get_nic1_netmask=$4 51 | get_nic1_mac=$5 52 | get_nic2_ip=$6 53 | get_nic2_netmask=$7 54 | get_nic2_mac=$8 55 | echo "test" >>/root/setmac.txt 56 | #************************get variable********* 57 | 58 | ##############set hostname##################### 59 | echo "host name is"$get_host_name 60 | if [ -z "$get_host_name" ];then 61 | echo "please give host name!" 62 | echo "variable order by hostname gateway nic1 ip nic1 netmask nic1 mac nic2 ip nic2 netmask nic2 mac" 63 | exit 6 64 | else 65 | sed -i 's/.*HOSTNAME.*/HOSTNAME\="'$get_host_name'"/g' /etc/sysconfig/network 66 | echo "host name set OK!" 67 | fi 68 | ################################################ 69 | 70 | ##############set gateway##################### 71 | echo "gate way is"$get_gateway 72 | if [ -z "$get_gateway" ];then 73 | echo "please give gateway!" 74 | echo "variable order by hostname gateway nic1 ip nic1 netmask nic1 mac nic2 ip nic2 netmask nic2 mac" 75 | exit 7 76 | else 77 | if [ `cat /etc/sysconfig/network |grep GATEWAY |wc -l` -eq 1 ];then 78 | sed -i 's/.*GATEWAY.*/GATEWAY\="'$get_gateway'"/g' /etc/sysconfig/network 79 | else 80 | echo "GATEWAY="$get_gateway >> /etc/sysconfig/network 81 | fi 82 | echo "gate way set OK!" 83 | fi 84 | echo "-----------------------------------------------" 85 | cat /etc/sysconfig/network 86 | echo "-----------------------------------------------" 87 | ################################################ 88 | 89 | 90 | allif=`/sbin/ifconfig -a |grep Link |awk '{print $1}'|grep -vE "lo|inet6|sit0"` 91 | allmac=`/sbin/ifconfig -a |grep Link |awk '{print $5}'|grep -vE "lo|inet6|sit0"` 92 | ifcounter=`/sbin/ifconfig -a |grep Link|grep -vE "lo|inet6|sit0" |wc -l` 93 | echo $allif 94 | echo $allmac 95 | echo $ifcounter 96 | 97 | #push if and mac to array 98 | x=1 99 | while [ $x -le $ifcounter ]; 100 | 101 | do 102 | #STR_TEMP=`printf "%s%s" "$STR_TEMP" "$1"` 103 | ifname[$x]=`echo $allif|awk '{print $"'$x'"}'` 104 | ifmac[$x]=`echo $allmac|awk '{print $"'$x'"}'` 105 | echo "x" $x 106 | echo "ifname" ${ifname[$x]} 107 | echo "ifmac" ${ifmac[$x]} 108 | if [ "${ifmac[$x]}" = "$get_nic1_mac" ];then 109 | set_nic_ip ${ifname[$x]} $get_nic1_ip $get_nic2_netmask 110 | else 111 | echo "not nic1" 112 | fi 113 | if [ "${ifmac[$x]}" = "$get_nic2_mac" ];then 114 | set_nic_ip ${ifname[$x]} $get_nic2_ip $get_nic2_netmask 115 | else 116 | echo "not nic2" 117 | fi 118 | x=`expr $x + 1` 119 | done 120 | #b[0]=`echo $a |awk '{print $1}'` 121 | #b[1]=`echo $a |awk '{print $2}'` 122 | #echo ${b[0]} 123 | #echo ${b[1]} 124 | #-----------------disable rc.local----------------------- 125 | sed -i '/^sh\ \/bin\/setipbymac/s/^/#/' /etc/rc.local 126 | sed -i '/^sh\ \/bin\/setipbymac/s/^/#/' /etc/rc.d/rc.local 127 | sed -i 's/\(127.*\)/\1 "'$get_host_name'"/' /etc/hosts 128 | sed -i 's/"/\ /g' /etc/hosts 129 | reboot 130 | -------------------------------------------------------------------------------- /virttmp/nicinfo.ini: -------------------------------------------------------------------------------- 1 | ipsetup:0 2 | ip:12.12.12.12 3 | mask:255.255.255.0 4 | gw:12.12.12.1 5 | mac:52:54:00:ea:ab:77 6 | ip:172.0.0.12 7 | mask:255.255.255.0 8 | gw:none 9 | mac:52:54:00:28:16:b7 10 | -------------------------------------------------------------------------------- /virttmp/rc.local: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES 3 | # 4 | # It is highly advisable to create own systemd services or udev rules 5 | # to run scripts during boot instead of using this file. 6 | # 7 | # In constrast to previous versions due to parallel execution during boot 8 | # this script will NOT be run after all other services. 9 | # 10 | # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure 11 | # that this script will be executed during boot. 12 | 13 | touch /var/lock/subsys/local 14 | sh /bin/setipbymac.sh centos7-12 12.12.12.1 12.12.12.12 255.255.255.0 52:54:00:EA:AB:77 172.0.0.12 255.255.255.0 52:54:00:28:16:B7 15 | -------------------------------------------------------------------------------- /virtvdb/win2k3.vdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoli110/kvm_vm_setup/a1e4b155737bf48b5398f6921816a446ce30f597/virtvdb/win2k3.vdb -------------------------------------------------------------------------------- /virtvdb/win2k8.vdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoli110/kvm_vm_setup/a1e4b155737bf48b5398f6921816a446ce30f597/virtvdb/win2k8.vdb -------------------------------------------------------------------------------- /virtxml/win03.xml: -------------------------------------------------------------------------------- 1 | 2 | vmname 3 | vmmem 4 | vmmem 5 | vmcpu 6 | 7 | hvm 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Westmere 17 | Intel 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | destroy 37 | restart 38 | restart 39 | 40 | /usr/libexec/qemu-kvm 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /vm.csv: -------------------------------------------------------------------------------- 1 | #vmflag,template,name,disk1_size,disk2_size,mem_size,cpu_num,nic_type,nic1_bridge,nic2_bridge,vnc_port,outip,outmask,outgw,inip,inmask,ingw 2 | #vm template name must be ''win2003ent32chs' 'win2003ent64chs' 'win2008ent64chs' 'centos56x64' 'ubuntu1204X64' 3 | #keyword vmLvm means create lvm for vm,default vg is datavg 4 | #keyword vmCpOnly means not resize images , just cp imaiges,default vg is datavg 5 | #kerword url: means download vm images path,like 6 | #url:http://172.16.1.100/ 7 | url:ftp://virtftp:QmjfNGRFJ9EHyI5teZFz@211.147.0.120:38602/ 8 | url:ftp://virtftp:v39Ufjp5rdoYhoGb5Kw8@116.211.20.200:38602/ 9 | #vm,win2003ent32chs,win2003-138,20G,20G,2048,2,e1000,br1,br1,5921,10.10.10.21,255.255.255.0,10.10.10.1,192.168.122.138,255.255.255.0,none 10 | #vmLvm,win2003ent32chs,virt1-lab-222,10G,10G,2048,2,e1000,br2,br2,59222,10.0.0.222,255.0.0.0,10.0.0.1,172.16.2.222,255.255.255.0,none 11 | #vmCpOnly,centos6564.qcow2,centos65-8,30G,20G,2048,2,virtio,br1,br1,59008,10.10.10.8,255.255.255.0,10.10.10.1,172.16.2.8,255.255.255.0,none 12 | --------------------------------------------------------------------------------