2016-06-17 00:22:35 +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:22:35 +03:00
import os
import shutil
import subprocess
import tempfile
2019-06-17 04:34:47 +03:00
from . . logger import log
2019-06-17 04:12:39 +03:00
2016-06-17 00:22:35 +03:00
2019-06-10 01:48:22 +03:00
def _run_initrd_commands ( initrd , tempdir ) :
2019-06-17 04:12:39 +03:00
log . debug ( " Appending to the initrd. " )
2019-06-08 22:20:16 +03:00
2016-06-17 00:22:35 +03:00
find_proc = subprocess . Popen ( [ ' find ' , ' . ' , ' -print0 ' ] ,
stdout = subprocess . PIPE ,
stderr = subprocess . PIPE ,
cwd = tempdir )
2019-04-02 22:02:47 +03:00
cpio_proc = subprocess . Popen ( [ ' cpio ' , ' --create ' , ' --null ' , ' --quiet ' ,
2019-04-04 01:07:12 +03:00
' --format=newc ' , ' --owner=+0:+0 ' ] ,
2016-06-17 00:22:35 +03:00
stdin = find_proc . stdout ,
stdout = subprocess . PIPE ,
stderr = subprocess . PIPE ,
cwd = tempdir )
f = open ( initrd , ' ab ' )
gzip_proc = subprocess . Popen ( [ ' gzip ' ] , stdin = cpio_proc . stdout ,
stdout = f , stderr = subprocess . PIPE )
cpio_proc . wait ( )
find_proc . wait ( )
gzip_proc . wait ( )
f . close ( )
finderr = find_proc . stderr . read ( )
cpioerr = cpio_proc . stderr . read ( )
gziperr = gzip_proc . stderr . read ( )
2019-06-10 21:15:50 +03:00
if finderr : # pragma: no cover
2019-06-17 04:12:39 +03:00
log . debug ( " find stderr= %s " , finderr )
2019-06-10 21:15:50 +03:00
if cpioerr : # pragma: no cover
2019-06-17 04:12:39 +03:00
log . debug ( " cpio stderr= %s " , cpioerr )
2019-06-10 21:15:50 +03:00
if gziperr : # pragma: no cover
2019-06-17 04:12:39 +03:00
log . debug ( " gzip stderr= %s " , gziperr )
2019-06-08 16:55:09 +03:00
2019-06-28 19:05:18 +03:00
def _run_iso_commands ( iso , tempdir , cloudinit = False ) :
2021-04-07 16:37:53 +03:00
# These three programs all behave similarly for our needs, and
# different distros only have some available. xorriso is apparently
# the actively maintained variant that should be available everywhere
# and without any license issues. Some more info here:
# https://wiki.debian.org/genisoimage
programs = [ " xorrisofs " , " genisoimage " , " mkisofs " ]
2019-12-12 18:58:15 +03:00
for program in programs :
if shutil . which ( program ) :
break
cmd = [ program ,
2019-06-10 01:48:22 +03:00
" -o " , iso ,
" -J " ,
" -input-charset " , " utf8 " ,
2019-06-28 19:05:18 +03:00
" -rational-rock " ]
if cloudinit :
cmd . extend ( [ " -V " , " cidata " ] )
cmd . append ( tempdir )
2019-06-17 04:12:39 +03:00
log . debug ( " Running iso build command: %s " , cmd )
2019-06-10 01:48:22 +03:00
output = subprocess . check_output ( cmd , stderr = subprocess . STDOUT )
2019-06-17 04:12:39 +03:00
log . debug ( " cmd output: %s " , output )
2019-06-10 01:48:22 +03:00
2019-07-08 08:53:36 +03:00
def _perform_generic_injections ( injections , scratchdir , media , cb , * * kwargs ) :
2019-06-08 16:55:09 +03:00
if not injections :
return
tempdir = tempfile . mkdtemp ( dir = scratchdir )
try :
os . chmod ( tempdir , 0o775 )
for filename in injections :
2019-06-08 22:20:16 +03:00
if type ( filename ) is tuple :
filename , dst = filename
else :
dst = os . path . basename ( filename )
2019-06-17 04:12:39 +03:00
log . debug ( " Injecting src= %s dst= %s into media= %s " ,
2019-06-10 01:48:22 +03:00
filename , dst , media )
2019-06-08 22:20:16 +03:00
shutil . copy ( filename , os . path . join ( tempdir , dst ) )
2019-06-08 16:55:09 +03:00
2019-07-08 08:53:36 +03:00
return cb ( media , tempdir , * * kwargs )
2019-06-08 16:55:09 +03:00
finally :
shutil . rmtree ( tempdir )
2019-06-10 01:48:22 +03:00
2019-07-08 08:53:36 +03:00
def perform_initrd_injections ( initrd , injections , scratchdir ) :
2019-06-10 01:48:22 +03:00
"""
Insert files into the root directory of the initial ram disk
"""
_perform_generic_injections ( injections , scratchdir , initrd ,
2019-07-08 08:53:36 +03:00
_run_initrd_commands )
2019-06-10 01:48:22 +03:00
2019-06-28 19:05:18 +03:00
def perform_cdrom_injections ( injections , scratchdir , cloudinit = False ) :
2019-06-10 01:48:22 +03:00
"""
Insert files into the root directory of a generated cdrom
"""
2019-07-08 09:04:37 +03:00
if cloudinit :
iso_suffix = " -cloudinit.iso "
else :
iso_suffix = " -unattended.iso "
2019-06-10 01:48:22 +03:00
fileobj = tempfile . NamedTemporaryFile (
2019-07-08 09:04:37 +03:00
prefix = " virtinst- " , suffix = iso_suffix ,
2019-06-14 04:50:38 +03:00
dir = scratchdir , delete = False )
2019-06-10 01:48:22 +03:00
iso = fileobj . name
try :
_perform_generic_injections ( injections , scratchdir , iso ,
2019-07-08 08:53:36 +03:00
_run_iso_commands , cloudinit = cloudinit )
2019-06-10 21:15:50 +03:00
except Exception : # pragma: no cover
2019-06-10 01:48:22 +03:00
os . unlink ( iso )
raise
return iso