Since all sysprep functions output a message when they get executed,
add the message printing functionality to the sysprep decorator
import textwrap
import re
from collections import namedtuple
import textwrap
import re
from collections import namedtuple
+from functools import wraps
def os_cls(distro, osfamily):
def os_cls(distro, osfamily):
-def sysprep(enabled=True):
+def sysprep(message, enabled=True):
"""Decorator for system preparation tasks"""
"""Decorator for system preparation tasks"""
func.sysprep = True
func.enabled = enabled
func.executed = False
func.sysprep = True
func.enabled = enabled
func.executed = False
- return func
- return wrapper
+
+ @wraps(func)
+ def wrapper2(self, print_message=True):
+ if print_message:
+ self.out.output(message)
+ return func(self)
+
+ return wrapper2
+
+ return wrapper1
class Freebsd(Unix):
"""OS class for FreeBSD Unix-like os"""
class Freebsd(Unix):
"""OS class for FreeBSD Unix-like os"""
- @sysprep()
- def cleanup_password(self, print_header=True):
+ @sysprep("Cleaning up passwords & locking all user accounts")
+ def cleanup_password(self):
"""Remove all passwords and lock all user accounts"""
"""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():
master_passwd = []
for line in self.g.cat('/etc/master.passwd').splitlines():
self._uuid = dict()
self._persistent = re.compile('/dev/[hsv]d[a-z][1-9]*')
self._uuid = dict()
self._persistent = re.compile('/dev/[hsv]d[a-z][1-9]*')
- @sysprep(enabled=False)
- def remove_user_accounts(self, print_header=True):
+ @sysprep('Removing user accounts with id greater that 1000', enabled=False)
+ def remove_user_accounts(self):
"""Remove all user accounts with id greater than 1000"""
"""Remove all user accounts with id greater than 1000"""
- if print_header:
- self.out.output("Removing all user accounts with id greater than "
- "1000")
-
if 'USERS' not in self.meta:
return
if 'USERS' not in self.meta:
return
if self.g.is_dir(home) and home.startswith('/home/'):
self.g.rm_rf(home)
if self.g.is_dir(home) and home.startswith('/home/'):
self.g.rm_rf(home)
- @sysprep()
- def cleanup_passwords(self, print_header=True):
+ @sysprep('Cleaning up password & locking all user accounts')
+ def cleanup_passwords(self):
"""Remove all passwords and lock all user accounts"""
"""Remove all passwords and lock all user accounts"""
- if print_header:
- self.out.output("Cleaning up passwords & locking all user "
- "accounts")
-
shadow = []
for line in self.g.cat('/etc/shadow').splitlines():
shadow = []
for line in self.g.cat('/etc/shadow').splitlines():
self.g.write('/etc/shadow', "\n".join(shadow) + '\n')
self.g.write('/etc/shadow', "\n".join(shadow) + '\n')
- @sysprep()
- def fix_acpid(self, print_header=True):
+ @sysprep('Fixing acpid powerdown action')
+ def fix_acpid(self):
"""Replace acpid powerdown action scripts to immediately shutdown the
system without checking if a GUI is running.
"""
"""Replace acpid powerdown action scripts to immediately shutdown the
system without checking if a GUI is running.
"""
- if print_header:
- self.out.output('Fixing acpid powerdown action')
-
powerbtn_action = '#!/bin/sh\n\nPATH=/sbin:/bin:/usr/bin\n' \
'shutdown -h now "Power button pressed"\n'
powerbtn_action = '#!/bin/sh\n\nPATH=/sbin:/bin:/usr/bin\n' \
'shutdown -h now "Power button pressed"\n'
self.out.warn("No acpi power button event found!")
self.out.warn("No acpi power button event found!")
- @sysprep()
- def remove_persistent_net_rules(self, print_header=True):
+ @sysprep('Removing persistent network interface names')
+ def remove_persistent_net_rules(self):
"""Remove udev rules that will keep network interface names persistent
after hardware changes and reboots. Those rules will be created again
the next time the image runs.
"""
"""Remove udev rules that will keep network interface names persistent
after hardware changes and reboots. Those rules will be created again
the next time the image runs.
"""
- if print_header:
- self.out.output('Removing persistent network interface names')
-
rule_file = '/etc/udev/rules.d/70-persistent-net.rules'
if self.g.is_file(rule_file):
self.g.rm(rule_file)
rule_file = '/etc/udev/rules.d/70-persistent-net.rules'
if self.g.is_file(rule_file):
self.g.rm(rule_file)
- @sysprep()
- def remove_swap_entry(self, print_header=True):
+ @sysprep('Removing swap entry from fstab')
+ def remove_swap_entry(self):
"""Remove swap entry from /etc/fstab. If swap is the last partition
then the partition will be removed when shrinking is performed. If the
swap partition is not the last partition in the disk or if you are not
going to shrink the image you should probably disable this.
"""
"""Remove swap entry from /etc/fstab. If swap is the last partition
then the partition will be removed when shrinking is performed. If the
swap partition is not the last partition in the disk or if you are not
going to shrink the image you should probably disable this.
"""
- if print_header:
- self.out.output('Removing swap entry from fstab')
-
new_fstab = ""
fstab = self.g.cat('/etc/fstab')
for line in fstab.splitlines():
new_fstab = ""
fstab = self.g.cat('/etc/fstab')
for line in fstab.splitlines():
self.g.write('/etc/fstab', new_fstab)
self.g.write('/etc/fstab', new_fstab)
- @sysprep()
- def use_persistent_block_device_names(self, print_header=True):
+ @sysprep('Replacing fstab & grub non-persistent device references')
+ def use_persistent_block_device_names(self):
"""Scan fstab & grub configuration files and replace all non-persistent
device references with UUIDs.
"""
"""Scan fstab & grub configuration files and replace all non-persistent
device references with UUIDs.
"""
- if print_header:
- self.out.output("Replacing fstab & grub non-persistent device "
- "references")
-
# convert all devices in fstab to persistent
persistent_root = self._persistent_fstab()
# convert all devices in fstab to persistent
persistent_root = self._persistent_fstab()
class Slackware(Linux):
"""OS class for Slackware Linux"""
class Slackware(Linux):
"""OS class for Slackware Linux"""
- @sysprep()
- def cleanup_log(self, print_header=True):
+ @sysprep("Emptying all files under /var/log")
+ def cleanup_log(self):
"""Empty all files under /var/log"""
"""Empty all files under /var/log"""
- if print_header:
- self.out.output('Emptying all files under /var/log')
-
# In slackware the metadata about installed packages are
# stored in /var/log/packages. Clearing all /var/log files
# will destroy the package management system.
# In slackware the metadata about installed packages are
# stored in /var/log/packages. Clearing all /var/log files
# will destroy the package management system.
- @sysprep()
- def cleanup_cache(self, print_header=True):
+ @sysprep('Removing files u)nder /var/cache')
+ def cleanup_cache(self):
"""Remove all regular files under /var/cache"""
"""Remove all regular files under /var/cache"""
- 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):
+ @sysprep('Removing files under /tmp and /var/tmp')
+ def cleanup_tmp(self):
"""Remove all files under /tmp and /var/tmp"""
"""Remove all files under /tmp and /var/tmp"""
- 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):
+ @sysprep('Emptying all files under /var/log')
+ def cleanup_log(self):
"""Empty all files under /var/log"""
"""Empty all files under /var/log"""
- 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):
+ @sysprep('Removing files under /var/mail & /var/spool/mail', enabled=False)
+ def cleanup_mail(self):
"""Remove all files under /var/mail and /var/spool/mail"""
"""Remove all files under /var/mail and /var/spool/mail"""
- if print_header:
- 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/mail', self.g.rm_rf, maxdepth=1)
if self.g.is_dir('/var/spool/mail'):
self._foreach_file('/var/spool/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):
+ @sysprep('Removing sensitive user data')
+ def cleanup_userdata(self):
"""Delete sensitive userdata"""
homedirs = ['/root']
if self.g.is_dir('/home/'):
homedirs += self._ls('/home/')
"""Delete sensitive userdata"""
homedirs = ['/root']
if self.g.is_dir('/home/'):
homedirs += self._ls('/home/')
- if print_header:
- self.out.output("Removing sensitive user data under %s" %
- " ".join(homedirs))
-
for homedir in homedirs:
for data in self.sensitive_userdata:
fname = "%s/%s" % (homedir, data)
for homedir in homedirs:
for data in self.sensitive_userdata:
fname = "%s/%s" % (homedir, data)
- @sysprep(enabled=True)
- def disable_ipv6_privacy_extensions(self, print_header=True):
+ @sysprep('Disabling IPv6 privacy extensions')
+ def disable_ipv6_privacy_extensions(self):
"""Disable IPv6 privacy extensions"""
"""Disable IPv6 privacy extensions"""
- if print_header:
- self.out.output("Disabling IPv6 privacy extensions")
-
self._guest_exec('netsh interface ipv6 set global '
'randomizeidentifiers=disabled store=persistent')
self._guest_exec('netsh interface ipv6 set global '
'randomizeidentifiers=disabled store=persistent')
- @sysprep(enabled=True)
- def microsoft_sysprep(self, print_header=True):
+ @sysprep('Executing sysprep on the image (may take more that 10 minutes)')
+ def microsoft_sysprep(self):
"""Run the Microsoft System Preparation Tool on the Image. This will
remove system-specific data and will make the image ready to be
deployed. After this no other task may run.
"""
"""Run the Microsoft System Preparation Tool on the Image. This will
remove system-specific data and will make the image ready to be
deployed. After this no other task may run.
"""
- if print_header:
- self.out.output("Executing sysprep on the image (may take more "
- "than 10 minutes)")
-
self._guest_exec(r'C:\Windows\system32\sysprep\sysprep '
r'/quiet /generalize /oobe /shutdown')
self.syspreped = True
self._guest_exec(r'C:\Windows\system32\sysprep\sysprep '
r'/quiet /generalize /oobe /shutdown')
self.syspreped = True