summaryrefslogtreecommitdiff
path: root/ec2-run-user-data.py
diff options
context:
space:
mode:
authorSoren Hansen <soren@canonical.com>2009-08-25 23:56:04 +0200
committerSoren Hansen <soren@canonical.com>2009-08-25 23:56:04 +0200
commit5dfb04f0d8628cee0eb1f8f72636417f81282c3f (patch)
tree8743a08d8e959f2a4b5648f55452aa1079218c58 /ec2-run-user-data.py
parentd15a2104883b6e6ec6d4dc78d95a4f4c5717b508 (diff)
parent59d21bb23db06e5e02cbd91ec531b1506ab97fae (diff)
downloadvyos-cloud-init-5dfb04f0d8628cee0eb1f8f72636417f81282c3f.tar.gz
vyos-cloud-init-5dfb04f0d8628cee0eb1f8f72636417f81282c3f.zip
Merge with lp:~soren/ec2-init/appliancexml
This gives us the bulk of the magic needed on the instance side to implement http://wiki.ubuntu.com/VirtualApplianceSpec
Diffstat (limited to 'ec2-run-user-data.py')
-rwxr-xr-xec2-run-user-data.py103
1 files changed, 94 insertions, 9 deletions
diff --git a/ec2-run-user-data.py b/ec2-run-user-data.py
index 5af04249..d7e8e632 100755
--- a/ec2-run-user-data.py
+++ b/ec2-run-user-data.py
@@ -22,6 +22,7 @@ import email
import os
import subprocess
import tempfile
+from xml.dom.minidom import parse, parseString
import ec2init
@@ -34,14 +35,6 @@ def register_handler(mimetype, func):
content_type_handlers[mimetype] = func
return func
-def main():
- ec2 = ec2init.EC2Init()
-
- user_data = ec2.get_user_data()
-
- msg = email.message_from_string(user_data)
- handle_part(msg)
-
def handle_part(part):
if part.is_multipart():
for p in part.get_payload():
@@ -57,10 +50,18 @@ def handle_unknown_payload(payload):
# Try to detect magic
if payload.startswith('#!'):
content_type_handlers['text/x-shellscript'](payload)
+ return
+ if payload.startswith('<appliance>'):
+ content_type_handlers['text/x-appliance-config'](payload)
+
+@handler('text/x-appliance-config')
+def handle_appliance_config(payload):
+ app = ApplianceConfig(payload)
+ app.handle()
@handler('text/x-ebs-mount-description')
def handle_ebs_mount_description(payload):
- (volume_description, path) = payload.split(':')
+ (volume_description, paths) = payload.split(':')
(identifier_type, identifier) = volume_description.split('=')
if identifier_type == 'device':
@@ -72,6 +73,17 @@ def handle_ebs_mount_description(payload):
else:
return
+ mount_ebs_volume(device, paths.split(','))
+
+def mount_ebs_volume(device, paths):
+ if os.path.exists('ec2-init-appliance-ebs-volume-mount.sh'):
+ helper = './ec2-init-appliance-ebs-volume-mount.sh'
+ else:
+ helper = '/usr/share/ec2-init/ec2-init-appliance-ebs-volume-mount.sh'
+ helper = subprocess.Popen([helper, device] + paths, stdout=subprocess.PIPE)
+ stdout, stderr = helper.communicate()
+ return stdout
+
@handler('text/x-shellscript')
def handle_shell_script(payload):
(fd, path) = tempfile.mkstemp()
@@ -87,5 +99,78 @@ def handle_shell_script(payload):
os.unlink(path)
+class ApplianceConfig(object):
+ def __init__(self, data):
+ self.data = data
+
+ def handle(self):
+ self.dom = parseString(self.data)
+
+ if self.dom.childNodes[0].tagName == 'appliance':
+ root = self.dom.childNodes[0]
+ else:
+ return
+
+ for node in root.childNodes:
+ if node.tagName == 'package':
+ pkg = None
+ for subnode in node.childNodes:
+ if subnode.nodeType == root.TEXT_NODE:
+ pkg = subnode.nodeValue
+ if not pkg:
+ # Something's fishy. We should have been passed the name of
+ # a package.
+ return
+ if node.getAttribute('action') == 'remove':
+ remove_package(pkg)
+ else:
+ install_package(pkg)
+ elif node.tagName == 'script':
+ script = ''
+ for subnode in node.childNodes:
+ # If someone went through the trouble of wrapping it in CDATA,
+ # it's probably the script we want to run..
+ if subnode.nodeType == root.CDATA_SECTION_NODE:
+ script = subnode.nodeValue
+ # ..however, fall back to whatever TEXT_NODE stuff is between
+ # the <script> tags.
+ if subnode.nodeType == root.TEXT_NODE and not script:
+ script = subnode.nodeValue
+ if not script:
+ # An empty script?
+ continue
+ content_type_handlers['text/x-shellscript'](script)
+ elif node.tagName == 'storage':
+ paths = []
+ device = node.getAttribute('device')
+ for subnode in node.childNodes:
+ if subnode.tagName == 'path':
+ for subsubnode in subnode.childNodes:
+ if subsubnode.nodeType == root.TEXT_NODE:
+ paths += [subsubnode.nodeValue.strip()]
+ break
+ mount_ebs_volume(device, paths)
+
+def main():
+ ec2 = ec2init.EC2Init()
+
+ user_data = ec2.get_user_data()
+ msg = parse_user_data(user_data)
+ handle_part(msg)
+
+def parse_user_data(user_data):
+ return email.message_from_string(user_data)
+
+def install_remove_package(pkg, action):
+ apt_get = subprocess.Popen(['apt-get', action, pkg], stdout=subprocess.PIPE)
+ logger_process = subprocess.Popen(['logger', '-t', 'user-data'], stdin=apt_get.stdout)
+ logger_process.communicate()
+
+def install_package(pkg):
+ return install_remove_package(pkg, 'install')
+
+def remove_package(pkg):
+ return install_remove_package(pkg, 'remove')
+
if __name__ == '__main__':
main()