+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""Package for creating images to be used with Synnefo open source cloud
+software.
+"""
+
from image_creator.version import __version__
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module hosts the code that performes the host bundling operation. By
+using the create_image method of the BundleVolume class the user can create an
+image out of the running system.
+"""
+
import os
import re
import tempfile
#!/usr/bin/env python
-
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module is the entrance point for the dialog-based version of the
+snf-image-creator program. The main function will create a dialog where the
+user is asked if he wants to use the program in expert or wizard mode.
+"""
+
import dialog
import sys
import os
-#!/usr/bin/env python
-
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module implements the "expert" mode of the dialog-based version of
+snf-image-creator.
+"""
+
import os
import textwrap
import StringIO
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
continue
if len(answer) == 0 and "account" in session:
- del session["account"]
+ del session["account"]
else:
token = answer.strip()
session['account'] = Kamaki.get_account(token)
-#!/usr/bin/env python
-
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""Module providing useful functions for the dialog-based version of
+snf-image-creator.
+"""
+
import os
from image_creator.output.dialog import GaugeOutput
from image_creator.util import MD5
-#!/usr/bin/env python
-
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module implements the "wizard" mode of the dialog-based version of
+snf-image-creator.
+"""
+
import time
import StringIO
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""Module hosting the Disk class."""
+
from image_creator.util import get_command
from image_creator.util import try_fail_repeat
from image_creator.util import free_space
blockdev = get_command('blockdev')
-TMP_CANDIDATES = ['/var/tmp', os.path.expanduser('~'), '/mnt']
+def get_tmp_dir(default=None):
+ """Check tmp directory candidates and return the one with the most
+ available space.
+ """
+ if default is not None:
+ return default
+
+ TMP_CANDIDATES = ['/var/tmp', os.path.expanduser('~'), '/mnt']
+
+ space = map(free_space, TMP_CANDIDATES)
+
+ max_idx = 0
+ max_val = space[0]
+ for i, val in zip(range(len(space)), space):
+ if val > max_val:
+ max_val = val
+ max_idx = i
+
+ # Return the candidate path with more available space
+ return TMP_CANDIDATES[max_idx]
class Disk(object):
self.out = output
self.meta = {}
self.tmp = tempfile.mkdtemp(prefix='.snf_image_creator.',
- dir=self._get_tmp_dir(tmp))
+ dir=get_tmp_dir(tmp))
self._add_cleanup(shutil.rmtree, self.tmp)
- def _get_tmp_dir(self, default=None):
- """Check tmp directory candidates and return the one with the most
- available space.
- """
- if default is not None:
- return default
-
- space = map(free_space, TMP_CANDIDATES)
-
- max_idx = 0
- max_val = space[0]
- for i, val in zip(range(len(space)), space):
- if val > max_val:
- max_val = val
- max_idx = i
-
- # Return the candidate path with more available space
- return TMP_CANDIDATES[max_idx]
-
def _add_cleanup(self, job, *args):
"""Add a new job in the cleanup list"""
self._cleanup_jobs.append((job, args))
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module provides the code for handling GUID partition tables"""
+
import struct
import sys
import uuid
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This package hosts the help files of the programe."""
+
import sys
import os
def get_help_file(name):
+ """Returns the full path of a helpfile"""
dirname = os.path.dirname(sys.modules[__name__].__file__)
return "%s%s%s.rst" % (dirname, os.sep, name)
+# -*- coding: utf-8 -*-
+#
# Copyright 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This modules provides the interface for working with the ./kamaki library.
+The library is used to upload images to and register them with a Synnefo
+deployment.
+"""
+
from os.path import basename
from kamaki.cli.config import Config
class Kamaki(object):
-
+ """Wrapper class for the ./kamaki library"""
CONTAINER = "images"
@staticmethod
#!/usr/bin/env python
-
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module is the entrance point for the non-interactive version of the
+snf-image-creator program.
+"""
+
from image_creator import __version__ as version
from image_creator.disk import Disk
from image_creator.util import FatalError, MD5
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This package provides various classes for preparing different Operating
+Systems for image creation.
+"""
+
from image_creator.util import FatalError
import textwrap
def collect_metadata(self):
"""Collect metadata about the OS"""
-
try:
if not self.mount(readonly=True):
raise FatalError("Unable to mount the media read-only")
finally:
self.umount()
- def _do_collect_metadata(self):
-
- self.meta['ROOT_PARTITION'] = "%d" % self.g.part_to_partnum(self.root)
- self.meta['OSFAMILY'] = self.g.inspect_get_type(self.root)
- self.meta['OS'] = self.g.inspect_get_distro(self.root)
- if self.meta['OS'] == "unknown":
- self.meta['OS'] = self.meta['OSFAMILY']
- self.meta['DESCRIPTION'] = self.g.inspect_get_product_name(self.root)
-
- def _is_sysprep(self, obj):
- return getattr(obj, 'sysprep', False) and callable(obj)
+ self.out.output()
def list_syspreps(self):
-
+ """Returns a list of sysprep objects"""
objs = [getattr(self, name) for name in dir(self)
if not name.startswith('_')]
return [x for x in objs if self._is_sysprep(x) and x.executed is False]
def sysprep_info(self, obj):
+ """Returns information about a sysprep object"""
assert self._is_sysprep(obj), "Object is not a sysprep"
return (obj.__name__.replace('_', '-'), textwrap.dedent(obj.__doc__))
descr = wrapper.fill(textwrap.dedent(sysprep.__doc__))
self.out.output(' %s:\n%s\n' % (name, descr))
+ def do_sysprep(self):
+ """Prepare system for image creation."""
+
+ try:
+ if not self.mount(readonly=False):
+ raise FatalError("Unable to mount the media read-write")
+
+ self.out.output('Preparing system for image creation:')
+
+ tasks = self.list_syspreps()
+ enabled = filter(lambda x: x.enabled, tasks)
+
+ size = len(enabled)
+ cnt = 0
+ for task in enabled:
+ cnt += 1
+ self.out.output(('(%d/%d)' % (cnt, size)).ljust(7), False)
+ task()
+ setattr(task.im_func, 'executed', True)
+ finally:
+ self.umount()
+
+ self.out.output()
+
+ def mount(self, readonly=False):
+ """Mount image."""
+
+ if getattr(self, "mounted", False):
+ return True
+
+ mount_type = 'read-only' if readonly else 'read-write'
+ self.out.output("Mounting the media %s ..." % mount_type, False)
+
+ if not self._do_mount(readonly):
+ return False
+
+ self.mounted = True
+ self.out.success('done')
+ return True
+
+ def umount(self):
+ """Umount all mounted filesystems."""
+
+ self.out.output("Umounting the media ...", False)
+ self.g.umount_all()
+ self.mounted = False
+ self.out.success('done')
+
+ def _is_sysprep(self, obj):
+ """Checks if an object is a sysprep"""
+ return getattr(obj, 'sysprep', False) and callable(obj)
+
@add_prefix
- def ls(self, directory):
+ def _ls(self, directory):
"""List the name of all files under a directory"""
return self.g.ls(directory)
@add_prefix
- def find(self, directory):
+ def _find(self, directory):
"""List the name of all files recursively under a directory"""
return self.g.find(directory)
- def foreach_file(self, directory, action, **kargs):
+ def _foreach_file(self, directory, action, **kargs):
"""Perform an action recursively on all files under a directory.
The following options are allowed:
continue
if has_ftype(f, 'd'):
- self.foreach_file(full_path, action, **kargs)
+ self._foreach_file(full_path, action, **kargs)
if has_ftype(f, ftype):
action(full_path)
- def do_sysprep(self):
- """Prepere system for image creation."""
-
- try:
- if not self.mount(readonly=False):
- raise FatalError("Unable to mount the media read-write")
-
- self.out.output('Preparing system for image creation:')
-
- tasks = self.list_syspreps()
- enabled = filter(lambda x: x.enabled, tasks)
-
- size = len(enabled)
- cnt = 0
- for task in enabled:
- cnt += 1
- self.out.output(('(%d/%d)' % (cnt, size)).ljust(7), False)
- task()
- setattr(task.im_func, 'executed', True)
- self.out.output()
- finally:
- self.umount()
+ def _do_collect_metadata(self):
+ """helper method for collect_metadata"""
+ self.meta['ROOT_PARTITION'] = "%d" % self.g.part_to_partnum(self.root)
+ self.meta['OSFAMILY'] = self.g.inspect_get_type(self.root)
+ self.meta['OS'] = self.g.inspect_get_distro(self.root)
+ if self.meta['OS'] == "unknown":
+ self.meta['OS'] = self.meta['OSFAMILY']
+ self.meta['DESCRIPTION'] = self.g.inspect_get_product_name(self.root)
def _do_mount(self, readonly):
+ """helper method for mount"""
try:
self.g.mount_options('ro' if readonly else 'rw', self.root, '/')
except RuntimeError as msg:
return True
- def mount(self, readonly=False):
- """Mount image."""
-
- if getattr(self, "mounted", False):
- return True
-
- mount_type = 'read-only' if readonly else 'read-write'
- self.out.output("Mount the media %s ..." % mount_type, False)
-
- if not self._do_mount(readonly):
- return False
-
- self.mounted = True
- self.out.success('done')
- return True
-
- def umount(self):
- """Umount all mounted filesystems."""
- self.g.umount_all()
- self.mounted = False
-
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module hosts OS-specific code for FreeBSD."""
+
from image_creator.os_type.unix import Unix, sysprep
import re
def __init__(self, rootdev, ghandler, output):
super(Freebsd, self).__init__(rootdev, ghandler, output)
- def _do_collect_metadata(self):
+ @sysprep()
+ def cleanup_password(self, print_header=True):
+ """Remove all passwords and lock all user accounts"""
+
+ if print_header:
+ self.out.output("Cleaning up passwords & locking all user "
+ "accounts")
+
+ master_passwd = []
+
+ for line in self.g.cat('/etc/master.passwd').splitlines():
+
+ # Check for empty or comment lines
+ if len(line.split('#')[0]) == 0:
+ master_passwd.append(line)
+ continue
+
+ fields = line.split(':')
+ if fields[1] not in ('*', '!'):
+ fields[1] = '!'
+
+ master_passwd.append(":".join(fields))
+
+ self.g.write('/etc/master.passwd', "\n".join(master_passwd) + '\n')
+
+ # Make sure no one can login on the system
+ self.g.rm_rf('/etc/spwd.db')
+ def _do_collect_metadata(self):
+ """Collect metadata about the OS"""
super(Freebsd, self)._do_collect_metadata()
self.meta["USERS"] = " ".join(self._get_passworded_users())
del self.meta['USERS']
def _get_passworded_users(self):
+ """Returns a list of non-locked user accounts"""
users = []
regexp = re.compile(
'^([^:]+):((?:![^:]+)|(?:[^!*][^:]+)|):(?:[^:]*:){7}(?:[^:]*)'
critical_mpoints = ('/', '/etc', '/root', '/home', '/var')
- # libguestfs can't handle correct freebsd partitions on GUID
- # Partition Table. We have to do the translation to linux
- # device names ourselves
+ # libguestfs can't handle correct freebsd partitions on a GUID
+ # Partition Table. We have to do the translation to linux device names
+ # ourselves
guid_device = re.compile('^/dev/((?:ada)|(?:vtbd))(\d+)p(\d+)$')
mopts = "ufstype=ufs2,%s" % ('ro' if readonly else 'rw')
for mp, dev in self._mountpoints():
match = guid_device.match(dev)
if match:
- m2 = int(match.group(2))
- m3 = int(match.group(3))
- dev = '/dev/sd%c%d' % (chr(ord('a') + m2), m3)
+ group2 = int(match.group(2))
+ group3 = int(match.group(3))
+ dev = '/dev/sd%c%d' % (chr(ord('a') + group2), group3)
try:
self.g.mount_vfs(mopts, 'ufs', dev, mp)
except RuntimeError as msg:
return True
- @sysprep()
- def cleanup_password(self, print_header=True):
- """Remove all passwords and lock all user accounts"""
-
- if print_header:
- self.out.output("Cleaning up passwords & locking all user "
- "accounts")
-
- master_passwd = []
-
- for line in self.g.cat('/etc/master.passwd').splitlines():
-
- # Check for empty or comment lines
- if len(line.split('#')[0]) == 0:
- master_passwd.append(line)
- continue
-
- fields = line.split(':')
- if fields[1] not in ('*', '!'):
- fields[1] = '!'
-
- master_passwd.append(":".join(fields))
-
- self.g.write('/etc/master.passwd', "\n".join(master_passwd) + '\n')
-
- # Make sure no one can login on the system
- self.g.rm_rf('/etc/spwd.db')
-
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module hosts OS-specific code for GNU Hurd."""
+
from image_creator.os_type.unix import Unix
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module hosts OS-specific code for Linux"""
+
from image_creator.os_type.unix import Unix, sysprep
import re
self._uuid = dict()
self._persistent = re.compile('/dev/[hsv]d[a-z][1-9]*')
- def _do_collect_metadata(self):
- """Collect metadata about the OS"""
-
- super(Linux, self)._do_collect_metadata()
- self.meta["USERS"] = " ".join(self._get_passworded_users())
-
- # Delete the USERS metadata if empty
- if not len(self.meta['USERS']):
- self.out.warn("No passworded users found!")
- del self.meta['USERS']
-
- def _get_passworded_users(self):
- users = []
- regexp = re.compile('(\S+):((?:!\S+)|(?:[^!*]\S+)|):(?:\S*:){6}')
-
- for line in self.g.cat('/etc/shadow').splitlines():
- match = regexp.match(line)
- if not match:
- continue
-
- user, passwd = match.groups()
- if len(passwd) > 0 and passwd[0] == '!':
- self.out.warn("Ignoring locked %s account." % user)
- else:
- users.append(user)
-
- return users
-
- def is_persistent(self, dev):
- return not self._persistent.match(dev)
-
- def get_uuid(self, dev):
- if dev in self._uuid:
- return self._uuid[dev]
-
- uuid = self.g.vfs_uuid(dev)
- assert len(uuid)
- self._uuid[dev] = uuid
- return uuid
-
@sysprep(enabled=False)
def remove_user_accounts(self, print_header=True):
"""Remove all user accounts with id greater than 1000"""
event_exp = re.compile('event=(.+)', re.I)
action_exp = re.compile('action=(.+)', re.I)
- for f in self.g.readdir(events_dir):
- if f['ftyp'] != 'r':
+ for events_file in self.g.readdir(events_dir):
+ if events_file['ftyp'] != 'r':
continue
- fullpath = "%s/%s" % (events_dir, f['name'])
+ fullpath = "%s/%s" % (events_dir, events_file['name'])
event = ""
action = ""
for line in self.g.cat(fullpath).splitlines():
- m = event_exp.match(line)
- if m:
- event = m.group(1)
+ match = event_exp.match(line)
+ if match:
+ event = match.group(1)
continue
- m = action_exp.match(line)
- if m:
- action = m.group(1)
+ match = action_exp.match(line)
+ if match:
+ action = match.group(1)
continue
if event.strip() in ("button[ /]power", "button/power.*"):
self._persistent_grub1(persistent_root)
def _persistent_grub1(self, new_root):
+ """Replaces non-persistent device name occurencies with persistent
+ ones in GRUB1 configuration files.
+ """
if self.g.is_file('/boot/grub/menu.lst'):
grub1 = '/boot/grub/menu.lst'
elif self.g.is_file('/etc/grub.conf'):
roots = self.g.aug_match('/files%s/title[*]/kernel/root' % grub1)
for root in roots:
dev = self.g.aug_get(root)
- if not self.is_persistent(dev):
+ if not self._is_persistent(dev):
# This is not always correct. Grub may contain root entries
# for other systems, but we only support 1 OS per hard
# disk, so this shouldn't harm.
self.g.aug_close()
def _persistent_fstab(self):
+ """Replaces non-persistent device name occurencies in /etc/fstab with
+ persistent ones.
+ """
mpoints = self.g.mountpoints()
if len(mpoints) == 0:
pass # TODO: error handling
return root_dev
def _convert_fstab_line(self, line, devices):
+ """Replace non-persistent device names in an fstab line to their UUID
+ equivalent
+ """
orig = line
line = line.split('#')[0].strip()
if len(line) == 0:
dev = entry[0]
mpoint = entry[1]
- if not self.is_persistent(dev):
+ if not self._is_persistent(dev):
if mpoint in devices:
- dev = "UUID=%s" % self.get_uuid(devices[mpoint])
+ dev = "UUID=%s" % self._get_uuid(devices[mpoint])
entry[0] = dev
else:
# comment out the entry
return orig, dev, mpoint
+ def _do_collect_metadata(self):
+ """Collect metadata about the OS"""
+ super(Linux, self)._do_collect_metadata()
+ self.meta["USERS"] = " ".join(self._get_passworded_users())
+
+ # Delete the USERS metadata if empty
+ if not len(self.meta['USERS']):
+ self.out.warn("No passworded users found!")
+ del self.meta['USERS']
+
+ def _get_passworded_users(self):
+ """Returns a list of non-locked user accounts"""
+ users = []
+ regexp = re.compile('(\S+):((?:!\S+)|(?:[^!*]\S+)|):(?:\S*:){6}')
+
+ for line in self.g.cat('/etc/shadow').splitlines():
+ match = regexp.match(line)
+ if not match:
+ continue
+
+ user, passwd = match.groups()
+ if len(passwd) > 0 and passwd[0] == '!':
+ self.out.warn("Ignoring locked %s account." % user)
+ else:
+ users.append(user)
+
+ return users
+
+ def _is_persistent(self, dev):
+ """Checks if a device name is persistent."""
+ return not self._persistent.match(dev)
+
+ def _get_uuid(self, dev):
+ """Returns the UUID corresponding to a device"""
+ if dev in self._uuid:
+ return self._uuid[dev]
+
+ uuid = self.g.vfs_uuid(dev)
+ assert len(uuid)
+ self._uuid[dev] = uuid
+ return uuid
+
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module hosts OS-specific code for NetBSD."""
+
from image_creator.os_type.unix import Unix
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module hosts OS-specific code for Slackware Linux"""
+
from image_creator.os_type.linux import Linux, sysprep
# In slackware the metadata about installed packages are
# stored in /var/log/packages. Clearing all /var/log files
# will destroy the package management system.
- self.foreach_file('/var/log', self.g.truncate, ftype='r',
- exclude='/var/log/packages')
+ self._foreach_file('/var/log', self.g.truncate, ftype='r',
+ exclude='/var/log/packages')
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module hosts OS-specific code for Ubuntu Linux"""
+
from image_creator.os_type.linux import Linux
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module hosts OS-specific code common to all Unix-like OSs."""
+
import re
from image_creator.os_type import OSBase, sysprep
try:
self.g.mount_options(mopts, dev, mp)
except RuntimeError as msg:
- if mp in critical_mpoint:
+ if mp in critical_mpoints:
self.out.warn('unable to mount %s. Reason: %s' % (mp, msg))
return False
else:
if print_header:
self.out.output('Removing files under /var/cache')
- self.foreach_file('/var/cache', self.g.rm, ftype='r')
+ self._foreach_file('/var/cache', self.g.rm, ftype='r')
@sysprep()
def cleanup_tmp(self, print_header=True):
if print_header:
self.out.output('Removing files under /tmp and /var/tmp')
- self.foreach_file('/tmp', self.g.rm_rf, maxdepth=1)
- self.foreach_file('/var/tmp', self.g.rm_rf, maxdepth=1)
+ self._foreach_file('/tmp', self.g.rm_rf, maxdepth=1)
+ self._foreach_file('/var/tmp', self.g.rm_rf, maxdepth=1)
@sysprep()
def cleanup_log(self, print_header=True):
if print_header:
self.out.output('Emptying all files under /var/log')
- self.foreach_file('/var/log', self.g.truncate, ftype='r')
+ self._foreach_file('/var/log', self.g.truncate, ftype='r')
@sysprep(enabled=False)
def cleanup_mail(self, print_header=True):
self.out.output('Removing files under /var/mail & /var/spool/mail')
if self.g.is_dir('/var/spool/mail'):
- self.foreach_file('/var/spool/mail', self.g.rm_rf, maxdepth=1)
+ self._foreach_file('/var/spool/mail', self.g.rm_rf, maxdepth=1)
- self.foreach_file('/var/mail', self.g.rm_rf, maxdepth=1)
+ self._foreach_file('/var/mail', self.g.rm_rf, maxdepth=1)
@sysprep()
def cleanup_userdata(self, print_header=True):
homedirs = ['/root']
if self.g.is_dir('/home/'):
- homedirs += self.ls('/home/')
+ homedirs += self._ls('/home/')
if print_header:
self.out.output("Removing sensitive user data under %s" %
if self.g.is_file(fname):
self.g.scrub_file(fname)
elif self.g.is_dir(fname):
- self.foreach_file(fname, self.g.scrub_file, ftype='r')
+ self._foreach_file(fname, self.g.scrub_file, ftype='r')
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module hosts OS-specific code common for the various Microsoft
+Windows OSs."""
+
from image_creator.os_type import OSBase
import hivex
self.meta["USERS"] = " ".join(self._get_users())
def _get_users(self):
+ """Returns a list of users found in the images"""
samfd, sam = tempfile.mkstemp()
try:
systemroot = self.g.inspect_get_windows_systemroot(self.root)
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This package is intended to provide output classes for printing messages and
+progress bars. The user can change the output behaviour of the program by
+subclassing the Output class and assigning the derived one as the output class
+of the various parts of the image-creator package.
+"""
+
class Output(object):
"""A class for printing program output"""
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
def clear(stream):
- #clear the page
+ """Clears the terminal screen."""
if stream.isatty():
stream.write('\033[H\033[2J')
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module implements the CompositeOutput output class"""
+
from image_creator.output import Output
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module provides various dialog-based Output classes"""
+
from image_creator.output import Output
import time
import fcntl
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module provides an interface for the rsync utility"""
+
import subprocess
import time
import signal
stdout=subprocess.PIPE, bufsize=0)
try:
total = 0
- for line in iter(dry_run.stdout.readline, b''):
+ for _ in iter(dry_run.stdout.readline, b''):
total += 1
finally:
dry_run.communicate()
try:
t = time.time()
i = 0
- for line in iter(run.stdout.readline, b''):
+ for _ in iter(run.stdout.readline, b''):
i += 1
current = time.time()
if current - t > 0.1:
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
+"""This module provides various helper functions to be used by other parts of
+the package.
+"""
+
import sh
import hashlib
import time
#!/usr/bin/env python
-
+# -*- coding: utf-8 -*-
+#
# Copyright 2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or