1
2 import base64
3 try:
4
5 import ConfigParser
6 except ImportError:
7
8 import configparser as ConfigParser
9 import itertools
10 import os
11 import platform
12 import pycurl
13 import sys
14
15 import virtualization.support as virt_support
16 from virtualization.util import generate_uuid
17 from virtualization.errors import VirtualizationException
18 from up2date_client import up2dateLog
19
20 log = up2dateLog.initLog()
21
22 config = ConfigParser.ConfigParser({
23 "IMAGE_BASE_PATH" : "/var/lib/libvirt/images/",
24 "IMAGE_CFG_TEMPLATE" : "/etc/sysconfig/rhn/kvm-template.xml",
25 "PRE_SCRIPT" : "",
26 })
27 config.read('/etc/sysconfig/rhn/image.cfg')
28 IMAGE_BASE_PATH = config.get("global", "IMAGE_BASE_PATH")
29 IMAGE_CFG_TEMPLATE = config.get("global", "IMAGE_CFG_TEMPLATE")
30 PRE_SCRIPT = config.get("global", "PRE_SCRIPT")
31
32
33 __rhnexport__ = [
34 'deploy'
35 ]
36
38 """Download file from a URL to given filename using given proxy settings."""
39 log.log_debug("downloading %s" % server_url)
40
41
42 c = pycurl.Curl()
43 c.setopt(pycurl.URL, server_url)
44
45
46
47
48
49 if "proxyURL" in proxy_settings and proxy_settings["proxyURL"] is not None and proxy_settings["proxyURL"] != "":
50 server = proxy_settings["proxyURL"]
51 c.setopt(pycurl.PROXY, server )
52 if "proxyUser" in proxy_settings and proxy_settings["proxyUser"] is not None and proxy_settings["proxyUser"] != "":
53 user = proxy_settings["proxyUser"]
54 password = base64.b64decode(proxy_settings["proxyPass"])
55 c.setopt(pycurl.PROXYUSERPWD, "%s:%s" % (user, password))
56
57 file_path = "/%s/%s" % (IMAGE_BASE_PATH, target_filename)
58 f = open(file_path, 'w')
59 c.setopt(pycurl.FOLLOWLOCATION, 1)
60 c.setopt(pycurl.WRITEFUNCTION, f.write)
61 c.setopt(pycurl.SSL_VERIFYPEER, 0)
62 c.perform()
63 log.log_debug("curl got HTTP code: %s" % c.getinfo(pycurl.HTTP_CODE))
64 f.close()
65 return c.getinfo(pycurl.HTTP_CODE)
66
83
86
87 -def _domain_exists(dom, connection):
88 try:
89 connection.lookupByName(dom)
90 except Exception:
91 log.log_debug("domain %s does not exist" % dom)
92 return False
93 log.log_debug("domain %s exists" % dom)
94 return True
95
110
111
112
113
114
115
116
117
118
119
120
121 -def deploy(params, extra_params="", cache_only=None):
122 """Download and start a new image."""
123
124 image_filename = params["downloadURL"].split('/')[-1]
125 domain_name, image_extension = os.path.splitext(image_filename)
126 if not image_extension or image_extension != ".qcow2":
127 return (1, "image type is not qcow2: %s" % image_filename, {})
128 image_arch = platform.machine() or 'x86_64'
129
130 try:
131 connection = _connect_to_hypervisor()
132 except Exception as e:
133 return (1, "%s" % e, {})
134
135
136 if "domainName" in params and params["domainName"] != "":
137 domain_name = params["domainName"]
138 image_filename = domain_name + image_extension
139
140
141 if _domain_exists(domain_name, connection) or _file_exists("%s/%s" % (IMAGE_BASE_PATH, image_filename)):
142 for i in itertools.count(1):
143 new_domain_name = ("%s-%i" % (domain_name, i))
144 image_filename = new_domain_name + image_extension
145 if not _domain_exists(new_domain_name, connection) and not _file_exists("%s/%s" % (IMAGE_BASE_PATH, image_filename)):
146 log.log_debug("free domain and matching filename found")
147 domain_name = new_domain_name
148 break
149
150 log.log_debug("filename=%s domain=%s arch=%s" % (image_filename, domain_name, image_arch))
151
152 if not domain_name or image_arch not in ['x86_64', 'i686', 'ppc64le', 's390x']:
153 log.log_debug("invalid domain name or arch")
154 return (1, "invalid domain name or arch: domain=%s arch=%s" % (domain_name, image_arch), {})
155
156 http_response_code = -1
157 try:
158 http_response_code = _download_file(image_filename, params["downloadURL"], params["proxySettings"])
159 if not _file_exists("%s/%s" % (IMAGE_BASE_PATH, image_filename)):
160 log.log_debug("downloading image file failed, HTTP return code: %s" % http_response_code)
161 return (1, "downloading image file failed: %s/%s (%s)" % (IMAGE_BASE_PATH, image_filename, http_response_code), {})
162 except Exception as e:
163 return (1, "getting the image failed with: %s" % e, {})
164 if cache_only:
165 return (0, "image fetched and cached for later deployment", {})
166
167 image_path = "%s/%s" % (IMAGE_BASE_PATH, image_filename)
168 if not os.path.exists(image_path):
169 return (1, "image not found at %s" % image_path, {})
170 log.log_debug("working on image in %s" % image_path)
171
172 create_params = { 'name' : domain_name,
173 'arch' : image_arch,
174 'extra' : extra_params,
175 'mem_kb' : params["memKB"],
176 'vcpus' : params["vCPUs"],
177 'uuid' : generate_uuid(),
178 'disk' : image_path,
179 'imageType' : 'qcow2',
180 'virtBridge' : params["virtBridge"],
181 }
182 create_xml = _generate_xml(create_params)
183 domain = None
184 try:
185 domain = connection.defineXML(create_xml)
186 except Exception as e:
187 return (1, "failed to pass XML to libvirt: %s" % e, {})
188
189 domain.create()
190 virt_support.refresh()
191
192 return (0, "image '%s' deployed and started" % domain_name, {})
193
194
195 if __name__ == "__main__":
196
197 log.log_debug("actions/image.py called")
198 print("You can not run this module by itself")
199 sys.exit(-1)
200