summaryrefslogtreecommitdiff
path: root/cloudinit/filters
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@yahoo-inc.com>2012-08-31 15:44:50 -0400
committerScott Moser <smoser@ubuntu.com>2012-08-31 15:44:50 -0400
commit27118e7406237510ca56e969aa1b6d9152c8afbf (patch)
tree781517557785592eb8dbe40fd52a0752af774ced /cloudinit/filters
parentc6e4c646287e26d15b8d2402527e1f77e21113cd (diff)
parentff60020fa3d8e457cf9d1d543af9193376bf598c (diff)
downloadvyos-cloud-init-27118e7406237510ca56e969aa1b6d9152c8afbf.tar.gz
vyos-cloud-init-27118e7406237510ca56e969aa1b6d9152c8afbf.zip
support launch index specific user-data
EC2 and openstack provide 'launch_index' in their metadata. This allows the user to specify cloud-config or multipart mime data that includes the 'Launch-Index' header. If launch index is available in the metadata service, then: * any part that contains a launch index other than the current launch-index of this instance will be ignored. * any part that does not contain a launch index will be considered as for this instance. If there is no such header, or launch_index is not available in the metadata service, then no such filtering will be done. LP: #1023177
Diffstat (limited to 'cloudinit/filters')
-rw-r--r--cloudinit/filters/__init__.py21
-rw-r--r--cloudinit/filters/launch_index.py75
2 files changed, 96 insertions, 0 deletions
diff --git a/cloudinit/filters/__init__.py b/cloudinit/filters/__init__.py
new file mode 100644
index 00000000..da124641
--- /dev/null
+++ b/cloudinit/filters/__init__.py
@@ -0,0 +1,21 @@
+# vi: ts=4 expandtab
+#
+# Copyright (C) 2012 Canonical Ltd.
+# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+# Copyright (C) 2012 Yahoo! Inc.
+#
+# Author: Scott Moser <scott.moser@canonical.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.com>
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
diff --git a/cloudinit/filters/launch_index.py b/cloudinit/filters/launch_index.py
new file mode 100644
index 00000000..4299fb46
--- /dev/null
+++ b/cloudinit/filters/launch_index.py
@@ -0,0 +1,75 @@
+# vi: ts=4 expandtab
+#
+# Copyright (C) 2012 Canonical Ltd.
+# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+# Copyright (C) 2012 Yahoo! Inc.
+#
+# Author: Scott Moser <scott.moser@canonical.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.com>
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import copy
+
+from cloudinit import log as logging
+from cloudinit import user_data as ud
+from cloudinit import util
+
+LOG = logging.getLogger(__name__)
+
+
+class Filter(object):
+ def __init__(self, wanted_idx, allow_none=True):
+ self.wanted_idx = wanted_idx
+ self.allow_none = allow_none
+
+ def _select(self, message):
+ msg_idx = message.get('Launch-Index', None)
+ if self.allow_none and msg_idx is None:
+ return True
+ msg_idx = util.safe_int(msg_idx)
+ if msg_idx != self.wanted_idx:
+ return False
+ return True
+
+ def _do_filter(self, message):
+ # Don't use walk() here since we want to do the reforming of the
+ # messages ourselves and not flatten the message listings...
+ if not self._select(message):
+ return None
+ if message.is_multipart():
+ # Recreate it and its child messages
+ prev_msgs = message.get_payload(decode=False)
+ new_msgs = []
+ discarded = 0
+ for m in prev_msgs:
+ m = self._do_filter(m)
+ if m is not None:
+ new_msgs.append(m)
+ else:
+ discarded += 1
+ LOG.debug(("Discarding %s multipart messages "
+ "which do not match launch index %s"),
+ discarded, self.wanted_idx)
+ new_message = copy.copy(message)
+ new_message.set_payload(new_msgs)
+ new_message[ud.ATTACHMENT_FIELD] = str(len(new_msgs))
+ return new_message
+ else:
+ return copy.copy(message)
+
+ def apply(self, root_message):
+ if self.wanted_idx is None:
+ return root_message
+ return self._do_filter(root_message)