Skip to content
This repository has been archived by the owner on Oct 31, 2021. It is now read-only.

Commit

Permalink
Progressive copy. First part.
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyrille Pontvieux committed Feb 18, 2013
1 parent a79f72d commit 4409eb3
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 15 deletions.
5 changes: 4 additions & 1 deletion src/salix-live-installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1464,11 +1464,13 @@ def thread_install_salix(self):
if not self.is_test:
main_sizes = sltl.getSizes("/dev/{0}".format(self.main_partition))
main_size = main_sizes['size']
main_block_size = getBlockSize("/dev/{0}".format(self.main_partition))
module_size = 0
for m in install_modules:
module_size += sltl.getUsedSize("/mnt/salt/mnt/{0}".format(m), blocksize = '4K')['size']
module_size += sltl.getUsedSize("/mnt/salt/mnt/{0}".format(m), main_block_size, False)['size']
minimum_free_size = 50 * 1024 * 1024 # 50 M
if module_size + minimum_free_size > main_size:
self.ProgressWindow.set_keep_above(False)
error_dialog(_("Cannot install!\nNot enougth space on main partition ({size} needed)").format(size = getHumanSize(module_size + minimum_free_size)))
self.installation = 'error'
return
Expand Down Expand Up @@ -1653,6 +1655,7 @@ def thread_install_completed(self):
if self.installation == 'installing':
self.InstallProgressBar.set_text(_("Installation process completed successfully..."))
self.InstallProgressBar.set_fraction(1)
self.ProgressWindow.set_keep_above(False)
if not self.is_test:
if self.linux_partitions:
rootmp = getMountPoint("/dev/{0}".format(self.main_partition))
Expand Down
45 changes: 35 additions & 10 deletions src/salix_livetools_library/freesize.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Calculate some size and free size of folders and mount points.
Functions:
- getHumanSize
- getBlockSize
- getSizes
- getUsedSize
"""
Expand Down Expand Up @@ -40,7 +41,19 @@ def getHumanSize(size):
sizeHuman = sizeHuman / 1024
return "{0:.1f}{1}".format(sizeHuman, units[unit])

def getSizes(path):
def getBlockSize(path):
"""
Returns the block size of the underlying filesystem denoted by 'path'.
"""
if S_ISBLK(os.stat(path).st_mode):
diskDevice = re.sub(r'^.*/([^/]+?)[0-9]*$', r'\1', path)
blockSize = int(open('/sys/block/{0}/queue/logical_block_size'.format(diskDevice), 'r').read().strip())
else:
st = os.statvfs(path)
blockSize = st.f_frsize
return blockSize

def getSizes(path, withHuman = True):
"""
Computes the different sizes of the fileystem denoted by path (either a device or a file in filesystem).
Return the following sizes (in a dictionary):
Expand Down Expand Up @@ -75,15 +88,24 @@ def getSizes(path):
uuFree = st.f_bavail * st.f_frsize # free size for unpriviliedge users
used = size - free
uuUsed = size - uuFree # used size appear differently for commun users than from root user
return {
'size':size, 'sizeHuman':getHumanSize(size),
'free':free, 'freeHuman':getHumanSize(free),
'uuFree':uuFree, 'uuFreeHuman':getHumanSize(uuFree),
'used':used, 'usedHuman':getHumanSize(used),
'uuUsed':uuUsed, 'uuUsedHuman':getHumanSize(uuUsed)
}
if withHuman:
return {
'size':size, 'sizeHuman':getHumanSize(size),
'free':free, 'freeHuman':getHumanSize(free),
'uuFree':uuFree, 'uuFreeHuman':getHumanSize(uuFree),
'used':used, 'usedHuman':getHumanSize(used),
'uuUsed':uuUsed, 'uuUsedHuman':getHumanSize(uuUsed)
}
else:
return {
'size':size, 'sizeHuman':None,
'free':free, 'freeHuman':None,
'uuFree':uuFree, 'uuFreeHuman':None,
'used':used, 'usedHuman':None,
'uuUsed':uuUsed, 'uuUsedHuman':None
}

def getUsedSize(path, blocksize = None):
def getUsedSize(path, blocksize = None, withHuman = True):
"""
Returns the size of the space used by files and folders under 'path'.
If 'blocksize' is specified, mimic the space that will be used if the blocksize of the underlying filesystem where the one specified.
Expand All @@ -102,7 +124,10 @@ def getUsedSize(path, blocksize = None):
size = int(size)
if blocksize:
size *= blocksize
return {'size':size, 'sizeHuman':getHumanSize(size)}
if withHuman:
return {'size':size, 'sizeHuman':getHumanSize(size)}
else:
return {'size':size, 'sizeHuman':None}

# Unit test
if __name__ == '__main__':
Expand Down
46 changes: 42 additions & 4 deletions src/salix_livetools_library/salt.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import glob
import re
from execute import execCall
from freesize import *
from threading import Thread
from time import sleep

def getSaLTVersion():
"""
Expand Down Expand Up @@ -125,14 +128,49 @@ def listSaLTModules():
moduledir = '{0}/{1}/{2}/modules'.format(getSaLTLiveMountPoint(), getSaLTBaseDir(), getSaLTRootDir())
return sorted(map(lambda(x): re.sub(r'.*/([^/]+).salt$', r'\1', x), glob.glob('{0}/*.salt'.format(moduledir))))

def installSaLTModule(moduleName, targetMountPoint):
def getSaLTModulePath(moduleName):
"""
Get the module full path.
"""
return '/mnt/salt/mnt/{0}'.format(moduleName)

def installSaLTModule(moduleName, targetMountPoint, callback, interval = 10, completeCallback = None):
"""
Install the module 'moduleName' from this Live session into the targetMountPoint.
The 'callback' function will be called each 'interval' seconds with the pourcentage (0 ≤ x ≤ 1) of progression (based on used size of target partition) as argument.
The 'completeCallback' function will be called after the completion of installation.
"""
_checkLive()
if not os.path.isdir('/mnt/salt/mnt/{0}'.format(moduleName)):
src = getSaLTModulePath(moduleName)
if not os.path.isdir(src):
raise IOError("The module '{0}' does not exists".format(moduleName))
if not os.path.isdir(targetMountPoint):
raise IOError("The target mount point '{0}' does not exists".format(targetMountPoint))
# TODO Pythonic way ??
execCall(['cp', '--preserve', '-r', '-f', '/mnt/salt/mnt/{0}/*'.format(moduleName), targetMountPoint], shell = False)
def get_used_size(p):
return getSizes(p, False)['used']
class ExecCopyTask:
def _start(self, cmd):
self._stopped = False
execCall(cmd)
self.stop()
def start(self, cmd):
Thread(target=self._start, args=(cmd)).start()
def is_running(self):
return not self._stopped
def stop(self):
self._stopped = True
copy_size = getUsedSize(src, getBlockSize(targetMountPoint), False)['size'] # the source can use a different blocksize than the destination
init_size = get_used_size(targetMountPoint)
final_size = init_size + copy_size
actual_size = init_size
t = ExecCopyTask(callback, interval, completeCallback)
t.start(['cp', '--preserve', '-r', '-f', '{0}/*'.format(src), targetMountPoint])
while t.is_running():
sleep(interval)
actual_size = get_used_size(targetMountPoint)
p = float(actual_size) / final_size
if p > 1:
p = 1
callback(p)
if completeCallback:
completeCallback()

0 comments on commit 4409eb3

Please sign in to comment.