mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-22 18:00:35 +00:00
add azure provider
This commit is contained in:
parent
399dfa3fa0
commit
fb5d630c9b
8 changed files with 275 additions and 0 deletions
28
bootstrapvz/providers/azure/README.md
Normal file
28
bootstrapvz/providers/azure/README.md
Normal 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" }, ...
|
73
bootstrapvz/providers/azure/__init__.py
Normal file
73
bootstrapvz/providers/azure/__init__.py
Normal 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)
|
40
bootstrapvz/providers/azure/manifest-schema.json
Normal file
40
bootstrapvz/providers/azure/manifest-schema.json
Normal 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"]
|
||||
}
|
||||
}
|
||||
}
|
0
bootstrapvz/providers/azure/tasks/__init__.py
Normal file
0
bootstrapvz/providers/azure/tasks/__init__.py
Normal file
17
bootstrapvz/providers/azure/tasks/boot.py
Normal file
17
bootstrapvz/providers/azure/tasks/boot.py
Normal 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')
|
||||
|
26
bootstrapvz/providers/azure/tasks/image.py
Normal file
26
bootstrapvz/providers/azure/tasks/image.py
Normal 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))
|
51
bootstrapvz/providers/azure/tasks/packages.py
Normal file
51
bootstrapvz/providers/azure/tasks/packages.py
Normal 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')])
|
||||
|
40
manifests/azure.manifest.json
Normal file
40
manifests/azure.manifest.json
Normal 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"]
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue