add azure provider

This commit is contained in:
Olivier Sallou 2014-04-07 14:23:24 +02:00 committed by Olivier Sallou
parent 399dfa3fa0
commit fb5d630c9b
8 changed files with 275 additions and 0 deletions

View file

@ -0,0 +1,28 @@
Azure provider
===========
This provider generates raw images for Microsoft Azure computing platform.
It also supports an optional virtio integration.
Setup
=====
qemu-img >= 1.7.0 required to convert raw image to vhd fixed size disk.
This release is available in wheezy-backports.
Manifest must use the *raw* format, provider will automatically transform the disk to a vhd disk format.
Do not create swap space on the OS disk:
The Windows Azure Linux Agent can automatically configure swap space using the local resource disk that is attached to the VM after provisioning on Azure. Modify the following parameters in /etc/waagent.conf appropriately:
ResourceDisk.Format=y
ResourceDisk.Filesystem=ext4
ResourceDisk.MountPoint=/mnt/resource
ResourceDisk.EnableSwap=y
ResourceDisk.SwapSizeMB=2048 ## NOTE: set this to whatever you need it to be.
You can specify a waagent.conf file to replace the default one in the manifest in the azure/waagent section of the provider:
"azure" : { "waagent" : "path_to_my_conf_file" }, ...

View file

@ -0,0 +1,73 @@
import tasks.packages
import tasks.boot
import tasks.image
from bootstrapvz.common.tasks import volume
from bootstrapvz.common.tasks import loopback
from bootstrapvz.common.tasks import partitioning
from bootstrapvz.common.tasks import filesystem
from bootstrapvz.common.tasks import bootstrap
from bootstrapvz.common.tasks import security
from bootstrapvz.common.tasks import network
from bootstrapvz.common.tasks import initd
from bootstrapvz.common.tasks import cleanup
from bootstrapvz.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):
from bootstrapvz.common import task_sets
tasklist.update(task_sets.base_set)
tasklist.update(task_sets.volume_set)
tasklist.update(task_sets.mounting_set)
tasklist.update(task_sets.get_apt_set(manifest))
tasklist.update(task_sets.locale_set)
tasklist.update(task_sets.bootloader_set.get(manifest.system['bootloader']))
if manifest.volume['partitions']['type'] != 'none':
tasklist.update(task_sets.partitioning_set)
tasklist.update([tasks.packages.DefaultPackages,
loopback.Create,
security.EnableShadowConfig,
network.RemoveDNSInfo,
network.ConfigureNetworkIF,
network.RemoveHostname,
initd.AddSSHKeyGeneration,
initd.InstallInitScripts,
tasks.packages.Waagent,
tasks.boot.ConfigureGrub,
cleanup.ClearMOTD,
cleanup.CleanTMP,
tasks.image.ConvertToVhd
])
if manifest.bootstrapper.get('tarball', False):
tasklist.add(bootstrap.MakeTarball)
tasklist.update(task_sets.get_fs_specific_set(manifest.volume['partitions']))
if 'boot' in manifest.volume['partitions']:
tasklist.update(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)

View file

@ -0,0 +1,40 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Azure manifest",
"type": "object",
"properties": {
"azure": {
"type": "object",
"properties": {
"waagent": {
"type": "string"
}
}
},
"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"]
}
}
}

View file

@ -0,0 +1,17 @@
from bootstrapvz.base import Task
from bootstrapvz.common import phases
from bootstrapvz.common.tasks import boot
class ConfigureGrub(Task):
description = 'Change grub configuration to allow for ttyS0 output'
phase = phases.system_modification
successors = [boot.InstallGrub]
@classmethod
def run(cls, info):
import os
from bootstrapvz.common.tools import sed_i
grub_config = os.path.join(info.root, 'etc/default/grub')
sed_i(grub_config, r'^(GRUB_CMDLINE_LINUX*=".*)"\s*$', r'\1console=ttyS0 earlyprintk=ttyS0 rootdelay=300"')
sed_i(grub_config, r'^.*(GRUB_TIMEOUT=).*$', r'GRUB_TIMEOUT=0')

View file

@ -0,0 +1,26 @@
from bootstrapvz.base import Task
from bootstrapvz.common import phases
from bootstrapvz.common.tasks import loopback
class ConvertToVhd(Task):
description = 'Convert raw image to vhd disk'
phase = phases.image_registration
@classmethod
def run(cls, info):
image_name = info.manifest.image['name'].format(**info.manifest_vars)
filename = '{image_name}.{ext}'.format(image_name=image_name, ext='vhd')
import os.path
destination = os.path.join(info.manifest.bootstrapper['workspace'], filename)
file_size = os.path.getsize(info.volume.image_path)
rounded_vol_size = str(((file_size/(1024*1024)+1)*(1024*1024)))
from bootstrapvz.common.tools import log_check_call
log_check_call(['qemu-img', 'resize', info.volume.image_path, rounded_vol_size])
log_check_call(['qemu-img', 'convert', '-o', 'subformat=fixed', '-O', 'vpc', info.volume.image_path, destination])
os.remove(info.volume.image_path)
import logging
log = logging.getLogger(__name__)
log.info('The volume image has been moved to {image_path}'.format(image_path=destination))

View file

@ -0,0 +1,51 @@
from bootstrapvz.base import Task
from bootstrapvz.common import phases
from bootstrapvz.common.tasks import apt
from bootstrapvz.common.tasks.packages import InstallPackages
class DefaultPackages(Task):
description = 'Adding image packages required for Azure'
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('openssl')
info.packages.add('python-openssl')
info.packages.add('openssh-server')
info.packages.add('python-pyasn1')
info.packages.add('git')
info.packages.add('sudo')
#info.packages.add('waagent')
class Waagent(Task):
description = 'Add waagent'
phase = phases.package_installation
predecessors = [InstallPackages]
@classmethod
def run(cls, info):
from bootstrapvz.common.tools import log_call
import os
env = os.environ.copy()
env['GIT_SSL_NO_VERIFY'] = 'true'
status, out, err = log_call(['chroot', info.root,
'git','clone', 'https://github.com/WindowsAzure/WALinuxAgent.git',
'/root/WALinuxAgent'], env=env)
status, out, err = log_call(['chroot', info.root,
'cp','/root/WALinuxAgent/waagent','/usr/sbin/waagent'])
status, out, err = log_call(['chroot', info.root,
'chmod','755','/usr/sbin/waagent'])
status, out, err = log_call(['chroot', info.root,
'/usr/sbin/waagent','-install'])
import os.path
if hasattr(info.manifest, 'azure') and info.manifest.azure['waagent']:
if os.path.isfile(info.manifest.azure['waagent']):
status, out, err = log_call(['cp',
info.manifest.azure['waagent'],
os.path.join(info.root,'etc/waagent.conf')])

View file

@ -0,0 +1,40 @@
{
"provider": "azure",
"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": "7GiB",
"filesystem": "ext4"
}
}
},
"plugins": {
"ntp": {
"servers": ["time.windows.com"]
}
}
}