From 738ba47c6557aad7de04f754d0f53cb8f036c068 Mon Sep 17 00:00:00 2001 From: Anders Ingemann Date: Sun, 22 Sep 2013 17:31:43 +0200 Subject: [PATCH] Add references instead of instances to the tasklist --- base/task.py | 20 ----- base/tasklist.py | 37 ++++++---- plugins/admin_user/__init__.py | 10 +-- plugins/backports/__init__.py | 4 +- plugins/build_metadata/__init__.py | 2 +- plugins/convert_image/__init__.py | 2 +- plugins/opennebula/__init__.py | 2 +- plugins/prebootstrapped/__init__.py | 10 +-- plugins/root_password/__init__.py | 2 +- plugins/unattended_upgrades/__init__.py | 4 +- plugins/user_packages/__init__.py | 4 +- providers/virtualbox/__init__.py | 98 ++++++++++++------------- 12 files changed, 93 insertions(+), 102 deletions(-) diff --git a/base/task.py b/base/task.py index c3841a6..8a10462 100644 --- a/base/task.py +++ b/base/task.py @@ -1,4 +1,3 @@ -from common.exceptions import TaskListError class Task(object): @@ -6,27 +5,8 @@ class Task(object): before = [] after = [] - def __init__(self): - self._check_ordering() - def __str__(self): return '{module}.{task}'.format(module=self.__module__, task=self.__class__.__name__) def __repr__(self): return self.__str__() - - def _check_ordering(self): - def name(ref): - return '{module}.{task}'.format(module=ref.__module__, task=ref.__class__.__name__) - for task in self.before: - if self.phase > task.phase: - msg = ("The task {self} is specified as running before {other}, " - "but its phase '{phase}' lies after the phase '{other_phase}'" - .format(self=type(self), other=task, phase=self.phase, other_phase=task.phase)) - raise TaskListError(msg) - for task in self.after: - if self.phase < task.phase: - msg = ("The task {self} is specified as running after {other}, " - "but its phase '{phase}' lies before the phase '{other_phase}'" - .format(self=type(self), other=task, phase=self.phase, other_phase=task.phase)) - raise TaskListError(msg) diff --git a/base/tasklist.py b/base/tasklist.py index d786abd..68b1427 100644 --- a/base/tasklist.py +++ b/base/tasklist.py @@ -13,23 +13,19 @@ class TaskList(object): self.tasks.update(args) def remove(self, *args): - for task_type in args: - task = self.get(task_type) - if task is not None: - self.tasks.discard(task) + for task in args: + self.tasks.discard(task) def replace(self, task, replacement): self.remove(task) self.add(replacement) - def get(self, ref): - return next((task for task in self.tasks if type(task) is ref), None) - def run(self, bootstrap_info): task_list = self.create_list(self.tasks) log.debug('Tasklist:\n\t{list}'.format(list='\n\t'.join(repr(task) for task in task_list))) - for task in task_list: + for task_type in task_list: + task = task_type() if hasattr(task, 'description'): log.info(task.description) else: @@ -41,12 +37,13 @@ class TaskList(object): from common.phases import order graph = {} for task in tasks: - successors = [] - successors.extend([self.get(succ) for succ in task.before]) - successors.extend(filter(lambda succ: type(task) in succ.after, tasks)) + self.check_ordering(task) + successors = set() + successors.update(task.before) + successors.update(filter(lambda succ: task in succ.after, tasks)) succeeding_phases = order[order.index(task.phase) + 1:] - successors.extend(filter(lambda succ: succ.phase in succeeding_phases, tasks)) - graph[task] = filter(lambda succ: succ in self.tasks, successors) + successors.update(filter(lambda succ: succ.phase in succeeding_phases, tasks)) + graph[task] = filter(lambda succ: succ in tasks, successors) components = self.strongly_connected_components(graph) cycles_found = 0 @@ -63,6 +60,20 @@ class TaskList(object): return sorted_tasks + def check_ordering(self, task): + for successor in task.before: + if successor.phase > successor.phase: + msg = ("The task {task} is specified as running before {other}, " + "but its phase '{phase}' lies after the phase '{other_phase}'" + .format(task=task, other=successor, phase=task.phase, other_phase=successor.phase)) + raise TaskListError(msg) + for predecessor in task.after: + if task.phase < predecessor.phase: + msg = ("The task {task} is specified as running after {other}, " + "but its phase '{phase}' lies before the phase '{other_phase}'" + .format(task=task, other=predecessor, phase=task.phase, other_phase=predecessor.phase)) + raise TaskListError(msg) + def strongly_connected_components(self, graph): # Source: http://www.logarithmic.net/pfh-files/blog/01208083168/sort.py # Find the strongly connected components in a graph using Tarjan's algorithm. diff --git a/plugins/admin_user/__init__.py b/plugins/admin_user/__init__.py index 8c396c9..2916bd0 100644 --- a/plugins/admin_user/__init__.py +++ b/plugins/admin_user/__init__.py @@ -2,11 +2,11 @@ def tasks(tasklist, manifest): import tasks - tasklist.add(tasks.AddSudoPackage()) - tasklist.add(tasks.CreateAdminUser()) - tasklist.add(tasks.PasswordlessSudo()) - tasklist.add(tasks.AdminUserCredentials()) - tasklist.add(tasks.DisableRootLogin()) + tasklist.add(tasks.AddSudoPackage. + tasks.CreateAdminUser, + tasks.PasswordlessSudo, + tasks.AdminUserCredentials, + tasks.DisableRootLogin) def validate_manifest(data, schema_validate): diff --git a/plugins/backports/__init__.py b/plugins/backports/__init__.py index bdeae13..834c2d8 100644 --- a/plugins/backports/__init__.py +++ b/plugins/backports/__init__.py @@ -2,8 +2,8 @@ def tasks(tasklist, manifest): import tasks - tasklist.add(tasks.AptSourcesBackports()) - tasklist.add(tasks.AddBackportsPackages()) + tasklist.add(tasks.AptSourcesBackports, + tasks.AddBackportsPackages) def validate_manifest(data, schema_validate): diff --git a/plugins/build_metadata/__init__.py b/plugins/build_metadata/__init__.py index a8db8ba..71d1abf 100644 --- a/plugins/build_metadata/__init__.py +++ b/plugins/build_metadata/__init__.py @@ -2,4 +2,4 @@ def tasks(tasklist, manifest): from tasks import WriteMetadata - tasklist.add(WriteMetadata()) + tasklist.add(WriteMetadata diff --git a/plugins/convert_image/__init__.py b/plugins/convert_image/__init__.py index a36d8f4..f37792b 100644 --- a/plugins/convert_image/__init__.py +++ b/plugins/convert_image/__init__.py @@ -2,7 +2,7 @@ def tasks(tasklist, manifest): from tasks import ConvertImage - tasklist.add(ConvertImage()) + tasklist.add(ConvertImage) def validate_manifest(data, schema_validate): diff --git a/plugins/opennebula/__init__.py b/plugins/opennebula/__init__.py index a9ae730..6ffcec9 100644 --- a/plugins/opennebula/__init__.py +++ b/plugins/opennebula/__init__.py @@ -2,4 +2,4 @@ def tasks(tasklist, manifest): import tasks - tasklist.add(tasks.OpenNebulaContext()) + tasklist.add(tasks.OpenNebulaContext) diff --git a/plugins/prebootstrapped/__init__.py b/plugins/prebootstrapped/__init__.py index dc258a7..ff6aec9 100644 --- a/plugins/prebootstrapped/__init__.py +++ b/plugins/prebootstrapped/__init__.py @@ -21,16 +21,16 @@ def tasks(tasklist, manifest): bootstrap.Bootstrap] if manifest.volume['backing'] == 'ebs': if 'snapshot' in settings and settings['snapshot'] is not None: - tasklist.replace(ebs.Create, CreateFromSnapshot()) + tasklist.replace(ebs.Create, CreateFromSnapshot) tasklist.remove(*skip_tasks) else: - tasklist.add(Snapshot()) + tasklist.add(Snapshot) else: if 'image' in settings and settings['image'] is not None: - tasklist.replace(loopback.Create, CreateFromImage()) + tasklist.replace(loopback.Create, CreateFromImage) tasklist.remove(*skip_tasks) else: - tasklist.add(CopyImage()) + tasklist.add(CopyImage) def rollback_tasks(tasklist, tasks_completed, manifest): @@ -38,7 +38,7 @@ def rollback_tasks(tasklist, tasks_completed, manifest): def counter_task(task, counter): if task in completed and counter not in completed: - tasklist.add(counter()) + tasklist.add(counter) if manifest.volume['backing'] == 'ebs': counter_task(CreateFromSnapshot, volume.Delete) diff --git a/plugins/root_password/__init__.py b/plugins/root_password/__init__.py index f3d4e87..34b1248 100644 --- a/plugins/root_password/__init__.py +++ b/plugins/root_password/__init__.py @@ -3,7 +3,7 @@ def tasks(tasklist, manifest): from common.tasks.security import DisableSSHPasswordAuthentication from tasks import SetRootPassword - tasklist.replace(DisableSSHPasswordAuthentication, SetRootPassword()) + tasklist.replace(DisableSSHPasswordAuthentication, SetRootPassword) def validate_manifest(data, schema_validate): diff --git a/plugins/unattended_upgrades/__init__.py b/plugins/unattended_upgrades/__init__.py index aa1d239..8025744 100644 --- a/plugins/unattended_upgrades/__init__.py +++ b/plugins/unattended_upgrades/__init__.py @@ -2,8 +2,8 @@ def tasks(tasklist, manifest): import tasks - tasklist.add(tasks.AddUnattendedUpgradesPackage()) - tasklist.add(tasks.EnablePeriodicUpgrades()) + tasklist.add(tasks.AddUnattendedUpgradesPackage, + tasks.EnablePeriodicUpgrades) def validate_manifest(data, schema_validate): diff --git a/plugins/user_packages/__init__.py b/plugins/user_packages/__init__.py index e223e0a..218975c 100644 --- a/plugins/user_packages/__init__.py +++ b/plugins/user_packages/__init__.py @@ -2,5 +2,5 @@ def tasks(tasklist, manifest): from user_packages import AddUserPackages, AddLocalUserPackages - tasklist.add(AddUserPackages()) - tasklist.add(AddLocalUserPackages()) + tasklist.add(AddUserPackages, + AddLocalUserPackages) diff --git a/providers/virtualbox/__init__.py b/providers/virtualbox/__init__.py index 0eb7475..4d095b2 100644 --- a/providers/virtualbox/__init__.py +++ b/providers/virtualbox/__init__.py @@ -23,54 +23,54 @@ def initialize(): def tasks(tasklist, manifest): - tasklist.add(workspace.CreateWorkspace(), - packages.HostPackages(), - common_packages.HostPackages(), - packages.ImagePackages(), - common_packages.ImagePackages(), - host.CheckPackages(), + tasklist.add(workspace.CreateWorkspace, + packages.HostPackages, + common_packages.HostPackages, + packages.ImagePackages, + common_packages.ImagePackages, + host.CheckPackages, - loopback.Create(), - volume_tasks.Attach(), - partitioning.PartitionVolume(), - partitioning.MapPartitions(), - filesystem.Format(), - filesystem.CreateMountDir(), - filesystem.MountRoot(), + loopback.Create, + volume_tasks.Attach, + partitioning.PartitionVolume, + partitioning.MapPartitions, + filesystem.Format, + filesystem.CreateMountDir, + filesystem.MountRoot, - bootstrap.Bootstrap(), - filesystem.MountSpecials(), - locale.GenerateLocale(), - locale.SetTimezone(), - apt.DisableDaemonAutostart(), - apt.AptSources(), - apt.AptUpgrade(), - boot.ConfigureGrub(), - filesystem.FStab(), - common_boot.BlackListModules(), - common_boot.DisableGetTTYs(), - security.EnableShadowConfig(), - network.RemoveDNSInfo(), - network.ConfigureNetworkIF(), - network.RemoveHostname(), - initd.ResolveInitScripts(), - initd.InstallInitScripts(), - cleanup.ClearMOTD(), - cleanup.CleanTMP(), - apt.PurgeUnusedPackages(), - apt.AptClean(), - apt.EnableDaemonAutostart(), - filesystem.UnmountSpecials(), + bootstrap.Bootstrap, + filesystem.MountSpecials, + locale.GenerateLocale, + locale.SetTimezone, + apt.DisableDaemonAutostart, + apt.AptSources, + apt.AptUpgrade, + boot.ConfigureGrub, + filesystem.FStab, + common_boot.BlackListModules, + common_boot.DisableGetTTYs, + security.EnableShadowConfig, + network.RemoveDNSInfo, + network.ConfigureNetworkIF, + network.RemoveHostname, + initd.ResolveInitScripts, + initd.InstallInitScripts, + cleanup.ClearMOTD, + cleanup.CleanTMP, + apt.PurgeUnusedPackages, + apt.AptClean, + apt.EnableDaemonAutostart, + filesystem.UnmountSpecials, - filesystem.UnmountRoot(), - partitioning.UnmapPartitions(), - volume_tasks.Detach(), - filesystem.DeleteMountDir(), - loopback.MoveImage(), - workspace.DeleteWorkspace()) + filesystem.UnmountRoot, + partitioning.UnmapPartitions, + volume_tasks.Detach, + filesystem.DeleteMountDir, + loopback.MoveImage, + workspace.DeleteWorkspace) if manifest.bootstrapper.get('tarball', False): - tasklist.add(bootstrap.MakeTarball()) + tasklist.add(bootstrap.MakeTarball) partitions = manifest.volume['partitions'] import re @@ -78,19 +78,19 @@ def tasks(tasklist, manifest): if key not in partitions: continue if re.match('^ext[2-4]$', partitions[key]['filesystem']) is not None: - tasklist.add(filesystem.TuneVolumeFS()) + tasklist.add(filesystem.TuneVolumeFS) break for key in ['boot', 'root']: if key not in partitions: continue if partitions[key]['filesystem'] == 'xfs': - tasklist.add(filesystem.AddXFSProgs()) + tasklist.add(filesystem.AddXFSProgs) break if 'boot' in manifest.volume['partitions']: - tasklist.add(filesystem.CreateBootMountDir(), - filesystem.MountBoot(), - filesystem.UnmountBoot()) + tasklist.add(filesystem.CreateBootMountDir, + filesystem.MountBoot, + filesystem.UnmountBoot) def rollback_tasks(tasklist, tasks_completed, manifest): @@ -98,7 +98,7 @@ def rollback_tasks(tasklist, tasks_completed, manifest): def counter_task(task, counter): if task in completed and counter not in completed: - tasklist.add(counter()) + tasklist.add(counter) counter_task(loopback.Create, volume_tasks.Delete) counter_task(filesystem.CreateMountDir, filesystem.DeleteMountDir)