1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
#
# Copyright 2006-2009, 2013, 2014 Red Hat, Inc.
#
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import os
from . import progress
from .logger import log
from .devices import DeviceDisk
from .storage import StoragePool, StorageVolume
def _build_pool(conn, meter, path):
"""
Helper function for building a pool on demand. Used for building
a scratchdir pool for volume upload
"""
pool = StoragePool.lookup_pool_by_path(conn, path)
if pool: # pragma: no cover
log.debug("Existing pool '%s' found for %s", pool.name(), path)
StoragePool.ensure_pool_is_running(pool, refresh=True)
return pool
name = StoragePool.find_free_name(conn, "boot-scratch")
log.debug("Building storage pool: path=%s name=%s", path, name)
poolbuild = StoragePool(conn)
poolbuild.type = poolbuild.TYPE_DIR
poolbuild.name = name
poolbuild.target_path = path
# Explicitly don't build? since if we are creating this directory
# we probably don't have correct perms
ret = poolbuild.install(meter=meter, create=True, build=False,
autostart=True)
return ret
class _MockStream:
_data_size = None
def send(self, data):
if self._data_size is None:
self._data_size = len(data)
block_size = 128
ret = min(self._data_size, block_size)
self._data_size = max(0, self._data_size - block_size)
return ret
def finish(self):
pass
def _upload_file(conn, meter, destpool, src):
"""
Helper for uploading a file to a pool, via libvirt. Used for
kernel/initrd upload when we can't access the system scratchdir
"""
# Build stream object
if conn.in_testsuite():
stream = _MockStream()
else:
stream = conn.newStream(0) # pragma: no cover
def safe_send(data):
while True:
ret = stream.send(data)
if ret == 0 or ret == len(data):
break
data = data[ret:]
meter = progress.ensure_meter(meter)
# Build placeholder volume
size = os.path.getsize(src)
basename = os.path.basename(src)
name = StorageVolume.find_free_name(conn, destpool, basename)
log.debug("Generated volume name %s", name)
vol_install = DeviceDisk.build_vol_install(conn, name, destpool,
(float(size) / 1024.0 / 1024.0 / 1024.0), True)
disk = DeviceDisk(conn)
disk.set_vol_install(vol_install)
disk.validate()
disk.build_storage(meter)
vol = disk.get_vol_object()
if not vol:
raise RuntimeError( # pragma: no cover
"Failed to lookup scratch media volume")
try:
# Register upload
offset = 0
length = size
flags = 0
if not conn.in_testsuite():
vol.upload(stream, offset, length, flags) # pragma: no cover
# Open source file
fileobj = open(src, "rb")
# Start transfer
total = 0
meter.start(size=size,
text=_("Transferring %s") % os.path.basename(src))
while True:
# blocksize = (1024 ** 2)
blocksize = 1024
data = fileobj.read(blocksize)
if not data:
break
safe_send(data)
total += len(data)
meter.update(total)
# Cleanup
stream.finish()
meter.end(size)
except Exception: # pragma: no cover
vol.delete(0)
raise
return vol
def upload_kernel_initrd(conn, scratchdir, system_scratchdir,
meter, kernel, initrd):
"""
Upload kernel/initrd media to remote connection if necessary
"""
tmpvols = []
if (not conn.is_remote() and
(conn.is_session_uri() or scratchdir == system_scratchdir)):
# We have access to system scratchdir, don't jump through hoops
log.debug("Have access to preferred scratchdir so"
" nothing to upload") # pragma: no cover
return kernel, initrd, tmpvols # pragma: no cover
if not conn.support_remote_url_install():
# Needed for the test_urls suite
log.debug("Media upload not supported") # pragma: no cover
return kernel, initrd, tmpvols # pragma: no cover
# Build pool
log.debug("Uploading kernel/initrd media")
pool = _build_pool(conn, meter, system_scratchdir)
kvol = _upload_file(conn, meter, pool, kernel)
newkernel = kvol.path()
tmpvols.append(kvol)
ivol = _upload_file(conn, meter, pool, initrd)
newinitrd = ivol.path()
tmpvols.append(ivol)
return newkernel, newinitrd, tmpvols
|