diff --git a/bootstrapvz/providers/oracle/README.md b/bootstrapvz/providers/oracle/README.md new file mode 100644 index 0000000..5fd0429 --- /dev/null +++ b/bootstrapvz/providers/oracle/README.md @@ -0,0 +1,36 @@ +Oracle +====== + +The Oracle provider creates RAW images compressed in a `.tar.gz` tarball. Those image have to be uploaded using the web interface of the Oracle Compute Cloud Service dashboard. + +## Dependencies + +Oracle Compute Cloud currently supports only kernel images compressed with GZIP. Debian kernels from 3.6 and up are compressed with XZ and will not work. If you plan to bootstrap a `jessie` image, for instance, you will have to download or build a custom kernel. The manifest examples expects a custom kernel package located at `/tmp/linux-image-3.16.7-ckt11-gzip-1_amd64.deb`. + +## Quick Start + +Install `apt`/`pip` dependencies: + + $ sudo apt-get install debootstrap git parted kpartx qemu-utils python-pip + $ sudo pip install termcolor jsonschema fysom docopt pyyaml + +Download a custom-built gzipped kernel: + + $ cd /tmp/ + $ wget http://viridian.ilieve.org/kernel/linux-image-3.16.7-ckt11-gzip-1_amd64.deb + +Clone this repository: + + $ cd ~/ + $ git clone https://github.com/myhro/bootstrap-vz.git + +Create a new local branch from this one: + + $ cd bootstrap-vz/ + $ git checkout -b oracle origin/oracle + +Bootstrap a new image: + + $ sudo ./bootstrap-vz --debug manifests/examples/oracle/jessie.yml + +P.s.: you probably want to change the root password define on the example manifest, as `cloud-init` isn't properly fetching public keys on Oracle Compute Cloud right now. diff --git a/bootstrapvz/providers/oracle/__init__.py b/bootstrapvz/providers/oracle/__init__.py new file mode 100644 index 0000000..a1bc29a --- /dev/null +++ b/bootstrapvz/providers/oracle/__init__.py @@ -0,0 +1,37 @@ +from bootstrapvz.common import task_groups +from bootstrapvz.common.tasks import image +from bootstrapvz.common.tasks import loopback +from bootstrapvz.common.tasks import initd +from bootstrapvz.common.tasks import ssh +from bootstrapvz.common.tasks import volume +import tasks.image +import tasks.network + + +def validate_manifest(data, validator, error): + import os.path + schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml')) + validator(data, schema_path) + + +def resolve_tasks(taskset, manifest): + taskset.update(task_groups.get_standard_groups(manifest)) + + taskset.update([loopback.AddRequiredCommands, + loopback.Create, + initd.InstallInitScripts, + ssh.AddOpenSSHPackage, + ssh.ShredHostkeys, + ssh.AddSSHKeyGeneration, + image.MoveImage, + volume.Delete, + tasks.image.CreateImageTarball, + tasks.network.InstallDHCPCD, + ]) + + if 'cloud_init' in manifest.plugins: + taskset.add(tasks.network.SetCloudInitMetadataURL) + + +def resolve_rollback_tasks(taskset, manifest, completed, counter_task): + taskset.update(task_groups.get_standard_rollback_tasks(completed)) diff --git a/bootstrapvz/providers/oracle/assets/cloud-init/90_dpkg.cfg b/bootstrapvz/providers/oracle/assets/cloud-init/90_dpkg.cfg new file mode 100644 index 0000000..b064094 --- /dev/null +++ b/bootstrapvz/providers/oracle/assets/cloud-init/90_dpkg.cfg @@ -0,0 +1,4 @@ +# Created by bootstrap-vz, can be generated using "dpkg-reconfigure cloud-init" +datasource: + Ec2: + metadata_urls: [ 'http://192.0.0.192/' ] diff --git a/bootstrapvz/providers/oracle/manifest-schema.yml b/bootstrapvz/providers/oracle/manifest-schema.yml new file mode 100644 index 0000000..32da5d5 --- /dev/null +++ b/bootstrapvz/providers/oracle/manifest-schema.yml @@ -0,0 +1,27 @@ +--- +$schema: http://json-schema.org/draft-04/schema# +title: Oracle manifest +type: object +properties: + system: + type: object + properties: + bootloader: + type: string + enum: [grub] + volume: + type: object + properties: + backing: + type: string + enum: [raw] + partitions: + type: object + properties: + type: + type: string + enum: + - none + - msdos + - gpt + required: [backing] diff --git a/bootstrapvz/providers/oracle/tasks/__init__.py b/bootstrapvz/providers/oracle/tasks/__init__.py new file mode 100644 index 0000000..494ec79 --- /dev/null +++ b/bootstrapvz/providers/oracle/tasks/__init__.py @@ -0,0 +1,3 @@ +import os.path + +assets = os.path.normpath(os.path.join(os.path.dirname(__file__), '../assets')) diff --git a/bootstrapvz/providers/oracle/tasks/image.py b/bootstrapvz/providers/oracle/tasks/image.py new file mode 100644 index 0000000..e7221fb --- /dev/null +++ b/bootstrapvz/providers/oracle/tasks/image.py @@ -0,0 +1,21 @@ +from bootstrapvz.base import Task +from bootstrapvz.common import phases +from bootstrapvz.common.tasks import image +from bootstrapvz.common.tools import log_check_call +import os + + +class CreateImageTarball(Task): + description = 'Creating tarball with image' + phase = phases.image_registration + predecessors = [image.MoveImage] + + @classmethod + def run(cls, info): + image_name = info.manifest.name.format(**info.manifest_vars) + filename = image_name + '.' + info.volume.extension + + tarball_name = image_name + '.tar.gz' + tarball_path = os.path.join(info.manifest.bootstrapper['workspace'], tarball_name) + log_check_call(['tar', '--sparse', '-C', info.manifest.bootstrapper['workspace'], + '-caf', tarball_path, filename]) diff --git a/bootstrapvz/providers/oracle/tasks/network.py b/bootstrapvz/providers/oracle/tasks/network.py new file mode 100644 index 0000000..b18e0dc --- /dev/null +++ b/bootstrapvz/providers/oracle/tasks/network.py @@ -0,0 +1,27 @@ +from bootstrapvz.base import Task +from bootstrapvz.common import phases +from . import assets +import os.path +import shutil + + +class InstallDHCPCD(Task): + description = 'Replacing isc-dhcp with dhcpcd5' + phase = phases.preparation + + @classmethod + def run(cls, info): + info.packages.add('dhcpcd5') + info.exclude_packages.add('isc-dhcp-client') + info.exclude_packages.add('isc-dhcp-common') + + +class SetCloudInitMetadataURL(Task): + description = 'Setting cloud-init metadata URL' + phase = phases.system_modification + + @classmethod + def run(cls, info): + cfg_src = os.path.join(assets, 'cloud-init/90_dpkg.cfg') + cfg_dst = os.path.join(info.root, 'etc/cloud/cloud.cfg.d/90_dpkg.cfg') + shutil.copy(cfg_src, cfg_dst) diff --git a/manifests/examples/oracle/jessie-cloud-init.yml b/manifests/examples/oracle/jessie-cloud-init.yml new file mode 100644 index 0000000..e22be39 --- /dev/null +++ b/manifests/examples/oracle/jessie-cloud-init.yml @@ -0,0 +1,30 @@ +--- +name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} +provider: + name: oracle +bootstrapper: + workspace: /target +system: + release: jessie + architecture: amd64 + bootloader: grub + charmap: UTF-8 + locale: en_US + timezone: UTC +volume: + backing: raw + partitions: + type: msdos + root: + filesystem: ext4 + size: 8GiB +packages: + install: + - initramfs-tools + - /tmp/linux-image-3.16.7-ckt11-gzip-1_amd64.deb +plugins: + cloud_init: + username: opc + metadata_sources: Ec2 + root_password: + password: ARealSecurePassword diff --git a/manifests/examples/oracle/jessie.yml b/manifests/examples/oracle/jessie.yml new file mode 100644 index 0000000..46a205d --- /dev/null +++ b/manifests/examples/oracle/jessie.yml @@ -0,0 +1,27 @@ +--- +name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} +provider: + name: oracle +bootstrapper: + workspace: /target +system: + release: jessie + architecture: amd64 + bootloader: grub + charmap: UTF-8 + locale: en_US + timezone: UTC +volume: + backing: raw + partitions: + type: msdos + root: + filesystem: ext4 + size: 8GiB +packages: + install: + - initramfs-tools + - /tmp/linux-image-3.16.7-ckt11-gzip-1_amd64.deb +plugins: + root_password: + password: ARealSecurePassword