PEPify unsquashfs
This commit is contained in:
parent
2b097e7f3c
commit
4b1975d3e2
@ -27,36 +27,39 @@ from collections import namedtuple
|
||||
|
||||
from libcalamares import *
|
||||
|
||||
UnpackEntry = namedtuple( 'UnpackEntry', [ 'source', 'destination', 'sourceDir' ] )
|
||||
UnpackStatusEntry = namedtuple( 'UnpackStatusEntry', [ 'copied', 'total' ] )
|
||||
UnpackEntry = namedtuple(
|
||||
'UnpackEntry', ['source', 'destination', 'source_dir'])
|
||||
UnpackStatusEntry = namedtuple('UnpackStatusEntry', ['copied', 'total'])
|
||||
|
||||
ON_POSIX = 'posix' in sys.builtin_module_names
|
||||
|
||||
|
||||
def fileCopy( source, dest, progress_cb ):
|
||||
def file_copy(source, dest, progress_cb):
|
||||
# Environment used for executing rsync properly
|
||||
# Setting locale to C (fix issue with tr_TR locale)
|
||||
at_env = os.environ
|
||||
at_env["LC_ALL"] = "C"
|
||||
|
||||
process = subprocess.Popen( [ 'rsync', '-ar', '--progress', source, dest ],
|
||||
env=self.at_env,
|
||||
bufsize=1,
|
||||
stdout=subprocess.PIPE,
|
||||
close_fds=ON_POSIX )
|
||||
process = subprocess.Popen(['rsync', '-ar', '--progress', source, dest],
|
||||
env=at_env,
|
||||
bufsize=1,
|
||||
stdout=subprocess.PIPE,
|
||||
close_fds=ON_POSIX)
|
||||
|
||||
for line in iter( self.process.stdout.readline, b'' ):
|
||||
for line in iter(process.stdout.readline, b''):
|
||||
# small comment on this regexp.
|
||||
# rsync outputs three parameters in the progress.
|
||||
# xfer#x => i try to interpret it as 'file copy try no. x'
|
||||
# to-check=x/y, where:
|
||||
# - x = number of files yet to be checked
|
||||
# - y = currently calculated total number of files.
|
||||
# but if you're copying directory with some links in it, the xfer# might not be a
|
||||
# reliable counter. ( for one increase of xfer, many files may be created)
|
||||
# but if you're copying directory with some links in it, the xfer#
|
||||
# might not be a reliable counter (for one increase of xfer, many
|
||||
# files may be created).
|
||||
# In case of manjaro, we pre-compute the total number of files.
|
||||
# therefore we can easily subtract x from y in order to get real files copied / processed count.
|
||||
m = re.findall( r'xfr#(\d+), ir-chk=(\d+)/(\d+)', line.decode() )
|
||||
# therefore we can easily subtract x from y in order to get real files
|
||||
# copied / processed count.
|
||||
m = re.findall(r'xfr#(\d+), ir-chk=(\d+)/(\d+)', line.decode())
|
||||
if m:
|
||||
# we've got a percentage update
|
||||
num_files_remaining = int(m[0][1])
|
||||
@ -64,68 +67,74 @@ def fileCopy( source, dest, progress_cb ):
|
||||
# adjusting the offset so that progressbar can be continuesly drawn
|
||||
num_files_copied = num_files_total_local - num_files_remaining
|
||||
|
||||
|
||||
# I guess we're updating every 100 files...
|
||||
if num_files_copied % 100 == 0:
|
||||
progress_cb( num_files_copied )
|
||||
progress_cb(num_files_copied)
|
||||
|
||||
|
||||
class UnsquashOperation:
|
||||
def __init__( self, unpack ):
|
||||
|
||||
def __init__(self, unpack):
|
||||
self.unpacklist = unpack
|
||||
self.unpackstatus = dict()
|
||||
for entry in unpack:
|
||||
self.unpackstatus[ entry.source ] = UnpackStatusEntry( copied=0, total=0 )
|
||||
self.unpackstatus[entry.source] = UnpackStatusEntry(
|
||||
copied=0, total=0)
|
||||
|
||||
|
||||
def updateCopyProgress( self, source, nfiles ):
|
||||
def update_copy_progress(self, source, nfiles):
|
||||
if source in self.unpackstatus:
|
||||
self.unpackstatus[ source ].copied = nfiles
|
||||
self.reportProgress()
|
||||
self.unpackstatus[source].copied = nfiles
|
||||
self.report_progress()
|
||||
|
||||
|
||||
def reportProgress( self ):
|
||||
progress = float( 0 )
|
||||
for statusEntry in self.unpackstatus:
|
||||
if statusEntry.total == 0:
|
||||
def report_progress(self):
|
||||
progress = float(0)
|
||||
for status_entry in self.unpackstatus:
|
||||
if status_entry.total == 0:
|
||||
continue
|
||||
|
||||
partialProgress = 0.05 # Having a total !=0 gives 5%
|
||||
partialprogress = 0.05 # Having a total !=0 gives 5%
|
||||
|
||||
partialProgress += 0.95 * ( statusEntry.copied / float( statusEntry.total ) )
|
||||
progress += partialProgress / len( self.unpackstatus )
|
||||
partialprogress += 0.95 * \
|
||||
(status_entry.copied / float(status_entry.total))
|
||||
progress += partialprogress / len(self.unpackstatus)
|
||||
|
||||
job.setprogress( progress )
|
||||
job.setprogress(progress)
|
||||
|
||||
|
||||
def run( self ):
|
||||
sourceMountPath = tempfile.mkdtemp()
|
||||
def run(self):
|
||||
source_mount_path = tempfile.mkdtemp()
|
||||
try:
|
||||
for entry in self.unpacklist:
|
||||
sqfsList = subprocess.check_output( [ "unsquashfs", "-l", entry.source ] )
|
||||
filesCount = sqfsList.splitlines().count()
|
||||
self.unpackstatus[ entry.source ].total = filesCount
|
||||
sqfslist = subprocess.check_output(["unsquashfs",
|
||||
"-l",
|
||||
entry.source])
|
||||
filescount = sqfslist.splitlines().count()
|
||||
self.unpackstatus[entry.source].total = filescount
|
||||
|
||||
imgBaseName = os.path.splitext( os.path.basename( entry.source ) )[ 0 ]
|
||||
imgMountDir = sourceMountPath + os.sep + imgBaseName
|
||||
os.mkdir( imgMountDir )
|
||||
entry.sourceDir = imgMountDir
|
||||
self.reportProgress()
|
||||
self.unsquashImage( entry )
|
||||
imgbasename = os.path.splitext(
|
||||
os.path.basename(entry.source))[0]
|
||||
imgmountdir = source_mount_path + os.sep + imgbasename
|
||||
os.mkdir(imgmountdir)
|
||||
entry.source_dir = imgmountdir
|
||||
self.report_progress()
|
||||
self.unsquash_image(entry)
|
||||
finally:
|
||||
shutil.rmtree( sourceMountPath )
|
||||
shutil.rmtree(source_mount_path)
|
||||
|
||||
|
||||
def unsquashImage( self, entry ):
|
||||
subprocess.check_call( [ "mount", entry.source, entry.sourceDir, "-t", "squashfs", "-o", "loop" ] )
|
||||
def unsquash_image(self, entry):
|
||||
subprocess.check_call(["mount",
|
||||
entry.source,
|
||||
entry.source_dir,
|
||||
"-t", "squashfs", "-o", "loop"])
|
||||
try:
|
||||
fileCopy( entry.sourceDir, entry.destination, self.reportProgress )
|
||||
file_copy(entry.source_dir,
|
||||
entry.destination,
|
||||
self.report_progress)
|
||||
finally:
|
||||
subprocess.check_call( [ "umount", "-l", entry.sourceDir ] )
|
||||
subprocess.check_call(["umount", "-l", entry.source_dir])
|
||||
|
||||
|
||||
def run():
|
||||
# from globalStorage: rootMountPoint
|
||||
# from globalstorage: rootMountPoint
|
||||
# from job.configuration:
|
||||
# the path to where to mount the source image(s) for copying
|
||||
# an ordered list of unpack mappings for sqfs file <-> target dir relative
|
||||
@ -137,24 +146,28 @@ def run():
|
||||
# - source: "/path/to/another/image.sqfs"
|
||||
# destination: ""
|
||||
|
||||
rootMountPoint = globalStorage.value( "rootMountPoint" )
|
||||
if not rootMountPoint:
|
||||
return ( "No mount point for root partition in GlobalStorage",
|
||||
"GlobalStorage does not contain a \"rootMountPoint\" key, doing nothing" )
|
||||
if not os.path.exists( rootMountPoint ):
|
||||
return ( "Bad mount point for root partition in GlobalStorage",
|
||||
"GlobalStorage[\"rootMountPoint\"] is \"{}\", which does not exist, doing nothing".format( rootMountPoint ) )
|
||||
root_mount_point = globalstorage.value("rootMountPoint")
|
||||
if not root_mount_point:
|
||||
return ("No mount point for root partition in globalstorage",
|
||||
"globalstorage does not contain a \"rootMountPoint\" key, "
|
||||
"doing nothing")
|
||||
if not os.path.exists(root_mount_point):
|
||||
return ("Bad mount point for root partition in globalstorage",
|
||||
"globalstorage[\"rootMountPoint\"] is \"{}\", which does not "
|
||||
"exist, doing nothing".format(root_mount_point))
|
||||
unpack = list()
|
||||
|
||||
for entry in job.configuration[ "unpack" ]:
|
||||
source = os.path.abspath( entry[ "source" ] )
|
||||
destination = os.path.abspath( os.path.join( rootMountPoint, entry[ "destination" ] ) )
|
||||
for entry in job.configuration["unpack"]:
|
||||
source = os.path.abspath(entry["source"])
|
||||
destination = os.path.abspath(
|
||||
os.path.join(root_mount_point, entry["destination"]))
|
||||
|
||||
if not os.path.isfile( source ) or not os.path.isdir( destination ):
|
||||
return ( "Bad source or destination",
|
||||
"source=\"{}\"\ndestination=\"{}\"".format( source, destination ) )
|
||||
if not os.path.isfile(source) or not os.path.isdir(destination):
|
||||
return ("Bad source or destination",
|
||||
"source=\"{}\"\ndestination=\"{}\"".format(source,
|
||||
destination))
|
||||
|
||||
unpack.append( UnpackEntry( source, destination ) )
|
||||
unpack.append(UnpackEntry(source, destination))
|
||||
|
||||
unsquashop = UnsquashOperation( unpack )
|
||||
unsquashop = UnsquashOperation(unpack)
|
||||
return unsquashop.run()
|
||||
|
Loading…
Reference in New Issue
Block a user