Statistics
| Branch: | Tag: | Revision:

root / image_creator / util.py @ 63af9c37

History | View | Annotate | Download (4.3 kB)

1 121f3bc0 Nikos Skalkotos
# -*- coding: utf-8 -*-
2 121f3bc0 Nikos Skalkotos
#
3 ae48a082 Nikos Skalkotos
# Copyright 2012 GRNET S.A. All rights reserved.
4 ae48a082 Nikos Skalkotos
#
5 ae48a082 Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
6 ae48a082 Nikos Skalkotos
# without modification, are permitted provided that the following
7 ae48a082 Nikos Skalkotos
# conditions are met:
8 ae48a082 Nikos Skalkotos
#
9 ae48a082 Nikos Skalkotos
#   1. Redistributions of source code must retain the above
10 ae48a082 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
11 ae48a082 Nikos Skalkotos
#      disclaimer.
12 ae48a082 Nikos Skalkotos
#
13 ae48a082 Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
14 ae48a082 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
15 ae48a082 Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
16 ae48a082 Nikos Skalkotos
#      provided with the distribution.
17 ae48a082 Nikos Skalkotos
#
18 ae48a082 Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 ae48a082 Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 ae48a082 Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 ae48a082 Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 ae48a082 Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 ae48a082 Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 ae48a082 Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 ae48a082 Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 ae48a082 Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 ae48a082 Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 ae48a082 Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 ae48a082 Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
30 ae48a082 Nikos Skalkotos
#
31 ae48a082 Nikos Skalkotos
# The views and conclusions contained in the software and
32 ae48a082 Nikos Skalkotos
# documentation are those of the authors and should not be
33 ae48a082 Nikos Skalkotos
# interpreted as representing official policies, either expressed
34 ae48a082 Nikos Skalkotos
# or implied, of GRNET S.A.
35 3ccb2618 Nikos Skalkotos
36 121f3bc0 Nikos Skalkotos
"""This module provides various helper functions to be used by other parts of
37 121f3bc0 Nikos Skalkotos
the package.
38 121f3bc0 Nikos Skalkotos
"""
39 121f3bc0 Nikos Skalkotos
40 0dbc4db9 Nikos Skalkotos
import sh
41 8e3065a0 Nikos Skalkotos
import hashlib
42 f3845095 Nikos Skalkotos
import time
43 c16850ae Nikos Skalkotos
import os
44 979096dd Nikos Skalkotos
45 f165adc0 Nikos Skalkotos
46 f165adc0 Nikos Skalkotos
class FatalError(Exception):
47 88f83027 Nikos Skalkotos
    """Fatal Error exception of snf-image-creator"""
48 f165adc0 Nikos Skalkotos
    pass
49 f165adc0 Nikos Skalkotos
50 f165adc0 Nikos Skalkotos
51 3ccb2618 Nikos Skalkotos
def get_command(command):
52 88f83027 Nikos Skalkotos
    """Return a file system binary command"""
53 3ccb2618 Nikos Skalkotos
    def find_sbin_command(command, exception):
54 3ccb2618 Nikos Skalkotos
        search_paths = ['/usr/local/sbin', '/usr/sbin', '/sbin']
55 3ccb2618 Nikos Skalkotos
        for fullpath in map(lambda x: "%s/%s" % (x, command), search_paths):
56 3ccb2618 Nikos Skalkotos
            if os.path.exists(fullpath) and os.access(fullpath, os.X_OK):
57 0dbc4db9 Nikos Skalkotos
                return sh.Command(fullpath)
58 3ccb2618 Nikos Skalkotos
        raise exception
59 3ccb2618 Nikos Skalkotos
60 3ccb2618 Nikos Skalkotos
    try:
61 0dbc4db9 Nikos Skalkotos
        return sh.__getattr__(command)
62 3f2ae845 Nikos Skalkotos
    except sh.CommandNotFound as e:
63 3ccb2618 Nikos Skalkotos
        return find_sbin_command(command, e)
64 22a6d232 Nikos Skalkotos
65 22a6d232 Nikos Skalkotos
66 f3845095 Nikos Skalkotos
def try_fail_repeat(command, *args):
67 88f83027 Nikos Skalkotos
    """Execute a command multiple times until it succeeds"""
68 f3845095 Nikos Skalkotos
    times = (0.1, 0.5, 1, 2)
69 f3845095 Nikos Skalkotos
    i = iter(times)
70 f3845095 Nikos Skalkotos
    while True:
71 f3845095 Nikos Skalkotos
        try:
72 f3845095 Nikos Skalkotos
            command(*args)
73 f3845095 Nikos Skalkotos
            return
74 f3845095 Nikos Skalkotos
        except sh.ErrorReturnCode:
75 f3845095 Nikos Skalkotos
            try:
76 f3845095 Nikos Skalkotos
                wait = i.next()
77 f3845095 Nikos Skalkotos
            except StopIteration:
78 f3845095 Nikos Skalkotos
                break
79 f3845095 Nikos Skalkotos
            time.sleep(wait)
80 f3845095 Nikos Skalkotos
81 f3845095 Nikos Skalkotos
    raise FatalError("Command: `%s %s' failed" % (command, " ".join(args)))
82 f3845095 Nikos Skalkotos
83 f3845095 Nikos Skalkotos
84 c16850ae Nikos Skalkotos
def free_space(dirname):
85 88f83027 Nikos Skalkotos
    """Compute the free space in a directory"""
86 c16850ae Nikos Skalkotos
    stat = os.statvfs(dirname)
87 c16850ae Nikos Skalkotos
    return stat.f_bavail * stat.f_frsize
88 c16850ae Nikos Skalkotos
89 c16850ae Nikos Skalkotos
90 48511209 Nikos Skalkotos
def check_guestfs_version(ghandler, major, minor, release):
91 48511209 Nikos Skalkotos
    """Checks if the version of the used libguestfs is smaller, equal or
92 48511209 Nikos Skalkotos
    greater than the one specified by the major, minor and release triplet
93 48511209 Nikos Skalkotos

94 48511209 Nikos Skalkotos
    Returns:
95 48511209 Nikos Skalkotos
        < 0 if the installed version is smaller than the specified one
96 48511209 Nikos Skalkotos
        = 0 if they are equal
97 48511209 Nikos Skalkotos
        > 0 if the installed one is greater than the specified one
98 48511209 Nikos Skalkotos
    """
99 48511209 Nikos Skalkotos
100 48511209 Nikos Skalkotos
    ver = ghandler.version()
101 48511209 Nikos Skalkotos
102 48511209 Nikos Skalkotos
    for (a, b) in (ver['major'], major), (ver['minor'], minor), \
103 48511209 Nikos Skalkotos
            (ver['release'], release):
104 48511209 Nikos Skalkotos
        if a != b:
105 48511209 Nikos Skalkotos
            return a - b
106 48511209 Nikos Skalkotos
107 48511209 Nikos Skalkotos
    return 0
108 48511209 Nikos Skalkotos
109 48511209 Nikos Skalkotos
110 e77e66a9 Nikos Skalkotos
class MD5:
111 88f83027 Nikos Skalkotos
    """Represents MD5 computations"""
112 e77e66a9 Nikos Skalkotos
    def __init__(self, output):
113 88f83027 Nikos Skalkotos
        """Create an MD5 instance"""
114 e77e66a9 Nikos Skalkotos
        self.out = output
115 8e3065a0 Nikos Skalkotos
116 e77e66a9 Nikos Skalkotos
    def compute(self, filename, size):
117 88f83027 Nikos Skalkotos
        """Compute the MD5 checksum of a file"""
118 96171db1 Nikos Skalkotos
        MB = 2 ** 20
119 96171db1 Nikos Skalkotos
        BLOCKSIZE = 4 * MB  # 4MB
120 8e3065a0 Nikos Skalkotos
121 96171db1 Nikos Skalkotos
        prog_size = ((size + MB - 1) // MB)  # in MB
122 4e58b51b Nikos Skalkotos
        progressbar = self.out.Progress(prog_size, "Calculating md5sum", 'mb')
123 e77e66a9 Nikos Skalkotos
        md5 = hashlib.md5()
124 e77e66a9 Nikos Skalkotos
        with open(filename, "r") as src:
125 e77e66a9 Nikos Skalkotos
            left = size
126 e77e66a9 Nikos Skalkotos
            while left > 0:
127 e77e66a9 Nikos Skalkotos
                length = min(left, BLOCKSIZE)
128 e77e66a9 Nikos Skalkotos
                data = src.read(length)
129 e77e66a9 Nikos Skalkotos
                md5.update(data)
130 e77e66a9 Nikos Skalkotos
                left -= length
131 96171db1 Nikos Skalkotos
                progressbar.goto((size - left) // MB)
132 42ace959 Nikos Skalkotos
133 e77e66a9 Nikos Skalkotos
        checksum = md5.hexdigest()
134 e77e66a9 Nikos Skalkotos
        progressbar.success(checksum)
135 8e3065a0 Nikos Skalkotos
136 e77e66a9 Nikos Skalkotos
        return checksum
137 22a6d232 Nikos Skalkotos
138 22a6d232 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :