2016-06-17 00:28:51 +03:00
#
# Copyright 2006-2009, 2013, 2014 Red Hat, Inc.
#
2018-04-04 16:35:41 +03:00
# This work is licensed under the GNU GPLv2 or later.
2018-03-20 22:00:02 +03:00
# See the COPYING file in the top-level directory.
2016-06-17 00:28:51 +03:00
import logging
import os
from . import util
2018-03-20 19:27:37 +03:00
from . devices import DeviceDisk
2016-06-17 00:28:51 +03:00
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 :
logging . debug ( " Existing pool ' %s ' found for %s " , pool . name ( ) , path )
pool . refresh ( 0 )
return pool
2017-07-19 02:09:58 +03:00
name = StoragePool . find_free_name ( conn , " boot-scratch " )
2016-06-17 00:28:51 +03:00
logging . 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
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
stream = conn . newStream ( 0 )
def safe_send ( data ) :
while True :
ret = stream . send ( data )
if ret == 0 or ret == len ( data ) :
break
data = data [ ret : ]
meter = util . ensure_meter ( meter )
# Build placeholder volume
size = os . path . getsize ( src )
basename = os . path . basename ( src )
name = StorageVolume . find_free_name ( destpool , basename )
if name != basename :
logging . debug ( " Generated non-colliding volume name %s " , name )
2018-03-20 19:18:35 +03:00
vol_install = DeviceDisk . build_vol_install ( conn , name , destpool ,
2016-06-17 00:28:51 +03:00
( float ( size ) / 1024.0 / 1024.0 / 1024.0 ) , True )
2018-03-20 19:18:35 +03:00
disk = DeviceDisk ( conn )
2016-06-17 00:28:51 +03:00
disk . set_vol_install ( vol_install )
disk . validate ( )
2018-09-03 23:44:38 +03:00
disk . build_storage ( meter )
2016-06-17 00:28:51 +03:00
vol = disk . get_vol_object ( )
if not vol :
2019-03-15 20:42:27 +03:00
raise RuntimeError ( " Failed to lookup scratch media volume " )
2016-06-17 00:28:51 +03:00
try :
# Register upload
offset = 0
length = size
flags = 0
vol . upload ( stream , offset , length , flags )
# Open source file
2018-03-18 18:50:22 +03:00
fileobj = open ( src , " rb " )
2016-06-17 00:28:51 +03:00
# 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 )
2017-07-24 11:26:48 +03:00
except Exception :
2018-03-18 18:50:22 +03:00
vol . delete ( 0 )
2016-06-17 00:28:51 +03:00
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
logging . debug ( " Have access to preferred scratchdir so "
" nothing to upload " )
return kernel , initrd , tmpvols
2019-02-28 20:23:00 +03:00
if not conn . support_remote_url_install ( ) :
# Needed for the test_urls suite
logging . debug ( " Media upload not supported " )
return kernel , initrd , tmpvols
2016-06-17 00:28:51 +03:00
# Build pool
logging . 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