├── .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 = " " % self.name
69 |
70 | return xml
71 |
72 |
73 | class CPU(XMLBuilderDomain.XMLBuilderDomain):
74 | """
75 | Class for generating 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 = " \n"
135 | return xml
136 |
137 | def _get_xml_config(self):
138 | mem_xml = self._get_memory_xml()
139 | if not mem_xml:
140 | return ""
141 |
142 | xml = " \n"
143 | xml += mem_xml
144 | xml += " "
145 | return xml
146 |
--------------------------------------------------------------------------------
/virtmod/virtinst/ImageFetcher.py:
--------------------------------------------------------------------------------
1 | #
2 | # Convenience module for fetching files from a network source
3 | #
4 | # Copyright 2006-2007 Red Hat, Inc.
5 | # Daniel P. Berrange
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 = " %s\n" % self.label
169 | if self.imagelabel:
170 | label_xml += " %s\n" % self.imagelabel
171 |
172 | if label_xml:
173 | xml += ">\n"
174 | xml += label_xml
175 | xml += " "
176 | else:
177 | xml += "/>"
178 |
179 |
180 | return xml
181 |
--------------------------------------------------------------------------------
/virtmod/virtinst/User.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 | # Use is subject to license terms.
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 | import platform
22 |
23 | from virtinst import uriutil
24 |
25 |
26 | class User(object):
27 | """Defines a particular user account."""
28 |
29 | PRIV_CLONE = 1
30 | PRIV_NFS_MOUNT = 2
31 | PRIV_QEMU_SYSTEM = 3
32 | PRIV_CREATE_DOMAIN = 4
33 | PRIV_CREATE_NETWORK = 5
34 |
35 | _privs = [PRIV_CLONE, PRIV_NFS_MOUNT, PRIV_QEMU_SYSTEM,
36 | PRIV_CREATE_DOMAIN, PRIV_CREATE_NETWORK]
37 |
38 | def __init__(self, euid):
39 | self._euid = euid
40 |
41 | def get_euid(self):
42 | return self._euid
43 | euid = property(get_euid)
44 |
45 | def has_priv(self, priv, conn=None):
46 | """Return if the given user is privileged enough to perform the
47 | given operation. This isn't entirely accurate currently,
48 | especially on Solaris."""
49 |
50 | if priv not in self._privs:
51 | raise ValueError('unknown privilege %s' % priv)
52 |
53 | if priv == self.PRIV_QEMU_SYSTEM:
54 | return self._euid == 0
55 |
56 | if priv == self.PRIV_CREATE_NETWORK:
57 | return (self._euid == 0) or uriutil.is_qemu_system(conn)
58 |
59 | if platform.system() == 'SunOS':
60 | return self._sun_has_priv(priv)
61 |
62 | # For all others, just assume that prescence of a connection
63 | # means we are privileged enough
64 | return True
65 |
66 | def _sun_has_priv(self, priv):
67 | # Not easy to work out!
68 | if self._euid != User.current().euid:
69 | return self._euid == 0
70 |
71 | import ucred # pylint: disable=F0401
72 | cred = ucred.get(os.getpid())
73 | if priv in [self.PRIV_CLONE,
74 | self.PRIV_CREATE_DOMAIN,
75 | self.PRIV_CREATE_NETWORK]:
76 | return cred.has_priv('Effective', 'virt_manage')
77 | if priv == self.PRIV_NFS_MOUNT:
78 | return (cred.has_priv('Effective', 'sys_mount') and
79 | cred.has_priv('Effective', 'net_privaddr'))
80 |
81 | def current():
82 | """Return the current user."""
83 | return User(os.geteuid())
84 |
85 | current = staticmethod(current)
86 |
--------------------------------------------------------------------------------
/virtmod/virtinst/VirtualAudio.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2008-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 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 = ""
304 | return xml
305 |
--------------------------------------------------------------------------------
/virtmod/virtinst/VirtualFilesystem.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2011 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 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 = " \n"
202 |
203 | if driver:
204 | if not wrpolicy:
205 | fsxml += " \n" % driver
206 | else:
207 | fsxml += " \n" % (
208 | driver,
209 | wrpolicy)
210 |
211 | fsxml += " \n" % (
212 | self.type_to_source_prop(ftype),
213 | source)
214 | fsxml += " \n" % target
215 |
216 | if readonly:
217 | fsxml += " \n"
218 |
219 | fsxml += " "
220 |
221 | return fsxml
222 |
--------------------------------------------------------------------------------
/virtmod/virtinst/VirtualHostDevice.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 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 = " "
58 | return xml
59 |
--------------------------------------------------------------------------------
/virtmod/virtinst/VirtualRNGDevice.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | #
3 | # Copyright 2013 Red Hat, Inc.
4 | # Giuseppe Scrivano
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"
192 |
193 | if self.type == self.TYPE_RANDOM:
194 | xml += " %s\n" % self.device
195 | else:
196 | model = "model='%s'" % self.type
197 | backend_type = "type='%s'" % (self.backend_type or "tcp")
198 | xml += " \n" % (model, backend_type)
199 |
200 | def add_source(mode, host, service):
201 | ret = " \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 = (" "
110 | return xml
111 | xml += ">\n"
112 | 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 = " \n"
85 | xml += " "
86 |
87 | return xml
88 |
--------------------------------------------------------------------------------
/virtmod/virtinst/VirtualVideoDevice.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 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"
92 |
93 | xml = (" ")
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 = " "
105 |
106 | return xml
107 |
--------------------------------------------------------------------------------
/virtmod/virtinst/__init__.py:
--------------------------------------------------------------------------------
1 | #
2 | # This program is free software; you can redistribute it and/or modify
3 | # it under the terms of the GNU General Public License as published by
4 | # the Free Software Foundation; either version 2 of the License, or
5 | # (at your option) any later version.
6 | #
7 | # This program is distributed in the hope that it will be useful,
8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | # GNU General Public License for more details.
11 | #
12 | # You should have received a copy of the GNU General Public License
13 | # along with this program; if not, write to the Free Software
14 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
15 | # MA 02110-1301 USA.
16 |
17 | from virtcli import cliconfig, cliutils
18 | stable_defaults = cliconfig.stable_defaults
19 | cliutils.setup_i18n()
20 |
21 |
22 | # Public imports
23 |
24 | from virtinst.Guest import Guest
25 | from virtinst.VirtualNetworkInterface import VirtualNetworkInterface
26 | from virtinst.VirtualGraphics import VirtualGraphics
27 | from virtinst.VirtualAudio import VirtualAudio
28 | from virtinst.VirtualInputDevice import VirtualInputDevice
29 | from virtinst.VirtualDisk import VirtualDisk
30 | from virtinst.VirtualHostDevice import (VirtualHostDevice,
31 | VirtualHostDeviceUSB,
32 | VirtualHostDevicePCI)
33 | from virtinst.VirtualCharDevice import VirtualCharDevice
34 | from virtinst.VirtualVideoDevice import VirtualVideoDevice
35 | from virtinst.VirtualController import VirtualController
36 | from virtinst.VirtualWatchdog import VirtualWatchdog
37 | from virtinst.VirtualFilesystem import VirtualFilesystem
38 | from virtinst.VirtualSmartCardDevice import VirtualSmartCardDevice
39 | from virtinst.VirtualRedirDevice import VirtualRedirDevice
40 | from virtinst.VirtualMemballoon import VirtualMemballoon
41 | from virtinst.DistroInstaller import DistroInstaller
42 | from virtinst.PXEInstaller import PXEInstaller
43 | from virtinst.LiveCDInstaller import LiveCDInstaller
44 | from virtinst.ImportInstaller import ImportInstaller
45 | from virtinst.ImageInstaller import ImageInstaller
46 | from virtinst.Installer import ContainerInstaller
47 | from virtinst.CloneManager import CloneDesign
48 | from virtinst.User import User
49 | from virtinst.Clock import Clock
50 | from virtinst.CPU import CPU, CPUFeature
51 | from virtinst.Seclabel import Seclabel
52 | from virtinst.VirtualRNGDevice import VirtualRNGDevice
53 |
--------------------------------------------------------------------------------
/virtmod/virtinst/hostkeymap.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 | import re
22 |
23 | # Host keytable entry : keymap name in qemu/xen
24 | # Only use lower case entries: all lookups are .lower()'d
25 | keytable = {
26 | "ar": "ar",
27 | "da": "da", "dk": "da",
28 | "de": "de",
29 | "de-ch": "de-ch",
30 | "en-gb": "en-gb", "gb": "en-gb", "uk": "en-gb",
31 | "en-us": "en-us", "us": "en-us",
32 | "es": "es",
33 | "et": "et",
34 | "fi": "fi", "se_fi": "fi",
35 | "fo": "fo",
36 | "fr": "fr",
37 | "fr-be": "fr-be", "be": "fr-be",
38 | "fr-ca": "fr-ca", "ca": "fr-ca",
39 | "fr-ch": "fr-ch", "fr_ch": "fr-ch",
40 | "hr": "hr",
41 | "hu": "hu",
42 | "is": "is",
43 | "it": "it",
44 | "ja": "ja", "jp106": "ja", "jp": "ja",
45 | "lt": "lt",
46 | "lv": "lv",
47 | "mk": "mk",
48 | "nl": "nl",
49 | "nl-be": "nl-be",
50 | "no": "no",
51 | "pl": "pl",
52 | "pt": "pt",
53 | "pt-br": "pt-br", "br": "pt-br", "br-abnt2": "pt-br",
54 | "ru": "ru",
55 | "sl": "sl",
56 | "sv": "sv",
57 | "th": "th",
58 | "tr": "tr",
59 | }
60 |
61 | KEYBOARD_DIR = "/etc/sysconfig/keyboard"
62 | XORG_CONF = "/etc/X11/xorg.conf"
63 | CONSOLE_SETUP_CONF = "/etc/default/console-setup"
64 |
65 |
66 | def find_xkblayout(path):
67 | """
68 | Reads a keyboard layout from a file that defines an XKBLAYOUT
69 | variable, e.g. /etc/default/{keyboard,console-setup}.
70 | The format of these files is such that they can be 'sourced'
71 | in a shell script.
72 | """
73 |
74 | kt = None
75 | try:
76 | f = open(path, "r")
77 | except IOError, e:
78 | logging.debug('Could not open "%s": %s ', path, str(e))
79 | else:
80 | keymap_re = re.compile(r'\s*XKBLAYOUT="(?P[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 |
--------------------------------------------------------------------------------