From f4ecac900f95bd1f5085cffeafaafb9fbed6449f Mon Sep 17 00:00:00 2001 From: Olivier Sallou Date: Thu, 30 Jan 2014 11:44:26 +0100 Subject: [PATCH] add KVM provider with virtio support --- manifests/kvm-virtio.manifest.json | 42 +++++++++++++++++ manifests/kvm.manifest.json | 41 ++++++++++++++++ providers/kvm/README.md | 14 ++++++ providers/kvm/__init__.py | 75 ++++++++++++++++++++++++++++++ providers/kvm/manifest-schema.json | 44 ++++++++++++++++++ providers/kvm/tasks/__init__.py | 0 providers/kvm/tasks/packages.py | 16 +++++++ providers/kvm/tasks/virtio.py | 19 ++++++++ 8 files changed, 251 insertions(+) create mode 100644 manifests/kvm-virtio.manifest.json create mode 100644 manifests/kvm.manifest.json create mode 100644 providers/kvm/README.md create mode 100644 providers/kvm/__init__.py create mode 100644 providers/kvm/manifest-schema.json create mode 100644 providers/kvm/tasks/__init__.py create mode 100644 providers/kvm/tasks/packages.py create mode 100644 providers/kvm/tasks/virtio.py diff --git a/manifests/kvm-virtio.manifest.json b/manifests/kvm-virtio.manifest.json new file mode 100644 index 0000000..689ad4a --- /dev/null +++ b/manifests/kvm-virtio.manifest.json @@ -0,0 +1,42 @@ +{ + "provider": "kvm", + "bootstrapper": { + "workspace": "/target", + "mirror": "http://ftp.fr.debian.org/debian/", + "virtio" : [ "virtio_pci", "virtio_blk" ] + }, + "image": { + "name": "debian-{system.release}-{system.architecture}-{%y}{%m}{%d}", + "description": "Debian {system.release} {system.architecture}" + }, + "system": { + "release": "wheezy", + "architecture": "amd64", + "bootloader": "grub", + "timezone": "UTC", + "locale": "en_US", + "charmap": "UTF-8" + }, + "packages": {}, + "volume": { + "backing": "raw", + "partitions": { + "type": "msdos", + "boot": { + "size": "32MiB", + "filesystem": "ext2" + }, + "root": { + "size": "864MiB", + "filesystem": "ext4" + }, + "swap": {"size": "128MiB"} + } + }, + "plugins": { + "root_password": { + "enabled": true, + "password": "test" + } + } +} diff --git a/manifests/kvm.manifest.json b/manifests/kvm.manifest.json new file mode 100644 index 0000000..2d3ea69 --- /dev/null +++ b/manifests/kvm.manifest.json @@ -0,0 +1,41 @@ +{ + "provider": "kvm", + "bootstrapper": { + "workspace": "/target", + "mirror": "http://ftp.fr.debian.org/debian/" + }, + "image": { + "name": "debian-{system.release}-{system.architecture}-{%y}{%m}{%d}", + "description": "Debian {system.release} {system.architecture}" + }, + "system": { + "release": "wheezy", + "architecture": "amd64", + "bootloader": "grub", + "timezone": "UTC", + "locale": "en_US", + "charmap": "UTF-8" + }, + "packages": {}, + "volume": { + "backing": "raw", + "partitions": { + "type": "msdos", + "boot": { + "size": "32MiB", + "filesystem": "ext2" + }, + "root": { + "size": "864MiB", + "filesystem": "ext4" + }, + "swap": {"size": "128MiB"} + } + }, + "plugins": { + "root_password": { + "enabled": true, + "password": "test" + } + } +} diff --git a/providers/kvm/README.md b/providers/kvm/README.md new file mode 100644 index 0000000..e8b4439 --- /dev/null +++ b/providers/kvm/README.md @@ -0,0 +1,14 @@ +KVM provider +=========== + +This provider generates raw images for KVM. +It also supports an optional virtio integration. + + +Virtio +====== + +Add to bootstrapper the list of virtio modules to load, example: + + "virtio" : [ "virtio_pci", "virtio_blk" ] + diff --git a/providers/kvm/__init__.py b/providers/kvm/__init__.py new file mode 100644 index 0000000..a0fe7b3 --- /dev/null +++ b/providers/kvm/__init__.py @@ -0,0 +1,75 @@ +import tasks.packages +from common.tasks import volume +from common.tasks import loopback +from common.tasks import partitioning +from common.tasks import filesystem +from common.tasks import bootstrap +from common.tasks import security +from common.tasks import network +from common.tasks import initd +from common.tasks import cleanup +from common.tasks import workspace + + +def initialize(): + pass + + +def validate_manifest(data, validator, error): + import os.path + schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.json')) + validator(data, schema_path) + + if data['volume']['partitions']['type'] == 'none' and data['system']['bootloader'] != 'extlinux': + error('Only extlinux can boot from unpartitioned disks', ['system', 'bootloader']) + + +def resolve_tasks(tasklist, manifest): + import common.task_sets + tasklist.update(common.task_sets.base_set) + tasklist.update(common.task_sets.volume_set) + tasklist.update(common.task_sets.mounting_set) + tasklist.update(common.task_sets.get_apt_set(manifest)) + tasklist.update(common.task_sets.locale_set) + + tasklist.update(common.task_sets.bootloader_set.get(manifest.system['bootloader'])) + + if manifest.volume['partitions']['type'] != 'none': + tasklist.update(common.task_sets.partitioning_set) + + tasklist.update([tasks.packages.DefaultPackages, + + loopback.Create, + + security.EnableShadowConfig, + network.RemoveDNSInfo, + network.ConfigureNetworkIF, + network.RemoveHostname, + initd.AddSSHKeyGeneration, + initd.InstallInitScripts, + cleanup.ClearMOTD, + cleanup.CleanTMP, + + loopback.MoveImage, + ]) + + if manifest.bootstrapper.get('tarball', False): + tasklist.add(bootstrap.MakeTarball) + + if manifest.bootstrapper.get('virtio', []): + from tasks import virtio + tasklist.update([virtio.VirtIO]) + + tasklist.update(common.task_sets.get_fs_specific_set(manifest.volume['partitions'])) + + if 'boot' in manifest.volume['partitions']: + tasklist.update(common.task_sets.boot_partition_set) + + +def resolve_rollback_tasks(tasklist, manifest, counter_task): + counter_task(loopback.Create, volume.Delete) + counter_task(filesystem.CreateMountDir, filesystem.DeleteMountDir) + counter_task(partitioning.MapPartitions, partitioning.UnmapPartitions) + counter_task(filesystem.MountRoot, filesystem.UnmountRoot) + counter_task(volume.Attach, volume.Detach) + counter_task(workspace.CreateWorkspace, workspace.DeleteWorkspace) diff --git a/providers/kvm/manifest-schema.json b/providers/kvm/manifest-schema.json new file mode 100644 index 0000000..12937c8 --- /dev/null +++ b/providers/kvm/manifest-schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "KVM manifest", + "type": "object", + "properties": { + "bootstrapper": { + "type": "object", + "properties": { + "virtio": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + } + } + }, + "system": { + "type": "object", + "properties": { + "bootloader": { + "type": "string", + "enum": ["grub", "extlinux"] + } + } + }, + "volume": { + "type": "object", + "properties": { + "backing": { + "type": "string", + "enum": ["raw"] + }, + "partitions": { + "type": "object", + "properties": { + "type": { "enum": ["none", "msdos", "gpt"] } + } + } + }, + "required": ["backing"] + } + } +} diff --git a/providers/kvm/tasks/__init__.py b/providers/kvm/tasks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/providers/kvm/tasks/packages.py b/providers/kvm/tasks/packages.py new file mode 100644 index 0000000..52d2639 --- /dev/null +++ b/providers/kvm/tasks/packages.py @@ -0,0 +1,16 @@ +from base import Task +from common import phases +from common.tasks import apt + + +class DefaultPackages(Task): + description = 'Adding image packages required for kvm' + phase = phases.preparation + predecessors = [apt.AddDefaultSources] + + @classmethod + def run(cls, info): + kernels = {'amd64': 'linux-image-amd64', + 'i386': 'linux-image-686', } + info.packages.add(kernels.get(info.manifest.system['architecture'])) + info.packages.add('openssh-server') diff --git a/providers/kvm/tasks/virtio.py b/providers/kvm/tasks/virtio.py new file mode 100644 index 0000000..5c718cc --- /dev/null +++ b/providers/kvm/tasks/virtio.py @@ -0,0 +1,19 @@ +from base import Task +from common import phases +from common.tasks.packages import InstallPackages +from common.exceptions import TaskError +import os + + +class VirtIO(Task): + description = 'Install virtio modules' + phase = phases.system_modification + + @classmethod + def run(cls, info): + from common.tools import log_call + modules = os.path.join(info.root,'/etc/initramfs-tools/modules') + with open(modules, "a") as modules_file: + modules_file.write("\n"); + for module in info.manifest.bootstrapper.get('virtio', []): + modules_file.write(module+"\n")