Merge lp:~cloud-init-dev/cloud-init/trunk into lp:~hannes-georg-0/cloud-init/add_mkswap_force_flag

Proposed by Hannes
Status: Merged
Merge reported by: Scott Moser
Merged at revision: not available
Proposed branch: lp:~cloud-init-dev/cloud-init/trunk
Merge into: lp:~hannes-georg-0/cloud-init/add_mkswap_force_flag
Diff against target: 51583 lines (+11/-49380) (has conflicts)
424 files modified
.bzrignore (+0/-4)
ChangeLog (+0/-761)
HACKING.rst (+0/-48)
LICENSE (+0/-674)
MANIFEST.in (+0/-8)
Makefile (+0/-82)
README (+11/-0)
TODO.rst (+0/-43)
bin/cloud-init (+0/-673)
cloudinit/__init__.py (+0/-21)
cloudinit/cloud.py (+0/-109)
cloudinit/config/__init__.py (+0/-58)
cloudinit/config/cc_apt_configure.py (+0/-292)
cloudinit/config/cc_apt_pipelining.py (+0/-57)
cloudinit/config/cc_bootcmd.py (+0/-54)
cloudinit/config/cc_byobu.py (+0/-80)
cloudinit/config/cc_ca_certs.py (+0/-104)
cloudinit/config/cc_chef.py (+0/-342)
cloudinit/config/cc_debug.py (+0/-109)
cloudinit/config/cc_disable_ec2_metadata.py (+0/-36)
cloudinit/config/cc_emit_upstart.py (+0/-69)
cloudinit/config/cc_fan.py (+0/-101)
cloudinit/config/cc_final_message.py (+0/-73)
cloudinit/config/cc_foo.py (+0/-52)
cloudinit/config/cc_growpart.py (+0/-300)
cloudinit/config/cc_grub_dpkg.py (+0/-73)
cloudinit/config/cc_keys_to_console.py (+0/-62)
cloudinit/config/cc_landscape.py (+0/-99)
cloudinit/config/cc_locale.py (+0/-37)
cloudinit/config/cc_lxd.py (+0/-176)
cloudinit/config/cc_mcollective.py (+0/-88)
cloudinit/config/cc_migrator.py (+0/-85)
cloudinit/config/cc_mounts.py (+0/-405)
cloudinit/config/cc_package_update_upgrade_install.py (+0/-99)
cloudinit/config/cc_phone_home.py (+0/-122)
cloudinit/config/cc_power_state_change.py (+0/-223)
cloudinit/config/cc_puppet.py (+0/-118)
cloudinit/config/cc_resizefs.py (+0/-185)
cloudinit/config/cc_resolv_conf.py (+0/-116)
cloudinit/config/cc_rh_subscription.py (+0/-408)
cloudinit/config/cc_rightscale_userdata.py (+0/-102)
cloudinit/config/cc_rsyslog.py (+0/-366)
cloudinit/config/cc_runcmd.py (+0/-38)
cloudinit/config/cc_salt_minion.py (+0/-59)
cloudinit/config/cc_scripts_per_boot.py (+0/-41)
cloudinit/config/cc_scripts_per_instance.py (+0/-41)
cloudinit/config/cc_scripts_per_once.py (+0/-41)
cloudinit/config/cc_scripts_user.py (+0/-42)
cloudinit/config/cc_scripts_vendor.py (+0/-43)
cloudinit/config/cc_seed_random.py (+0/-94)
cloudinit/config/cc_set_hostname.py (+0/-37)
cloudinit/config/cc_set_passwords.py (+0/-167)
cloudinit/config/cc_snappy.py (+0/-304)
cloudinit/config/cc_ssh.py (+0/-142)
cloudinit/config/cc_ssh_authkey_fingerprints.py (+0/-105)
cloudinit/config/cc_ssh_import_id.py (+0/-99)
cloudinit/config/cc_timezone.py (+0/-39)
cloudinit/config/cc_ubuntu_init_switch.py (+0/-162)
cloudinit/config/cc_update_etc_hosts.py (+0/-60)
cloudinit/config/cc_update_hostname.py (+0/-43)
cloudinit/config/cc_users_groups.py (+0/-34)
cloudinit/config/cc_write_files.py (+0/-103)
cloudinit/config/cc_yum_add_repo.py (+0/-107)
cloudinit/cs_utils.py (+0/-105)
cloudinit/distros/__init__.py (+0/-950)
cloudinit/distros/arch.py (+0/-201)
cloudinit/distros/debian.py (+0/-227)
cloudinit/distros/fedora.py (+0/-31)
cloudinit/distros/freebsd.py (+0/-417)
cloudinit/distros/gentoo.py (+0/-160)
cloudinit/distros/net_util.py (+0/-182)
cloudinit/distros/parsers/__init__.py (+0/-28)
cloudinit/distros/parsers/hostname.py (+0/-88)
cloudinit/distros/parsers/hosts.py (+0/-92)
cloudinit/distros/parsers/resolv_conf.py (+0/-169)
cloudinit/distros/parsers/sys_conf.py (+0/-113)
cloudinit/distros/rhel.py (+0/-222)
cloudinit/distros/rhel_util.py (+0/-89)
cloudinit/distros/sles.py (+0/-179)
cloudinit/distros/ubuntu.py (+0/-31)
cloudinit/ec2_utils.py (+0/-201)
cloudinit/filters/__init__.py (+0/-21)
cloudinit/filters/launch_index.py (+0/-75)
cloudinit/handlers/__init__.py (+0/-274)
cloudinit/handlers/boot_hook.py (+0/-70)
cloudinit/handlers/cloud_config.py (+0/-163)
cloudinit/handlers/shell_script.py (+0/-55)
cloudinit/handlers/upstart_job.py (+0/-119)
cloudinit/helpers.py (+0/-458)
cloudinit/importer.py (+0/-58)
cloudinit/log.py (+0/-155)
cloudinit/mergers/__init__.py (+0/-166)
cloudinit/mergers/m_dict.py (+0/-88)
cloudinit/mergers/m_list.py (+0/-89)
cloudinit/mergers/m_str.py (+0/-46)
cloudinit/net/__init__.py (+0/-771)
cloudinit/net/network_state.py (+0/-447)
cloudinit/net/udev.py (+0/-54)
cloudinit/netinfo.py (+0/-249)
cloudinit/patcher.py (+0/-58)
cloudinit/registry.py (+0/-37)
cloudinit/reporting/__init__.py (+0/-42)
cloudinit/reporting/events.py (+0/-248)
cloudinit/reporting/handlers.py (+0/-91)
cloudinit/safeyaml.py (+0/-32)
cloudinit/settings.py (+0/-68)
cloudinit/signal_handler.py (+0/-71)
cloudinit/sources/DataSourceAltCloud.py (+0/-293)
cloudinit/sources/DataSourceAzure.py (+0/-651)
cloudinit/sources/DataSourceBigstep.py (+0/-57)
cloudinit/sources/DataSourceCloudSigma.py (+0/-141)
cloudinit/sources/DataSourceCloudStack.py (+0/-253)
cloudinit/sources/DataSourceConfigDrive.py (+0/-424)
cloudinit/sources/DataSourceDigitalOcean.py (+0/-110)
cloudinit/sources/DataSourceEc2.py (+0/-211)
cloudinit/sources/DataSourceGCE.py (+0/-167)
cloudinit/sources/DataSourceMAAS.py (+0/-353)
cloudinit/sources/DataSourceNoCloud.py (+0/-336)
cloudinit/sources/DataSourceNone.py (+0/-57)
cloudinit/sources/DataSourceOVF.py (+0/-429)
cloudinit/sources/DataSourceOpenNebula.py (+0/-455)
cloudinit/sources/DataSourceOpenStack.py (+0/-173)
cloudinit/sources/DataSourceSmartOS.py (+0/-536)
cloudinit/sources/__init__.py (+0/-337)
cloudinit/sources/helpers/__init__.py (+0/-13)
cloudinit/sources/helpers/azure.py (+0/-279)
cloudinit/sources/helpers/openstack.py (+0/-499)
cloudinit/sources/helpers/vmware/__init__.py (+0/-13)
cloudinit/sources/helpers/vmware/imc/__init__.py (+0/-13)
cloudinit/sources/helpers/vmware/imc/boot_proto.py (+0/-25)
cloudinit/sources/helpers/vmware/imc/config.py (+0/-95)
cloudinit/sources/helpers/vmware/imc/config_file.py (+0/-129)
cloudinit/sources/helpers/vmware/imc/config_namespace.py (+0/-25)
cloudinit/sources/helpers/vmware/imc/config_nic.py (+0/-247)
cloudinit/sources/helpers/vmware/imc/config_source.py (+0/-23)
cloudinit/sources/helpers/vmware/imc/guestcust_error.py (+0/-24)
cloudinit/sources/helpers/vmware/imc/guestcust_event.py (+0/-27)
cloudinit/sources/helpers/vmware/imc/guestcust_state.py (+0/-25)
cloudinit/sources/helpers/vmware/imc/guestcust_util.py (+0/-128)
cloudinit/sources/helpers/vmware/imc/ipv4_mode.py (+0/-45)
cloudinit/sources/helpers/vmware/imc/nic.py (+0/-147)
cloudinit/sources/helpers/vmware/imc/nic_base.py (+0/-154)
cloudinit/ssh_util.py (+0/-314)
cloudinit/stages.py (+0/-844)
cloudinit/templater.py (+0/-149)
cloudinit/type_utils.py (+0/-52)
cloudinit/url_helper.py (+0/-509)
cloudinit/user_data.py (+0/-352)
cloudinit/util.py (+0/-2226)
cloudinit/version.py (+0/-27)
config/cloud.cfg (+0/-115)
config/cloud.cfg-freebsd (+0/-88)
config/cloud.cfg.d/05_logging.cfg (+0/-66)
config/cloud.cfg.d/README (+0/-3)
doc/README (+0/-4)
doc/examples/cloud-config-add-apt-repos.txt (+0/-34)
doc/examples/cloud-config-archive-launch-index.txt (+0/-30)
doc/examples/cloud-config-archive.txt (+0/-16)
doc/examples/cloud-config-boot-cmds.txt (+0/-15)
doc/examples/cloud-config-ca-certs.txt (+0/-31)
doc/examples/cloud-config-chef-oneiric.txt (+0/-90)
doc/examples/cloud-config-chef.txt (+0/-95)
doc/examples/cloud-config-datasources.txt (+0/-73)
doc/examples/cloud-config-disk-setup.txt (+0/-251)
doc/examples/cloud-config-final-message.txt (+0/-7)
doc/examples/cloud-config-gluster.txt (+0/-18)
doc/examples/cloud-config-growpart.txt (+0/-31)
doc/examples/cloud-config-install-packages.txt (+0/-15)
doc/examples/cloud-config-landscape.txt (+0/-22)
doc/examples/cloud-config-launch-index.txt (+0/-23)
doc/examples/cloud-config-lxd.txt (+0/-55)
doc/examples/cloud-config-mcollective.txt (+0/-49)
doc/examples/cloud-config-mount-points.txt (+0/-46)
doc/examples/cloud-config-phone-home.txt (+0/-14)
doc/examples/cloud-config-power-state.txt (+0/-40)
doc/examples/cloud-config-puppet.txt (+0/-51)
doc/examples/cloud-config-reporting.txt (+0/-17)
doc/examples/cloud-config-resolv-conf.txt (+0/-20)
doc/examples/cloud-config-rh_subscription.txt (+0/-49)
doc/examples/cloud-config-rsyslog.txt (+0/-46)
doc/examples/cloud-config-run-cmds.txt (+0/-22)
doc/examples/cloud-config-salt-minion.txt (+0/-53)
doc/examples/cloud-config-seed-random.txt (+0/-32)
doc/examples/cloud-config-ssh-keys.txt (+0/-46)
doc/examples/cloud-config-update-apt.txt (+0/-7)
doc/examples/cloud-config-update-packages.txt (+0/-8)
doc/examples/cloud-config-user-groups.txt (+0/-109)
doc/examples/cloud-config-vendor-data.txt (+0/-16)
doc/examples/cloud-config-write-files.txt (+0/-33)
doc/examples/cloud-config-yum-repo.txt (+0/-20)
doc/examples/cloud-config.txt (+0/-645)
doc/examples/include-once.txt (+0/-7)
doc/examples/include.txt (+0/-5)
doc/examples/kernel-cmdline.txt (+0/-18)
doc/examples/part-handler-v2.txt (+0/-38)
doc/examples/part-handler.txt (+0/-23)
doc/examples/plain-ignored.txt (+0/-2)
doc/examples/seed/README (+0/-22)
doc/examples/seed/meta-data (+0/-30)
doc/examples/seed/user-data (+0/-3)
doc/examples/upstart-cloud-config.txt (+0/-12)
doc/examples/upstart-rclocal.txt (+0/-12)
doc/examples/user-script.txt (+0/-8)
doc/merging.rst (+0/-188)
doc/rtd/conf.py (+0/-77)
doc/rtd/index.rst (+0/-31)
doc/rtd/static/logo.svg (+0/-89)
doc/rtd/topics/availability.rst (+0/-20)
doc/rtd/topics/capabilities.rst (+0/-24)
doc/rtd/topics/datasources.rst (+0/-200)
doc/rtd/topics/dir_layout.rst (+0/-81)
doc/rtd/topics/examples.rst (+0/-133)
doc/rtd/topics/format.rst (+0/-159)
doc/rtd/topics/hacking.rst (+0/-1)
doc/rtd/topics/merging.rst (+0/-5)
doc/rtd/topics/modules.rst (+0/-342)
doc/rtd/topics/moreinfo.rst (+0/-12)
doc/sources/altcloud/README.rst (+0/-87)
doc/sources/azure/README.rst (+0/-134)
doc/sources/cloudsigma/README.rst (+0/-38)
doc/sources/cloudstack/README.rst (+0/-29)
doc/sources/configdrive/README.rst (+0/-123)
doc/sources/digitalocean/README.rst (+0/-21)
doc/sources/kernel-cmdline.txt (+0/-48)
doc/sources/nocloud/README.rst (+0/-71)
doc/sources/opennebula/README.rst (+0/-142)
doc/sources/openstack/README.rst (+0/-24)
doc/sources/ovf/README (+0/-83)
doc/sources/ovf/example/ovf-env.xml (+0/-46)
doc/sources/ovf/example/ubuntu-server.ovf (+0/-130)
doc/sources/ovf/make-iso (+0/-156)
doc/sources/ovf/ovf-env.xml.tmpl (+0/-28)
doc/sources/ovf/ovfdemo.pem (+0/-27)
doc/sources/ovf/user-data (+0/-7)
doc/sources/smartos/README.rst (+0/-149)
doc/status.txt (+0/-53)
doc/userdata.txt (+0/-79)
doc/var-lib-cloud.txt (+0/-63)
doc/vendordata.txt (+0/-53)
packages/bddeb (+0/-260)
packages/brpm (+0/-277)
packages/debian/changelog.in (+0/-6)
packages/debian/cloud-init.postinst (+0/-16)
packages/debian/cloud-init.preinst (+0/-20)
packages/debian/compat (+0/-1)
packages/debian/control.in (+0/-29)
packages/debian/copyright (+0/-29)
packages/debian/dirs (+0/-6)
packages/debian/rules.in (+0/-23)
packages/debian/watch (+0/-2)
packages/redhat/cloud-init.spec.in (+0/-200)
packages/suse/cloud-init.spec.in (+0/-163)
requirements.txt (+0/-36)
setup.py (+0/-215)
systemd/cloud-config.service (+0/-16)
systemd/cloud-config.target (+0/-11)
systemd/cloud-final.service (+0/-17)
systemd/cloud-init-generator (+0/-133)
systemd/cloud-init-local.service (+0/-22)
systemd/cloud-init.service (+0/-18)
systemd/cloud-init.target (+0/-6)
sysvinit/debian/cloud-config (+0/-64)
sysvinit/debian/cloud-final (+0/-66)
sysvinit/debian/cloud-init (+0/-64)
sysvinit/debian/cloud-init-local (+0/-63)
sysvinit/freebsd/cloudconfig (+0/-35)
sysvinit/freebsd/cloudfinal (+0/-35)
sysvinit/freebsd/cloudinit (+0/-35)
sysvinit/freebsd/cloudinitlocal (+0/-35)
sysvinit/gentoo/cloud-config (+0/-13)
sysvinit/gentoo/cloud-final (+0/-11)
sysvinit/gentoo/cloud-init (+0/-12)
sysvinit/gentoo/cloud-init-local (+0/-13)
sysvinit/redhat/cloud-config (+0/-121)
sysvinit/redhat/cloud-final (+0/-121)
sysvinit/redhat/cloud-init (+0/-121)
sysvinit/redhat/cloud-init-local (+0/-124)
templates/chef_client.rb.tmpl (+0/-58)
templates/hosts.debian.tmpl (+0/-26)
templates/hosts.freebsd.tmpl (+0/-24)
templates/hosts.redhat.tmpl (+0/-24)
templates/hosts.suse.tmpl (+0/-26)
templates/resolv.conf.tmpl (+0/-30)
templates/sources.list.debian.tmpl (+0/-32)
templates/sources.list.ubuntu.tmpl (+0/-58)
test-requirements.txt (+0/-17)
tests/configs/sample1.yaml (+0/-52)
tests/data/filter_cloud_multipart.yaml (+0/-30)
tests/data/filter_cloud_multipart_1.email (+0/-11)
tests/data/filter_cloud_multipart_2.email (+0/-39)
tests/data/filter_cloud_multipart_header.email (+0/-11)
tests/data/merge_sources/expected1.yaml (+0/-1)
tests/data/merge_sources/expected10.yaml (+0/-7)
tests/data/merge_sources/expected11.yaml (+0/-5)
tests/data/merge_sources/expected12.yaml (+0/-5)
tests/data/merge_sources/expected2.yaml (+0/-3)
tests/data/merge_sources/expected3.yaml (+0/-1)
tests/data/merge_sources/expected4.yaml (+0/-2)
tests/data/merge_sources/expected5.yaml (+0/-7)
tests/data/merge_sources/expected6.yaml (+0/-9)
tests/data/merge_sources/expected7.yaml (+0/-38)
tests/data/merge_sources/expected8.yaml (+0/-7)
tests/data/merge_sources/expected9.yaml (+0/-5)
tests/data/merge_sources/source1-1.yaml (+0/-3)
tests/data/merge_sources/source1-2.yaml (+0/-5)
tests/data/merge_sources/source10-1.yaml (+0/-6)
tests/data/merge_sources/source10-2.yaml (+0/-6)
tests/data/merge_sources/source11-1.yaml (+0/-5)
tests/data/merge_sources/source11-2.yaml (+0/-3)
tests/data/merge_sources/source11-3.yaml (+0/-3)
tests/data/merge_sources/source12-1.yaml (+0/-8)
tests/data/merge_sources/source12-2.yaml (+0/-5)
tests/data/merge_sources/source2-1.yaml (+0/-6)
tests/data/merge_sources/source2-2.yaml (+0/-5)
tests/data/merge_sources/source3-1.yaml (+0/-4)
tests/data/merge_sources/source3-2.yaml (+0/-4)
tests/data/merge_sources/source4-1.yaml (+0/-3)
tests/data/merge_sources/source4-2.yaml (+0/-6)
tests/data/merge_sources/source5-1.yaml (+0/-6)
tests/data/merge_sources/source5-2.yaml (+0/-8)
tests/data/merge_sources/source6-1.yaml (+0/-5)
tests/data/merge_sources/source6-2.yaml (+0/-8)
tests/data/merge_sources/source7-1.yaml (+0/-27)
tests/data/merge_sources/source7-2.yaml (+0/-17)
tests/data/merge_sources/source8-1.yaml (+0/-7)
tests/data/merge_sources/source8-2.yaml (+0/-6)
tests/data/merge_sources/source9-1.yaml (+0/-5)
tests/data/merge_sources/source9-2.yaml (+0/-6)
tests/data/mountinfo_precise_ext4.txt (+0/-24)
tests/data/mountinfo_raring_btrfs.txt (+0/-13)
tests/data/roots/simple_ubuntu/etc/networks/interfaces (+0/-3)
tests/data/user_data.1.txt (+0/-15)
tests/data/vmware/cust-dhcp-2nic.cfg (+0/-34)
tests/data/vmware/cust-static-2nic.cfg (+0/-39)
tests/unittests/helpers.py (+0/-346)
tests/unittests/test__init__.py (+0/-220)
tests/unittests/test_builtin_handlers.py (+0/-73)
tests/unittests/test_cli.py (+0/-54)
tests/unittests/test_cs_util.py (+0/-84)
tests/unittests/test_data.py (+0/-559)
tests/unittests/test_datasource/test_altcloud.py (+0/-452)
tests/unittests/test_datasource/test_azure.py (+0/-646)
tests/unittests/test_datasource/test_azure_helper.py (+0/-421)
tests/unittests/test_datasource/test_cloudsigma.py (+0/-99)
tests/unittests/test_datasource/test_cloudstack.py (+0/-87)
tests/unittests/test_datasource/test_configdrive.py (+0/-407)
tests/unittests/test_datasource/test_digitalocean.py (+0/-127)
tests/unittests/test_datasource/test_gce.py (+0/-166)
tests/unittests/test_datasource/test_maas.py (+0/-163)
tests/unittests/test_datasource/test_nocloud.py (+0/-187)
tests/unittests/test_datasource/test_opennebula.py (+0/-300)
tests/unittests/test_datasource/test_openstack.py (+0/-347)
tests/unittests/test_datasource/test_smartos.py (+0/-585)
tests/unittests/test_distros/test_generic.py (+0/-233)
tests/unittests/test_distros/test_hostname.py (+0/-38)
tests/unittests/test_distros/test_hosts.py (+0/-41)
tests/unittests/test_distros/test_netconfig.py (+0/-321)
tests/unittests/test_distros/test_resolv.py (+0/-67)
tests/unittests/test_distros/test_sysconfig.py (+0/-82)
tests/unittests/test_distros/test_user_data_normalize.py (+0/-297)
tests/unittests/test_ec2_util.py (+0/-139)
tests/unittests/test_filters/test_launch_index.py (+0/-132)
tests/unittests/test_handler/test_handler_apt_configure.py (+0/-109)
tests/unittests/test_handler/test_handler_ca_certs.py (+0/-271)
tests/unittests/test_handler/test_handler_chef.py (+0/-192)
tests/unittests/test_handler/test_handler_debug.py (+0/-81)
tests/unittests/test_handler/test_handler_disk_setup.py (+0/-30)
tests/unittests/test_handler/test_handler_growpart.py (+0/-220)
tests/unittests/test_handler/test_handler_locale.py (+0/-67)
tests/unittests/test_handler/test_handler_lxd.py (+0/-134)
tests/unittests/test_handler/test_handler_mounts.py (+0/-133)
tests/unittests/test_handler/test_handler_power_state.py (+0/-127)
tests/unittests/test_handler/test_handler_rsyslog.py (+0/-174)
tests/unittests/test_handler/test_handler_seed_random.py (+0/-227)
tests/unittests/test_handler/test_handler_set_hostname.py (+0/-72)
tests/unittests/test_handler/test_handler_snappy.py (+0/-306)
tests/unittests/test_handler/test_handler_timezone.py (+0/-76)
tests/unittests/test_handler/test_handler_write_files.py (+0/-112)
tests/unittests/test_handler/test_handler_yum_add_repo.py (+0/-68)
tests/unittests/test_helpers.py (+0/-33)
tests/unittests/test_merging.py (+0/-257)
tests/unittests/test_net.py (+0/-130)
tests/unittests/test_pathprefix2dict.py (+0/-44)
tests/unittests/test_registry.py (+0/-28)
tests/unittests/test_reporting.py (+0/-369)
tests/unittests/test_rh_subscription.py (+0/-214)
tests/unittests/test_runs/test_merge_run.py (+0/-54)
tests/unittests/test_runs/test_simple_run.py (+0/-81)
tests/unittests/test_sshutil.py (+0/-171)
tests/unittests/test_templating.py (+0/-119)
tests/unittests/test_util.py (+0/-489)
tests/unittests/test_vmware_config_file.py (+0/-103)
tools/21-cloudinit.conf (+0/-6)
tools/Z99-cloud-locale-test.sh (+0/-98)
tools/build-on-freebsd (+0/-66)
tools/ccfg-merge-debug (+0/-90)
tools/cloud-init-per (+0/-60)
tools/hacking.py (+0/-170)
tools/make-dist-tarball (+0/-21)
tools/make-mime.py (+0/-60)
tools/make-tarball (+0/-39)
tools/mock-meta.py (+0/-454)
tools/motd-hook (+0/-35)
tools/read-dependencies (+0/-29)
tools/read-version (+0/-26)
tools/run-pep8 (+0/-22)
tools/run-pyflakes (+0/-18)
tools/run-pyflakes3 (+0/-2)
tools/tox-venv (+0/-42)
tools/uncloud-init (+0/-141)
tools/validate-yaml.py (+0/-25)
tools/write-ssh-key-fingerprints (+0/-38)
tox.ini (+0/-35)
udev/66-azure-ephemeral.rules (+0/-18)
udev/79-cloud-init-net-wait.rules (+0/-10)
udev/cloud-init-wait (+0/-70)
upstart/cloud-config.conf (+0/-9)
upstart/cloud-final.conf (+0/-10)
upstart/cloud-init-blocknet.conf (+0/-83)
upstart/cloud-init-container.conf (+0/-57)
upstart/cloud-init-local.conf (+0/-16)
upstart/cloud-init-nonet.conf (+0/-66)
upstart/cloud-init.conf (+0/-9)
upstart/cloud-log-shutdown.conf (+0/-19)
Conflict: can't delete cloudinit because it is not empty.  Not deleting.
Conflict because cloudinit is not versioned, but has versioned children.  Versioned directory.
Conflict: can't delete cloudinit/config because it is not empty.  Not deleting.
Conflict because cloudinit/config is not versioned, but has versioned children.  Versioned directory.
Contents conflict in cloudinit/config/cc_disk_setup.py
To merge this branch: bzr merge lp:~cloud-init-dev/cloud-init/trunk
Reviewer Review Type Date Requested Status
Chad Smith (community) Needs Fixing
Hannes Pending
Review via email: mp+296021@code.launchpad.net

Description of the change

Hi

The force field table in cc_disk_setup lacks an entry for swap.

Thank you
Hannes

To post a comment you must log in.
lp:~cloud-init-dev/cloud-init/trunk updated
1223. By Dan Watkins

Improve merging documentation

1224. By Scott Moser

Apt sources configuration improvements

- keyid-only (no source statement)
- key only (no source statement)
- custom source.list template
- support long gpg key fingerprints with spaces
- fix issue with key's that were already in the local gpg keyring
- allowing a new format to specify apt_sources in a dictionary instead of a
  list to allow merging of configurations

1225. By Scott Moser

improve network configuration

This branch accomplishes several things:
 - centrally handle 'dsmode' to be 'local' or 'net.
   This allows local data sources to run before networking
   but still have user-data read by default when networking is available.

 - support networking information being read on dreamcompute
   dreamcompute's openstack declares networking via the
   /etc/network/interfaces style 'network_config' format.

 - support reading and applying networking information on SmartOS

 - improve reading networking from openstack network_data.json (LP: #1577982)
   add support for mtu and routes and many miscellaneous fixes.

 - support for renaming devices in a container (LP: #1579130).
   Also rename network devices as instructed by the host on
   every boot where cloud-init networking is enabled. This is required
   because a.) containers do not get systemd.link files applied
   as they do not have udev. b.) if the initramfs is out of date
   then we need to apply them.

 - remove blocking of udev rules (LP: #1577844, LP: #1571761)

1226. By Scott Moser

tests: fix apt tests to run inside ubuntu build environment

This just mocks out use of lsb_release as it is not available
in a build environment.
Additionally mocks out use of getkeybyid. This admittedly
makes the test for a long key fingerprint not useful as it was
broken only inside getkeybyid.

Also fix 'make yaml' for cloud-config.txt

1227. By Scott Moser

skip test_apt_source_list_debian_mirrorfail for now

I've opened bug 1589174 with the intent to fix these tests
that I quickly fixed in the last 2 commits. Those were done
in haste so that we could get a functional trunk build again.

1228. By Scott Moser

make networking config provided in system config override datasource.

while datasource provided networking is more dynamic in most cases,
preference should still be given to networking configuration provided
in the system.

This is because the user of the image should be ultimately in control
of the networking configuration if they so choose.

1229. By Scott Moser

Change missing Cheetah log warning to debug [Andrew Jorgensen]

In the absence of cheetah, which is a fairly heavy templating engine, and
not strictly needed by anything in cloud-init, the only warning we saw in
the logs was this one from the templater. Degrading this to a debug
message makes any other warnings more relevant.

1230. By Scott Moser

Fix apt configure unittests to run in more environments

As well as some improvements that were found along testing them and due to
the fact that we review some of that code again in the scope of curtin
currently.

Tests:
 - add a test for an alternate keyserver
 - harden mirrorfail tests to detect and skip if no network is available
 - improve apt_source related tests to work on CentOS7

Changes:
 - gpg key handling is now in python instead of a shell blob and moved
   to its own module.
 - packages/bddeb has an option to sign as someone else than smoser
 - make exception handling of apt_source features more specific
   (do not catch broad 'Exception')
 - rename some functions to reflect better what they actually do
 - capture some helper subp calls output to avoid spilling into stdout when
   not intended

1231. By Scott Moser

clean up temp files made in tests

After a 'tox' run, now there are no tmpdirs left in /tmp.

1232. By Joshua Harlow

Refactor a large part of the networking code.

Splits off distro specific code into specific files so that
other kinds of networking configuration can be written by the
various distro(s) that cloud-init supports.

It also isolates some of the cloudinit.net code so that it can
be more easily used on its own (and incorporated into other
projects such as curtin).

During this process it adds tests so that the net process can
be tested (to some level) so that the format conversion processes
can be tested going forward.

1233. By Joshua Harlow

Fix the broken import and 'parse_net_config_data' function usage

1234. By Dan Watkins

Remove trailing dot from GCE metadata URL (LP: #1581200) [Phil Roche]

1235. By Scott Moser

[Revert] Remove trailing dot from GCE metadata URL

This change broke tox tests.

1236. By Scott Moser

fix pep8 failure introduced in recent commit.

The commit 1232 (Refactor a large part of the networking code) broke pep8.

1237. By Dan Watkins

Re-apply "Remove trailing dot from GCE metadata URL (LP: #1581200) [Phil Roche]"

This commit includes the content of that commit, plus a fix for the tests
(provided by Phil).

1238. By Scott Moser

move 'main' into cloudinit/cmd/ for easier testing

This moves bin/cloud-init's content into cloudinit/cmd/main.py,
and then fixes the pep8/flake8 issues with that.

The end result is easier testing of main.

1239. By Scott Moser

fix some errors reported by pylint

pylint --errors-only found several errors. Some of the changes
here represent real errors, others just code that pylint did
not like.

1240. By Scott Moser

fix usage of OSError.message that will not work in python3

python3's OSError does not have a .message attribute.

1241. By Scott Moser

DataSourceNoCloud: fix stack trace on reboot, default to dsmode=net

On reboot (loading module from obj.pkl) we would hit a AttributeError
when trying to access cmdline_id.
Addtionally, dsmode was inadvertantly defaulting to local for
DataSourceNoCloud.

1242. By Scott Moser

support network rendering to sysconfig (for centos and RHEL)

This intends to add support for rendering of network data under sysconfig
distributions (centos and rhel). The end result will be support for
network configuration via ConfigDrive or NoCloud on these OS.

1243. By Scott Moser

do not render systemd.link files

When fixing bug 1579130, we made cloud-init rename devices itself,
rather than relying on the systemd.link files to do that.
That was necessary to
 - rename devices in a container
 - rename devices on first boot or in any situation when the
   link files in the initramfs were stale.

However, cloud-init was still writing .link files like:
 /etc/systemd/network/50-cloud-init-ens2.link

That leads to just a confusing situation as cloud-init will trump
any renaming systemd does in all cases.

Also added here is a header into the rendered ENI file:
 /etc/network/interfaces.d/50-cloud-init.cfg

that describes how to disable cloud-init networking.

1244. By Scott Moser

write_files: if no permissions are given, just use default without warn.

if no permissions were given in a write_files stanza, then
a warning would be emitted.

The fix here is just to special case handling of None.

1245. By Scott Moser

user_data: fix error when user-data is not utf-8 decodable

when user-data was not decodable, cloud-init would raise exception.
This also changes the signature of user_data.convert_string.
The 'headers' argument was never used, and woudl have been broken
if it was, as it was expected to be a dictionary but then was
passed in with *headers.

1246. By Scott Moser

fix restoring from a datasource that did not have dsmode

On upgrade and reboot, if datasource restored from obj.pkl did not have
a dsmode attribute, then 'init --local' would fail due to stack trace.

1247. By Scott Moser

distros/debian.py: fix calling of eni renderer to not render link files

Under revno 1243 a failed attempt was made to not render systemd.link
files into /etc/systemd/network/ . The 'config' that was passed in was
incorrect though, and resulted in link files still getting rendered.

(original bug was LP: #1594546).

1248. By Joshua Harlow

Dict comprehensions don't work in 2.6

This fixes a small case of a leftover
dict comprehension being found that stops cloud-init
from working on centos6/rhel6 (which still use py2.6)

1249. By Joshua Harlow

Fixes missing/unpacked rpm files

There are a few new files that are missing from being
included in the rpm specification file (which if missing
causes rpmbuild to die) so make sure we add them in.

1250. By Joshua Harlow

Remove another stray dict comprehension

1251. By Joshua Harlow

Another stray occurence of a dict comprehension being removed

1252. By Joshua Harlow

String format requires positions on python 2.6

1253. By Joshua Harlow

Fix SmartOS datasource usage of dict comprehensions

1254. By Scott Moser

Fix mcollective module with python3

fixes mcollective when used with python3 and also adds a unit test.

1255. By Scott Moser

ConfigDrive: fix writing of 'injected' files and legacy networking

Previous commit inadvertently disabled the consumption of 'injected' files
in configdrive (openstack server boot --file=/target/file=local-file)
unless the datasource was in 'pass' mode. The default mode is 'net' so
that was not likely to happen.

Also here are:
a.) some comments to apply_network_config

b.) add backwards compatibility for distros that do not yet implement
    apply_network_config by converting the network config into ENI format
    and calling apply_network.

    This is required because prior to the previous commit, those distros
    would have had 'apply_network' called with the openstack provided
    ENI file. But after this change they will have apply_network_config
    called by cloudinit's main.

c.) add network_state_to_eni for converting net config to eni
    it supports the not-actually-correct 'hwaddress' field in ENI

1256. By Scott Moser

improvements to eni rendering

Some improvements here, and some bug fixes.
 - bring curtin revno 394's to support post-up for interface aliases.
 - sort attributes per interface for nicer order and consistent rendering
 - use arrays for each 'section' rather than content += . This allows
   better separation of the sections and also will perform better as long
   strings with += are slow.
 - improve how 'lo' is handled. If a network state that was being rendered
   had an entry for 'lo', then the rendered ENI would have 2 'lo'
   sections.
 - no longer skip 'lo' sections when loading an ENI in parse_deb_config
 - fix inet value for subnets, don't add interface attributes to alias
   (LP: #1588547)

Also add some tests of reading yaml and rendering ENI.

1257. By Joshua Harlow

Avoid depending on argparse in 2.7 or greater

At least (currently) for rhel7 the argparse package does
not get installed (even though rpm say it is installed by
the python core package) and this causes things that mention
argparse in there requirements to not believe that argparse
is installed (even though it is) so to avoid this whole mess
we can just avoid depending on argparse in python versions
where we don't need to (since it was included in the stdlib
in python 2.7+)

1258. By Scott Moser

mcollective: add tests, cleanups and bug fix when no config in /etc.

Things here:
 - restart rather than 'start' the service, to pick up a config change
   that we would have written.
 - update the config and write cert files whether or not the file
   existed on the system. Previously it would only write the cert
   files if /etc/mcollective/server.cfg already existed.
 - improve test coverage

1259. By Scott Moser

README: indicate move to git.

cloud-init development has moved its revision control to git.
It is available at
  https://code.launchpad.net/cloud-init

Clone with
  git clone https://git.launchpad.net/cloud-init
or
  git clone git+ssh://git.launchpad.net/cloud-ini

For more information see
  https://git.launchpad.net/cloud-init/tree/HACKING.rst

Revision history for this message
Chad Smith (chad.smith) wrote :

Hello,

Thank you for taking the time to contribute to cloud-init Cloud-init has moved its revision control system to git. As a result, we are marking all bzr merge proposals as 'rejected'. If you would like to re-submit this proposal for review, please do so by following the current HACKING documentation at http://cloudinit.readthedocs.io/en/latest/topics/hacking.html.

Thanks again,
The Cloud init folks

review: Needs Fixing
Revision history for this message
Scott Moser (smoser) wrote :

I'm not sure what exactly this merge proposal was for (it seems backwards).
I've marked it 'merged', to get it off of lists.
if you were using it for something ,please feel free to set it to another state.

but remember that cloud-init is now done in git.
Thanks.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed file '.bzrignore'
2--- .bzrignore 2015-01-21 20:35:56 +0000
3+++ .bzrignore 1970-01-01 00:00:00 +0000
4@@ -1,4 +0,0 @@
5-.tox
6-dist
7-cloud_init.egg-info
8-__pycache__
9
10=== removed file 'ChangeLog'
11--- ChangeLog 2016-05-26 13:02:17 +0000
12+++ ChangeLog 1970-01-01 00:00:00 +0000
13@@ -1,761 +0,0 @@
14-0.7.7:
15- - open 0.7.7
16- - Digital Ocean: add datasource for Digital Ocean. [Neal Shrader]
17- - expose uses_systemd as a distro function (fix rhel7)
18- - fix broken 'output' config (LP: #1387340)
19- - begin adding cloud config module docs to config modules (LP: #1383510)
20- - retain trailing eol from template files (sources.list) when
21- rendered with jinja (LP: #1355343)
22- - Only use datafiles and initsys addon outside virtualenvs
23- - Fix the digital ocean test case on python 2.6
24- - Increase the usefulness, robustness, configurability of the chef module
25- so that it is more useful, more documented and better for users
26- - Fix how '=' signs are not handled that well in ssh_utils (LP: #1391303)
27- - Be more tolerant of ssh keys passed into 'ssh_authorized_keys'; allowing
28- for list, tuple, set, dict, string types and warning on other unexpected
29- types
30- - Update to use newer/better OMNIBUS_URL for chef module
31- - GCE: Allow base64 encoded user-data (LP: #1404311) [Wayne Witzell III]
32- - GCE: use short hostname rather than fqdn (LP: #1383794) [Ben Howard]
33- - systemd: make init stage run before login prompts shown [Steve Langasek]
34- - hostname: on first boot apply hostname to be same as is written for
35- persistent hostname. (LP: #1246485)
36- - remove usage of dmidecode on linux in favor of /sys interface [Ben Howard]
37- - python3 support [Barry Warsaw, Daniel Watkins, Josh Harlow] (LP: #1247132)
38- - support managing gpt partitions in disk config [Daniel Watkins]
39- - Azure: utilze gpt support for ephemeral formating [Daniel Watkins]
40- - CloudStack: support fetching password from virtual router [Daniel Watkins]
41- (LP: #1422388)
42- - readurl, read_file_or_url returns bytes, user must convert as necessary
43- - SmartOS: use v2 metadata service (LP: #1436417) [Daniel Watkins]
44- - NoCloud: fix local datasource claiming found without explicit dsmode
45- - Snappy: add support for installing snappy packages and configuring.
46- - systemd: use network-online instead of network.target (LP: #1440180)
47- [Steve Langasek]
48- - Add functionality to fixate the uid of a newly added user.
49- - Don't overwrite the hostname if the user has changed it after we set it.
50- - GCE datasource does not handle instance ssh keys (LP: 1403617)
51- - sysvinit: make cloud-init-local run before network (LP: #1275098)
52- [Surojit Pathak]
53- - Azure: do not re-set hostname if user has changed it (LP: #1375252)
54- - Fix exception when running with no arguments on Python 3. [Daniel Watkins]
55- - Centos: detect/expect use of systemd on centos 7. [Brian Rak]
56- - Azure: remove dependency on walinux-agent [Daniel Watkins]
57- - EC2: know about eu-central-1 availability-zone (LP: #1456684)
58- - Azure: remove password from on-disk ovf-env.xml (LP: #1443311) [Ben Howard]
59- - Doc: include information on user-data in OpenStack [Daniel Watkins]
60- - Systemd: check for systemd using sd_booted symantics (LP: #1461201)
61- [Lars Kellogg-Stedman]
62- - Add an rh_subscription module to handle registration of Red Hat instances.
63- [Brent Baude]
64- - cc_apt_configure: fix importing keys under python3 (LP: #1463373)
65- - cc_growpart: fix specification of 'devices' list (LP: #1465436)
66- - CloudStack: fix password setting on cloudstack > 4.5.1 (LP: #1464253)
67- - GCE: fix determination of availability zone (LP: #1470880)
68- - ssh: generate ed25519 host keys (LP: #1461242)
69- - distro mirrors: provide datasource to mirror selection code to support
70- GCE regional mirrors. (LP: #1470890)
71- - add udev rules that identify ephemeral device on Azure (LP: #1411582)
72- - _read_dmi_syspath: fix bad log message causing unintended exception
73- - rsyslog: add additional configuration mode (LP: #1478103)
74- - status_wrapper in main: fix use of print_exc when handling exception
75- - reporting: add reporting module for web hook or logging of events.
76- - NoCloud: fix consumption of vendordata (LP: #1493453)
77- - power_state_change: support 'condition' to disable or enable poweroff
78- - ubuntu fan: support for config and installing of ubuntu fan (LP: #1504604)
79- - Azure: support extracting SSH key values from ovf-env.xml (LP: #1506244)
80- - AltCloud: fix call to udevadm settle (LP: #1507526)
81- - Ubuntu templates: modify sources.list template to provide same sources
82- as install from server or desktop ISO. (LP: #1177432)
83- - cc_mounts: use 'nofail' if system uses systemd. (LP: #1514485)
84- - Azure: get instance id from dmi instead of SharedConfig (LP: #1506187)
85- - systemd/power_state: fix power_state to work even if cloud-final
86- exited non-zero (LP: #1449318)
87- - SmartOS: Add support for Joyent LX-Brand Zones (LP: #1540965)
88- [Robert C Jennings]
89- - systemd: support using systemd-detect-virt to detect container
90- (LP: #1539016) [Martin Pitt]
91- - docs: fix lock_passwd documentation [Robert C Jennings]
92- - Azure: Handle escaped quotes in WALinuxAgentShim.find_endpoint.
93- (LP: #1488891) [Dan Watkins]
94- - lxd: add support for setting up lxd using 'lxd init' (LP: #1522879)
95- - Add Image Customization Parser for VMware vSphere Hypervisor
96- Support. [Sankar Tanguturi]
97- - timezone: use a symlink rather than copy for /etc/localtime
98- unless it is already a file (LP: #1543025).
99- - Enable password changing via a hashed string [Alex Sirbu]
100- - Added BigStep datasource [Alex Sirbu]
101- - No longer run pollinate in seed_random (LP: #1554152)
102- - groups: add defalt user to 'lxd' group. Create groups listed
103- for a user if they do not exist. (LP: #1539317)
104- - dmi data: fix failure of reading dmi data for unset dmi values
105- - doc: mention label for nocloud datasource must be 'cidata' [Peter Hurley]
106- - ssh_pwauth: fix module to support 'unchanged' and match behavior
107- described in documentation [Chris Cosby]
108- - quickly check to see if the previous instance id is still valid to
109- avoid dependency on network metadata service on every boot (LP: #1553815)
110- - support network configuration in cloud-init --local with support
111- device naming via systemd.link.
112- - FreeBSD: add support for installing packages, setting password and
113- timezone. Change default user to 'freebsd'. [Ben Arblaster]
114- - locale: list unsupported environment settings in warning (LP: #1558069)
115- - disk_setup: correctly send --force to mkfs on block devices (LP: #1548772)
116- - chef: fix chef install from gems (LP: #1553345)
117- - systemd: do not specify After of obsolete syslog.target (LP: #1536964)
118- - centos: Ensure that resolve conf object is written as a str (LP: #1479988)
119- - chef: straighten out validation_cert and validation_key (LP: #1568940)
120- - phone_home: allow usage of fqdn (LP: #1566824) [Ollie Armstrong]
121- - cloudstack: Only use DHCPv4 lease files as a datasource (LP: #1576273)
122- [Wido den Hollander]
123- - Paths: fix instance path if datasource's id has a '/'. (LP: #1575938)
124- [Robert Jennings]
125- - Ec2: do not retry requests for user-data path on 404.
126- - settings on the kernel command line (cc:) override all local settings
127- rather than only those in /etc/cloud/cloud.cfg (LP: #1582323)
128-
129-0.7.6:
130- - open 0.7.6
131- - Enable vendordata on CloudSigma datasource (LP: #1303986)
132- - Poll on /dev/ttyS1 in CloudSigma datasource only if dmidecode says
133- we're running on cloudsigma (LP: #1316475) [Kiril Vladimiroff]
134- - SmartOS test: do not require existance of /dev/ttyS1. [LP: #1316597]
135- - doc: fix user-groups doc to reference plural ssh-authorized-keys
136- (LP: #1327065) [Joern Heissler]
137- - fix 'make test' in python 2.6
138- - support jinja2 as a templating engine. Drop the hard requirement on
139- cheetah. This helps in python3 effort. (LP: #1219223)
140- - change install path for systemd files to /lib/systemd/system
141- [Dimitri John Ledkov]
142- - change trunk debian packaging to use pybuild and drop cdbs.
143- [Dimitri John Ledkov]
144- - SeLinuxGuard: remove invalid check that looked for stat.st_mode in os.lstat.
145- - do not write comments in /etc/timezone (LP: #1341710)
146- - ubuntu: provide 'ubuntu-init-switch' module to aid in systemd testing.
147- - status/result json: remove 'end' entry which was always null
148- - systemd: make cloud-init block ssh service startup to guarantee keys
149- are generated. [Jordan Evans] (LP: #1333920)
150- - default settings: fix typo resulting in OpenStack and GCE not working
151- unless config explicitly provided (LP: #1329583) [Garrett Holmstrom])
152- - fix rendering resolv.conf if no 'options' are provided (LP: #1328953)
153- - docs: fix disk-setup to reference 'table_type' [Rail Aliiev] (LP: #1313114)
154- - ssh_authkey_fingerprints: fix bug that prevented disabling the module.
155- (LP: #1340903) [Patrick Lucas]
156- - no longer use pylint as a checker, fix pep8 [Jay Faulkner].
157- - Openstack: do not load some urls twice.
158- - FreeBsd: fix initscripts and add working config file [Harm Weites]
159- - Datasource: fix broken logic to provide hostname if datasource does not
160- provide one
161- - Improved and less verbose logging.
162- - resizefs: first check that device is writable.
163- - configdrive: fix reading of vendor data to be like metadata service reader.
164- [Jay Faulkner]
165- - resizefs: fix broken background resizing [Jay Faulkner] (LP: #1338614)
166- - cc_grub_dpkg: fix EC2 hvm instances to avoid prompt on grub update.
167- (LP: #1336855)
168- - FreeBsd: support config drive datasource [Joseph bajin]
169- - cc_mounts: support creating a swap file
170- - DigitalOcean & GCE: fix get_hostname consistency
171-0.7.5:
172- - open 0.7.5
173- - Add a debug log message around import failures
174- - add a 'debug' module for easily printing out some information about
175- datasource and cloud-init [Shraddha Pandhe]
176- - support running apt with 'eatmydata' via configuration token
177- apt_get_wrapper (LP: #1236531).
178- - convert paths provided in config-drive 'files' to string before writing
179- (LP: #1260072).
180- - Azure: minor changes in logging output. ensure filenames are strings (not
181- unicode).
182- - config/cloud.cfg.d/05_logging.cfg: provide a default 'output' setting, to
183- redirect cloud-init stderr and stdout /var/log/cloud-init-output.log.
184- - drop support for resizing partitions with parted entirely (LP: #1212492).
185- This was broken as it was anyway.
186- - add support for vendordata in SmartOS and NoCloud datasources.
187- - drop dependency on boto for crawling ec2 metadata service.
188- - add 'Requires' on sudo (for OpenNebula datasource) in rpm specs, and
189- 'Recommends' in the debian/control.in [Vlastimil Holer]
190- - if mount_info reports /dev/root is a device path for /, then convert
191- that to a device via help of kernel cmdline.
192- - configdrive: consider partitions as possible datasources if they have
193- theh correct filesystem label. [Paul Querna]
194- - initial freebsd support [Harm Weites]
195- - fix in is_ipv4 to accept IP addresses with a '0' in them.
196- - Azure: fix issue when stale data in /var/lib/waagent (LP: #1269626)
197- - skip config_modules that declare themselves only verified on a set of
198- distros. Add them to 'unverified_modules' list to run anyway.
199- - Add CloudSigma datasource [Kiril Vladimiroff]
200- - Add initial support for Gentoo and Arch distributions [Nate House]
201- - Add GCE datasource [Vaidas Jablonskis]
202- - Add native Openstack datasource which reads openstack metadata
203- rather than relying on EC2 data in openstack metadata service.
204- - SmartOS, AltCloud: disable running on arm systems due to bug
205- (LP: #1243287, #1285686) [Oleg Strikov]
206- - Allow running a command to seed random, default is 'pollinate -q'
207- (LP: #1286316) [Dustin Kirkland]
208- - Write status to /run/cloud-init/status.json for consumption by
209- other programs (LP: #1284439)
210- - Azure: if a reboot causes ephemeral storage to be re-provisioned
211- Then we need to re-format it. (LP: #1292648)
212- - OpenNebula: support base64 encoded user-data
213- [Enol Fernandez, Peter Kotcauer]
214-0.7.4:
215- - fix issue mounting 'ephemeral0' if ephemeral0 was an alias for a
216- partitioned block device with target filesystem on ephemeral0.1.
217- (LP: #1236594)
218- - fix DataSourceAzure incompatibility with 2.6 (LP: #1232175)
219- - fix power_state_change config module so that example works. Improve
220- its documentation and add reference to 'timeout'
221- - support apt-add-archive with 'cloud-archive:' format. (LP: #1244355)
222- - Change SmartOS verb for availability zone (LP: #1249124)
223- - documentation fix for boothooks to use 'cloud-init-per'
224- - fix resizefs module by supporting kernels that do not have
225- /proc/PID/mountinfo. (LP: #1248625) [Tim Daly Jr.]
226- - fix 'make rpm' by removing 0.6.4 entry from ChangeLog (LP: #1241834)
227-0.7.3:
228- - fix omnibus chef installer (LP: #1182265) [Chris Wing]
229- - small fix for OVF datasource for iso transport on non-iso9660 filesystem
230- - determine if upstart version is suitable for
231- 'initctl reload-configuration' (LP: #1124384). If so, then invoke it.
232- supports setting up instance-store disk with partition table and filesystem.
233- - add Azure datasource.
234- - add support for SuSE / SLES [Juerg Haefliger]
235- - add a trailing carriage return to chpasswd input, which reportedly
236- caused a problem on rhel5 if missing.
237- - support individual MIME segments to be gzip compressed (LP: #1203203)
238- - always finalize handlers even if processing failed (LP: #1203368)
239- - support merging into cloud-config via jsonp. (LP: #1200476)
240- - add datasource 'SmartOS' for Joyent Cloud. Adds a dependency on serial.
241- - add 'log_time' helper to util for timing how long things take
242- which also reads from uptime. uptime is useful as clock may change during
243- boot due to ntp.
244- - prefer growpart resizer to 'parted resizepart' (LP: #1212492)
245- - support random data seed from config drive or azure, and a module
246- 'seed_random' to read that and write it to /dev/urandom.
247- - add OpenNebula Datasource [Vlastimil Holer]
248- - add 'cc_disk_setup' config module for paritioning disks and creating
249- filesystems. Useful if attached disks are not formatted (LP: #1218506)
250- - Fix usage of libselinux-python when selinux is disabled. [Garrett Holmstrom]
251- - multi_log: only write to /dev/console if it exists [Garrett Holmstrom]
252- - config/cloud.cfg: add 'sudo' to list groups for the default user
253- (LP: #1228228)
254- - documentation fix for use of 'mkpasswd' [Eric Nordlund]
255- - respect /etc/growroot-disabled file (LP: #1234331)
256-0.7.2:
257- - add a debian watch file
258- - add 'sudo' entry to ubuntu's default user (LP: #1080717)
259- - fix resizefs module when 'noblock' was provided (LP: #1080985)
260- - make sure there is no blank line before cloud-init entry in
261- there are no blank lines in /etc/ca-certificates.conf (LP: #1077020)
262- - fix sudoers writing when entry is a string (LP: #1079002)
263- - tools/write-ssh-key-fingerprints: use '-s' rather than '--stderr'
264- option (LP: #1083715)
265- - make install of puppet configurable (LP: #1090205) [Craig Tracey]
266- - support omnibus installer for chef [Anatoliy Dobrosynets]
267- - fix bug where cloud-config in user-data could not modify system_info
268- settings (LP: #1090482)
269- - fix CloudStack DataSource to use Virtual Router as described by
270- CloudStack documentation if it is available by searching through dhclient
271- lease files. If it is not available, then fall back to the default
272- gateway. (LP: #1089989)
273- - fix redaction of password field in log (LP: #1096417)
274- - fix to cloud-config user setup. Previously, lock_passwd was broken and
275- all accounts would be locked unless 'system' was given (LP: #1096423).
276- - Allow 'sr0' (or sr[0-9]) to be specified without /dev/ as a source for
277- mounts. [Vlastimil Holer]
278- - allow config-drive-data to come from a CD device by more correctly
279- filtering out partitions. (LP: #1100545)
280- - setup docs to be available on read-the-docs
281- https://cloudinit.readthedocs.org/en/latest/ (LP: #1093039)
282- - add HACKING file for information on contributing
283- - handle the legacy 'user:' configuration better, making it affect the
284- configured OS default user (LP: #1100920)
285- - Adding a resolv.conf configuration module (LP: #1100434). Currently only
286- working on redhat systems (no support for resolvconf)
287- - support grouping linux distros into "os_families". This allows a module
288- to operate on the family (redhat or debian) rather than the distro (ubuntu,
289- debian, fedora, rhel) (LP: #1100029)
290- - fix /etc/hosts writing when templates are used (LP: #1100036)
291- - add package versioning logic to package installation
292- functionality (LP: #1108047)
293- - fix documentation for write_files to correctly list 'permissions'
294- rather than 'perms' (LP: #1111205)
295- - cloud-init-container.conf: ensure /run/network before running ifquery
296- - DataSourceNoCloud: allow user-data and meta-data to be specified
297- in config (LP: #1115833).
298- - improve debian support in sysvinit scripts, package build scripts, and
299- split sources.list template to be distro specific.
300- - support for resizing btrfs root filesystems [Blair Zajac]
301- - fix issue when writing ssh keys to .ssh/authorized_keys (LP: #1136343)
302- - upstart: cloud-init-nonet.conf trap the TERM signal, so that dmesg or other
303- output does not get a 'killed by TERM signal' message.
304- - support resizing partitions via growpart or parted (LP: #1136936)
305- - allow specifying apt-get command in distro config ('apt_get_command')
306- - support different and user-suppliable merging algorithms for cloud-config
307- (LP: #1023179)
308- - use python-requests rather than urllib2. By using recent versions of
309- python-requests, we get https support (LP: #1067888).
310- - make apt-get invoke 'dist-upgrade' rather than 'upgrade' for
311- package_upgrade. (LP: #1164147)
312- - improvements for systemd with Fedora 18
313- - workaround 2.6 kernel issue that stopped blkid from showing /dev/sr0
314- - add new, backwards compatible merging syntax so merging of cloud-config
315- can be more useful.
316-
317-0.7.1:
318- - sysvinit: fix missing dependency in cloud-init job for RHEL 5.6
319- - config-drive: map hostname to local-hostname (LP: #1061964)
320- - landscape: install landscape-client package if not installed.
321- only take action if cloud-config is present (LP: #1066115)
322- - cc_landscape: restart landscape after install or config (LP: #1070345)
323- - multipart/archive. do not fail on unknown headers in multipart
324- mime or cloud-archive config (LP: #1065116).
325- - tools/Z99-cloud-locale-test.sh: avoid warning when user's shell is
326- zsh (LP: #1073077)
327- - fix stack trace when unknown user-data input had unicode (LP: #1075756)
328- - split 'apt-update-upgrade' config module into 'apt-configure' and
329- 'package-update-upgrade-install'. The 'package-update-upgrade-install'
330- will be a cross distro module.
331- - Cleanups:
332- - Remove usage of paths.join, as all code should run through util helpers
333- - Fix pylint complaining about tests folder 'helpers.py' not being found
334- - Add a pylintrc file that is used instead options hidden in 'run_pylint'
335- - fix bug where cloud-config from user-data could not affect system_info
336- settings [revno 703] (LP: #1076811)
337- - for write fqdn to system config for rh/fedora [revno 704]
338- - add yaml/cloud config examples checking tool [revno 706]
339- - Fix the merging of group configuration when that group configuration is a
340- dict => members. [revno 707]
341- - add yum_add_repo configuration module for adding additional yum repos
342- - fix public key importing with config-drive-v2 datasource (LP: #1077700)
343- - handle renaming and fixing up of marker names (LP: 1075980) [revno 710]
344- this relieves that burden from the distro/packaging.
345- - group config: fix how group members weren't being translated correctly
346- when the group: [member, member...] format was used (LP: #1077245)
347- - sysconfig: fix how the /etc/sysconfig/network should be using the fully
348- qualified domain name instead of the partially qualified domain name
349- which is used in the ubuntu/debian case (LP: #1076759)
350- - fix how string escaping was not working when the string was a unicode
351- string which was causing the warning message not to be written
352- out (LP: #1075756)
353- - for boto > 0.6.0 there was a lazy load of the metadata added, when
354- cloud-init runs the usage of this lazy loading is hidden and since that lazy
355- loading will be performed on future attribute access we must traverse the
356- lazy loaded dictionary and force it to full expand so that if cloud-init
357- blocks the ec2 metadata port the lazy loaded dictionary will continue
358- working properly instead of trying to make additional url calls which will
359- fail (LP: #1068801)
360- - use a set of helper/parsing classes to perform system configuration
361- for easier test. (/etc/sysconfig, /etc/hostname, resolv.conf, /etc/hosts)
362- - add power_state_change config module for shutting down stystem after
363- cloud-init finishes. (LP: #1064665)
364-0.7.0:
365- - add a 'exception_cb' argument to 'wait_for_url'. If provided, this
366- method will be called back with the exception received and the message.
367- - utilize the 'exception_cb' above to modify the oauth timestamp in
368- DataSourceMAAS requests if a 401 or 403 is received. (LP: #978127)
369- - catch signals and exit rather than stack tracing
370- - if logging fails, enable a fallback logger by patching the logging module
371- - do not 'start networking' in cloud-init-nonet, but add
372- cloud-init-container job that runs only if in container and emits
373- net-device-added (LP: #1031065)
374- - search only top level dns for 'instance-data' in
375- DataSourceEc2 (LP: #1040200)
376- - add support for config-drive-v2 (LP:#1037567)
377- - support creating users, including the default user.
378- [Ben Howard] (LP: #1028503)
379- - add apt_reboot_if_required to reboot if an upgrade or package installation
380- forced the need for one (LP: #1038108)
381- - allow distro mirror selection to include availability-zone (LP: #1037727)
382- - allow arch specific mirror selection (select ports.ubuntu.com on arm)
383- LP: #1028501
384- - allow specification of security mirrors (LP: #1006963)
385- - add the 'None' datasource (LP: #906669), which will allow jobs
386- to run even if there is no "real" datasource found.
387- - write ssh authorized keys to console, ssh_authkey_fingerprints
388- config module [Joshua Harlow] (LP: #1010582)
389- - Added RHEVm and vSphere support as source AltCloud [Joseph VLcek]
390- - add write-files module (LP: #1012854)
391- - Add setuptools + cheetah to debian package build dependencies (LP: #1022101)
392- - Adjust the sysvinit local script to provide 'cloud-init-local' and have
393- the cloud-config script depend on that as well.
394- - Add the 'bzr' name to all packages built
395- - Reduce logging levels for certain non-critical cases to DEBUG instead of the
396- previous level of WARNING
397- - unified binary that activates the various stages
398- - Now using argparse + subcommands to specify the various CLI options
399- - a stage module that clearly separates the stages of the different
400- components (also described how they are used and in what order in the
401- new unified binary)
402- - user_data is now a module that just does user data processing while the
403- actual activation and 'handling' of the processed user data is done via
404- a separate set of files (and modules) with the main 'init' stage being the
405- controller of this
406- - creation of boot_hook, cloud_config, shell_script, upstart_job version 2
407- modules (with classes that perform there functionality) instead of those
408- having functionality that is attached to the cloudinit object (which
409- reduces reuse and limits future functionality, and makes testing harder)
410- - removal of global config that defined paths, shared config, now this is
411- via objects making unit testing testing and global side-effects a non issue
412- - creation of a 'helpers.py'
413- - this contains an abstraction for the 'lock' like objects that the various
414- module/handler running stages use to avoid re-running a given
415- module/handler for a given frequency. this makes it separated from
416- the actual usage of that object (thus helpful for testing and clear lines
417- usage and how the actual job is accomplished)
418- - a common 'runner' class is the main entrypoint using these locks to
419- run function objects passed in (along with there arguments) and there
420- frequency
421- - add in a 'paths' object that provides access to the previously global
422- and/or config based paths (thus providing a single entrypoint object/type
423- that provides path information)
424- - this also adds in the ability to change the path when constructing
425- that path 'object' and adding in additional config that can be used to
426- alter the root paths of 'joins' (useful for testing or possibly useful
427- in chroots?)
428- - config options now avaiable that can alter the 'write_root' and the
429- 'read_root' when backing code uses the paths join() function
430- - add a config parser subclass that will automatically add unknown sections
431- and return default values (instead of throwing exceptions for these cases)
432- - a new config merging class that will be the central object that knows
433- how to do the common configuration merging from the various configuration
434- sources. The order is the following:
435- - cli config files override environment config files
436- which override instance configs which override datasource
437- configs which override base configuration which overrides
438- default configuration.
439- - remove the passing around of the 'cloudinit' object as a 'cloud' variable
440- and instead pass around an 'interface' object that can be given to modules
441- and handlers as there cloud access layer while the backing of that
442- object can be varied (good for abstraction and testing)
443- - use a single set of functions to do importing of modules
444- - add a function in which will search for a given set of module names with
445- a given set of attributes and return those which are found
446- - refactor logging so that instead of using a single top level 'log' that
447- instead each component/module can use its own logger (if desired), this
448- should be backwards compatible with handlers and config modules that used
449- the passed in logger (its still passed in)
450- - ensure that all places where exception are caught and where applicable
451- that the util logexc() is called, so that no exceptions that may occur
452- are dropped without first being logged (where it makes sense for this
453- to happen)
454- - add a 'requires' file that lists cloud-init dependencies
455- - applying it in package creation (bdeb and brpm) as well as using it
456- in the modified setup.py to ensure dependencies are installed when
457- using that method of packaging
458- - add a 'version.py' that lists the active version (in code) so that code
459- inside cloud-init can report the version in messaging and other config files
460- - cleanup of subprocess usage so that all subprocess calls go through the
461- subp() utility method, which now has an exception type that will provide
462- detailed information on python 2.6 and 2.7
463- - forced all code loading, moving, chmod, writing files and other system
464- level actions to go through standard set of util functions, this greatly
465- helps in debugging and determining exactly which system actions cloud-init
466- is performing
467- - adjust url fetching and url trying to go through a single function that
468- reads urls in the new 'url helper' file, this helps in tracing, debugging
469- and knowing which urls are being called and/or posted to from with-in
470- cloud-init code
471- - add in the sending of a 'User-Agent' header for all urls fetched that
472- do not provide there own header mapping, derive this user-agent from
473- the following template, 'Cloud-Init/{version}' where the version is the
474- cloud-init version number
475- - using prettytable for netinfo 'debug' printing since it provides a standard
476- and defined output that should be easier to parse than a custom format
477- - add a set of distro specific classes, that handle distro specific actions
478- that modules and or handler code can use as needed, this is organized into
479- a base abstract class with child classes that implement the shared
480- functionality. config determines exactly which subclass to load, so it can
481- be easily extended as needed.
482- - current functionality
483- - network interface config file writing
484- - hostname setting/updating
485- - locale/timezone/ setting
486- - updating of /etc/hosts (with templates or generically)
487- - package commands (ie installing, removing)/mirror finding
488- - interface up/down activating
489- - implemented a debian + ubuntu subclass
490- - implemented a redhat + fedora subclass
491- - adjust the root 'cloud.cfg' file to now have distrobution/path specific
492- configuration values in it. these special configs are merged as the normal
493- config is, but the system level config is not passed into modules/handlers
494- - modules/handlers must go through the path and distro object instead
495- - have the cloudstack datasource test the url before calling into boto to
496- avoid the long wait for boto to finish retrying and finally fail when
497- the gateway meta-data address is unavailable
498- - add a simple mock ec2 meta-data python based http server that can serve a
499- very simple set of ec2 meta-data back to callers
500- - useful for testing or for understanding what the ec2 meta-data
501- service can provide in terms of data or functionality
502- - for ssh key and authorized key file parsing add in classes and util
503- functions that maintain the state of individual lines, allowing for a
504- clearer separation of parsing and modification (useful for testing and
505- tracing)
506- - add a set of 'base' init.d scripts that can be used on systems that do
507- not have full upstart or systemd support (or support that does not match
508- the standard fedora/ubuntu implementation)
509- - currently these are being tested on RHEL 6.2
510- - separate the datasources into there own subdirectory (instead of being
511- a top-level item), this matches how config 'modules' and user-data
512- 'handlers' are also in there own subdirectory (thus helping new developers
513- and others understand the code layout in a quicker manner)
514- - add the building of rpms based off a new cli tool and template 'spec' file
515- that will templatize and perform the necessary commands to create a source
516- and binary package to be used with a cloud-init install on a 'rpm'
517- supporting system
518- - uses the new standard set of requires and converts those pypi requirements
519- into a local set of package requirments (that are known to exist on RHEL
520- systems but should also exist on fedora systems)
521- - adjust the bdeb builder to be a python script (instead of a shell script)
522- and make its 'control' file a template that takes in the standard set of
523- pypi dependencies and uses a local mapping (known to work on ubuntu) to
524- create the packages set of dependencies (that should also work on
525- ubuntu-like systems)
526- - pythonify a large set of various pieces of code
527- - remove wrapping return statements with () when it has no effect
528- - upper case all constants used
529- - correctly 'case' class and method names (where applicable)
530- - use os.path.join (and similar commands) instead of custom path creation
531- - use 'is None' instead of the frowned upon '== None' which picks up a large
532- set of 'true' cases than is typically desired (ie for objects that have
533- there own equality)
534- - use context managers on locks, tempdir, chdir, file, selinux, umask,
535- unmounting commands so that these actions do not have to be closed and/or
536- cleaned up manually in finally blocks, which is typically not done and
537- will eventually be a bug in the future
538- - use the 'abc' module for abstract classes base where possible
539- - applied in the datasource root class, the distro root class, and the
540- user-data v2 root class
541- - when loading yaml, check that the 'root' type matches a predefined set of
542- valid types (typically just 'dict') and throw a type error if a mismatch
543- occurs, this seems to be a good idea to do when loading user config files
544- - when forking a long running task (ie resizing a filesytem) use a new util
545- function that will fork and then call a callback, instead of having to
546- implement all that code in a non-shared location (thus allowing it to be
547- used by others in the future)
548- - when writing out filenames, go through a util function that will attempt to
549- ensure that the given filename is 'filesystem' safe by replacing '/' with
550- '_' and removing characters which do not match a given whitelist of allowed
551- filename characters
552- - for the varying usages of the 'blkid' command make a function in the util
553- module that can be used as the single point of entry for interaction with
554- that command (and its results) instead of having X separate implementations
555- - place the rfc 8222 time formatting and uptime repeated pieces of code in the
556- util module as a set of function with the name 'time_rfc2822'/'uptime'
557- - separate the pylint+pep8 calling from one tool into two indivudal tools so
558- that they can be called independently, add make file sections that can be
559- used to call these independently
560- - remove the support for the old style config that was previously located in
561- '/etc/ec2-init/ec2-config.cfg', no longer supported!
562- - instead of using a altered config parser that added its own 'dummy' section
563- on in the 'mcollective' module, use configobj which handles the parsing of
564- config without sections better (and it also maintains comments instead of
565- removing them)
566- - use the new defaulting config parser (that will not raise errors on sections
567- that do not exist or return errors when values are fetched that do not
568- exist) in the 'puppet' module
569- - for config 'modules' add in the ability for the module to provide a list of
570- distro names which it is known to work with, if when ran and the distro
571- being used name does not match one of those in this list, a warning will be
572- written out saying that this module may not work correctly on this
573- distrobution
574- - for all dynamically imported modules ensure that they are fixed up before
575- they are used by ensuring that they have certain attributes, if they do not
576- have those attributes they will be set to a sensible set of defaults instead
577- - adjust all 'config' modules and handlers to use the adjusted util functions
578- and the new distro objects where applicable so that those pieces of code can
579- benefit from the unified and enhanced functionality being provided in that
580- util module
581- - fix a potential bug whereby when a #includeonce was encountered it would
582- enable checking of urls against a cache, if later a #include was encountered
583- it would continue checking against that cache, instead of refetching (which
584- would likely be the expected case)
585- - add a openstack/nova based pep8 extension utility ('hacking.py') that allows
586- for custom checks (along with the standard pep8 checks) to occur when
587- running 'make pep8' and its derivatives
588- - support relative path in AuthorizedKeysFile (LP: #970071).
589- - make apt-get update run with --quiet (suitable for logging) (LP: #1012613)
590- - cc_salt_minion: use package 'salt-minion' rather than 'salt' (LP: #996166)
591- - use yaml.safe_load rather than yaml.load (LP: #1015818)
592-0.6.3:
593- - add sample systemd config files [Garrett Holmstrom]
594- - add Fedora support [Garrent Holstrom] (LP: #883286)
595- - fix bug in netinfo.debug_info if no net devices available (LP: #883367)
596- - use python module hashlib rather than md5 to avoid deprecation warnings.
597- - support configuration of mirror based on dns name ubuntu-mirror in
598- local domain.
599- - support setting of Acquire::HTTP::Proxy via 'apt_proxy'
600- - DataSourceEc2: more resilliant to slow metadata service
601- - config change: 'retries' dropped, 'max_wait' added, timeout increased
602- - close stdin in all cloud-init programs that are launched at boot
603- (LP: #903993)
604- - revert management of /etc/hosts to 0.6.1 style (LP: #890501, LP: #871966)
605- - write full ssh keys to console for easy machine consumption (LP: #893400)
606- - put INSTANCE_ID environment variable in bootcmd scripts
607- - add 'cloud-init-per' script for easily running things with a given frequency
608- - replace cloud-init-run-module with cloud-init-per
609- - support configuration of landscape-client via cloud-config (LP: #857366)
610- - part-handlers now get base64 decoded content rather than 2xbase64 encoded
611- in the payload parameter. (LP: #874342)
612- - add test case framework [Mike Milner] (LP: #890851)
613- - fix pylint warnings [Juerg Haefliger] (LP: #914739)
614- - add support for adding and deleting CA Certificates [Mike Milner]
615- (LP: #915232)
616- - in ci-info lines, use '.' to indicate empty field for easier machine reading
617- - support empty lines in "#include" files (LP: #923043)
618- - support configuration of salt minions (Jeff Bauer) (LP: #927795)
619- - DataSourceOVF: only search for OVF data on ISO9660 filesystems (LP: #898373)
620- - DataSourceConfigDrive: support getting data from openstack config drive
621- (LP: #857378)
622- - DataSourceNoCloud: support seed from external disk of ISO or vfat
623- (LP: #857378)
624- - DataSourceNoCloud: support inserting /etc/network/interfaces
625- - DataSourceMaaS: add data source for Ubuntu Machines as a Service (MaaS)
626- (LP: #942061)
627- - DataSourceCloudStack: add support for CloudStack datasource [Cosmin Luta]
628- - add option 'apt_pipelining' to address issue with S3 mirrors
629- (LP: #948461) [Ben Howard]
630- - warn on non-multipart, non-handled user-data [Martin Packman]
631- - run resizefs in the background in order to not block boot (LP: #961226)
632- - Fix bug in Chef support where validation_key was present in config, but
633- 'validation_cert' was not (LP: #960547)
634- - Provide user friendly message when an invalid locale is set
635- [Ben Howard] (LP: #859814)
636- - Support reading cloud-config from kernel command line parameter and
637- populating local file with it, which can then provide data for DataSources
638- - improve chef examples for working configurations on 11.10 and 12.04
639- [Lorin Hochstein] (LP: #960564)
640-
641-0.6.2:
642- - fix bug where update was not done unless update was explicitly set.
643- It would not be run if 'upgrade' or packages were set to be installed
644- - fix bug in part-handler code, that prevented working part-handlers
645- (LP: #739694)
646- - fix bug in resizefs cloud-config that would cause trace based on
647- failure of 'blkid /dev/root' (LP: #726938)
648- - convert dos formated files to unix for user-scripts, boothooks,
649- and upstart jobs (LP: #744965)
650- - fix bug in seeding of grub dpkg configuration (LP: #752361) due
651- to renamed devices in newer (natty) kernels (/dev/sda1 -> /dev/xvda1)
652- - make metadata urls configurable, to support eucalyptus in
653- STATIC or SYSTEM modes (LP: #761847)
654- - support disabling byobu in cloud-config
655- - run cc_ssh as a cloud-init module so it is guaranteed to run before
656- ssh starts (LP: #781101)
657- - make prefix for keys added to /root/.ssh/authorized_keys configurable
658- and add 'no-port-forwarding,no-agent-forwarding,no-X11-forwarding'
659- to the default (LP: #798505)
660- - make 'cloud-config ready' command configurable (LP: #785551)
661- - make fstab fields used to 'fill in' shorthand entries configurable
662- This means you do not have to have 'nobootwait' in the values
663- (LP: #785542)
664- - read /etc/ssh/sshd_config for AuthorizedKeysFile rather than
665- assuming ~/.ssh/authorized_keys (LP: #731849)
666- - fix cloud-init in ubuntu lxc containers (LP: #800824)
667- - sanitize hosts file for system's hostname to 127.0.1.1 (LP: #802637)
668- - add chef support (cloudinit/CloudConfig/cc_chef.py) (LP: ##798844)
669- - do not give trace on failure to resize in lxc container (LP: #800856)
670- - increase the timeout on url gets for "seedfrom" values (LP: #812646)
671- - do not write entries for ephemeral0 on t1.micro (LP: #744019)
672- - support 'include-once' so that expiring or one-time use urls can
673- be used for '#include' to provide sensitive data.
674- - support for passing public and private keys to mcollective via cloud-config
675- - support multiple staticly configured network devices, as long as
676- all of them come up early (LP: #810044)
677- - Changes to handling user data mean that:
678- * boothooks will now run more than once as they were intended (and as
679- bootcmd commands do)
680- * cloud-config and user-scripts will be updated from user data every boot
681- - Fix issue where 'isatty' would return true for apt-add-repository.
682- apt-add-repository would get stdin which was attached to a terminal
683- (/dev/console) and would thus hang when running during boot. (LP: 831505)
684- This was done by changing all users of util.subp to have None input unless
685- specified
686- - Add some debug info to the console when cloud-init runs.
687- This is useful if debugging, IP and route information is printed to the
688- console.
689- - change the mechanism for handling .ssh/authorized_keys, to update entries
690- rather than appending. This ensures that the authorized_keys that are
691- being inserted actually do something (LP: #434076, LP: #833499)
692- - log warning on failure to set hostname (LP: #832175)
693- - upstart/cloud-init-nonet.conf: wait for all network interfaces to be up
694- allow for the possibility of /var/run != /run.
695- - DataSourceNoCloud, DataSourceOVF : do not provide a default hostname.
696- This way the configured hostname of the system will be used if not provided
697- by metadata (LP: #838280)
698- - DataSourceOVF: change the default instance id to 'iid-dsovf' from 'nocloud'
699- - Improve the OVF documentation, and provide a simple command line
700- tool for creating a useful ISO file.
701-
702-0.6.1:
703- - fix bug in fixing permission on /var/log/cloud-init.log (LP: #704509)
704- - improve comment strings in rsyslog file tools/21-cloudinit.conf
705- - add previous-instance-id and previous-datasource files to datadir
706- - add 'datasource' file to instance dir
707- - add setting of passwords and enabling/disabling of PasswordAuthentication
708- for sshd. By default no changes are done to sshd.
709- - fix for puppet configuration options (LP: #709946) [Ryan Lane]
710- - fix pickling of DataSource, which broke seeding.
711- - turn resize_rootfs default to True
712- - avoid mounts in DataSourceOVF if 'read' on device fails
713- 'mount /dev/sr0' for an empty virtual cdrom device was taking 18 seconds
714- - add 'manual_cache_clean' option to select manual cleaning of
715- the /var/lib/cloud/instance/ link, for a data source that might
716- not be present on every boot
717- - make DataSourceEc2 retries and timeout configurable
718- - add helper routines for apt-get update and install
719- - add 'bootcmd' like 'runcmd' to cloud-config syntax for running things early
720- - move from '#opt_include' in config file format to conf_d.
721- ie, now files in /etc/cloud.cfg.d/ is read rather than reading
722- '#opt_include <filename>' or '#include <filename>' in cloud.cfg
723- - allow /etc/hosts to be written from hosts.tmpl. which allows
724- getting local-hostname into /etc/hosts (LP: #720440)
725- - better handle startup if there is no eth0 (LP: #714807)
726- - update rather than append in puppet config [Marc Cluet]
727- - add cloud-config for mcollective [Marc Cluet]
728-0.6.0:
729- - change permissions of /var/log/cloud-init.log to accomodate
730- syslog writing to it (LP: #704509)
731- - rework of /var/lib/cloud layout
732- - remove updates-check (LP: #653220)
733- - support resizing / on first boot (enabled by default)
734- - added support for running CloudConfig modules at cloud-init time
735- rather than cloud-config time, and the new 'cloud_init_modules'
736- entry in cloud.cfg to indicate which should run then.
737- The driving force behind this was to have the rsyslog module
738- able to run before rsyslog even runs so that a restart would
739- not be needed (rsyslog on ubuntu runs on 'filesystem')
740- - moved setting and updating of hostname to cloud_init_modules
741- this allows the user to easily disable these from running.
742- This also means:
743- - the semaphore name for 'set_hostname' and 'update_hostname'
744- changes to 'config_set_hostname' and 'config_update_hostname'
745- - added cloud-config option 'hostname' for setting hostname
746- - moved upstart/cloud-run-user-script.conf to upstart/cloud-final.conf
747- - cloud-final.conf now runs runs cloud-config modules similar
748- to cloud-config and cloud-init.
749- - LP: #653271
750- - added writing of "boot-finished" to /var/lib/cloud/instance/boot-finished
751- this is the last thing done, indicating cloud-init is finished booting
752- - writes message to console with timestamp and uptime
753- - write ssh keys to console as one of the last things done
754- this is to ensure they don't get run off the 'get-console-ouptut' buffer
755- - user_scripts run via cloud-final and thus semaphore renamed from
756- user_scripts to config_user_scripts
757- - add support for redirecting output of cloud-init, cloud-config, cloud-final
758- via the config file, or user data config file
759- - add support for posting data about the instance to a url (phone_home)
760- - add minimal OVF transport (iso) support
761- - make DataSources that are attempted dynamic and configurable from
762- system config. changen "cloud_type: auto" as configuration for this
763- to 'datasource_list: [ "Ec2" ]'. Each of the items in that list
764- must be modules that can be loaded by "DataSource<item>"
765- - add 'timezone' option to cloud-config (LP: #645458)
766- - Added an additional archive format, that can be used for multi-part
767- input to cloud-init. This may be more user friendly then mime-multipart
768- See example in doc/examples/cloud-config-archive.txt (LP: #641504)
769- - add support for reading Rightscale style user data (LP: #668400)
770- and acting on it in cloud-config (cc_rightscale_userdata.py)
771- - make the message on 'disable_root' more clear (LP: #672417)
772- - do not require public key if private is given in ssh cloud-config
773- (LP: #648905)
774-# vi: syntax=text textwidth=79
775
776=== removed file 'HACKING.rst'
777--- HACKING.rst 2014-08-26 18:53:44 +0000
778+++ HACKING.rst 1970-01-01 00:00:00 +0000
779@@ -1,48 +0,0 @@
780-=====================
781-Hacking on cloud-init
782-=====================
783-
784-To get changes into cloud-init, the process to follow is:
785-
786-* If you have not already, be sure to sign the CCA:
787-
788- - `Canonical Contributor Agreement`_
789-
790-* Get your changes into a local bzr branch.
791- Initialize a repo, and checkout trunk (init repo is to share bzr info across multiple checkouts, its different than git):
792-
793- - ``bzr init-repo cloud-init``
794- - ``bzr branch lp:cloud-init trunk.dist``
795- - ``bzr branch trunk.dist my-topic-branch``
796-
797-* Commit your changes (note, you can make multiple commits, fixes, more commits.):
798-
799- - ``bzr commit``
800-
801-* Check pep8 and test, and address any issues:
802-
803- - ``make test pep8``
804-
805-* Push to launchpad to a personal branch:
806-
807- - ``bzr push lp:~<YOUR_USERNAME>/cloud-init/<BRANCH_NAME>``
808-
809-* Propose that for a merge into lp:cloud-init via web browser.
810-
811- - Open the branch in `Launchpad`_
812-
813- - It will typically be at ``https://code.launchpad.net/<YOUR_USERNAME>/<PROJECT>/<BRANCH_NAME>``
814- - ie. https://code.launchpad.net/~smoser/cloud-init/mybranch
815-
816-* Click 'Propose for merging'
817-* Select 'lp:cloud-init' as the target branch
818-
819-Then, someone on cloud-init-dev (currently `Scott Moser`_ and `Joshua Harlow`_) will
820-review your changes and follow up in the merge request.
821-
822-Feel free to ping and/or join #cloud-init on freenode (irc) if you have any questions.
823-
824-.. _Launchpad: https://launchpad.net
825-.. _Canonical Contributor Agreement: http://www.canonical.com/contributors
826-.. _Scott Moser: https://launchpad.net/~smoser
827-.. _Joshua Harlow: https://launchpad.net/~harlowja
828
829=== removed file 'LICENSE'
830--- LICENSE 2011-09-21 19:08:17 +0000
831+++ LICENSE 1970-01-01 00:00:00 +0000
832@@ -1,674 +0,0 @@
833- GNU GENERAL PUBLIC LICENSE
834- Version 3, 29 June 2007
835-
836- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
837- Everyone is permitted to copy and distribute verbatim copies
838- of this license document, but changing it is not allowed.
839-
840- Preamble
841-
842- The GNU General Public License is a free, copyleft license for
843-software and other kinds of works.
844-
845- The licenses for most software and other practical works are designed
846-to take away your freedom to share and change the works. By contrast,
847-the GNU General Public License is intended to guarantee your freedom to
848-share and change all versions of a program--to make sure it remains free
849-software for all its users. We, the Free Software Foundation, use the
850-GNU General Public License for most of our software; it applies also to
851-any other work released this way by its authors. You can apply it to
852-your programs, too.
853-
854- When we speak of free software, we are referring to freedom, not
855-price. Our General Public Licenses are designed to make sure that you
856-have the freedom to distribute copies of free software (and charge for
857-them if you wish), that you receive source code or can get it if you
858-want it, that you can change the software or use pieces of it in new
859-free programs, and that you know you can do these things.
860-
861- To protect your rights, we need to prevent others from denying you
862-these rights or asking you to surrender the rights. Therefore, you have
863-certain responsibilities if you distribute copies of the software, or if
864-you modify it: responsibilities to respect the freedom of others.
865-
866- For example, if you distribute copies of such a program, whether
867-gratis or for a fee, you must pass on to the recipients the same
868-freedoms that you received. You must make sure that they, too, receive
869-or can get the source code. And you must show them these terms so they
870-know their rights.
871-
872- Developers that use the GNU GPL protect your rights with two steps:
873-(1) assert copyright on the software, and (2) offer you this License
874-giving you legal permission to copy, distribute and/or modify it.
875-
876- For the developers' and authors' protection, the GPL clearly explains
877-that there is no warranty for this free software. For both users' and
878-authors' sake, the GPL requires that modified versions be marked as
879-changed, so that their problems will not be attributed erroneously to
880-authors of previous versions.
881-
882- Some devices are designed to deny users access to install or run
883-modified versions of the software inside them, although the manufacturer
884-can do so. This is fundamentally incompatible with the aim of
885-protecting users' freedom to change the software. The systematic
886-pattern of such abuse occurs in the area of products for individuals to
887-use, which is precisely where it is most unacceptable. Therefore, we
888-have designed this version of the GPL to prohibit the practice for those
889-products. If such problems arise substantially in other domains, we
890-stand ready to extend this provision to those domains in future versions
891-of the GPL, as needed to protect the freedom of users.
892-
893- Finally, every program is threatened constantly by software patents.
894-States should not allow patents to restrict development and use of
895-software on general-purpose computers, but in those that do, we wish to
896-avoid the special danger that patents applied to a free program could
897-make it effectively proprietary. To prevent this, the GPL assures that
898-patents cannot be used to render the program non-free.
899-
900- The precise terms and conditions for copying, distribution and
901-modification follow.
902-
903- TERMS AND CONDITIONS
904-
905- 0. Definitions.
906-
907- "This License" refers to version 3 of the GNU General Public License.
908-
909- "Copyright" also means copyright-like laws that apply to other kinds of
910-works, such as semiconductor masks.
911-
912- "The Program" refers to any copyrightable work licensed under this
913-License. Each licensee is addressed as "you". "Licensees" and
914-"recipients" may be individuals or organizations.
915-
916- To "modify" a work means to copy from or adapt all or part of the work
917-in a fashion requiring copyright permission, other than the making of an
918-exact copy. The resulting work is called a "modified version" of the
919-earlier work or a work "based on" the earlier work.
920-
921- A "covered work" means either the unmodified Program or a work based
922-on the Program.
923-
924- To "propagate" a work means to do anything with it that, without
925-permission, would make you directly or secondarily liable for
926-infringement under applicable copyright law, except executing it on a
927-computer or modifying a private copy. Propagation includes copying,
928-distribution (with or without modification), making available to the
929-public, and in some countries other activities as well.
930-
931- To "convey" a work means any kind of propagation that enables other
932-parties to make or receive copies. Mere interaction with a user through
933-a computer network, with no transfer of a copy, is not conveying.
934-
935- An interactive user interface displays "Appropriate Legal Notices"
936-to the extent that it includes a convenient and prominently visible
937-feature that (1) displays an appropriate copyright notice, and (2)
938-tells the user that there is no warranty for the work (except to the
939-extent that warranties are provided), that licensees may convey the
940-work under this License, and how to view a copy of this License. If
941-the interface presents a list of user commands or options, such as a
942-menu, a prominent item in the list meets this criterion.
943-
944- 1. Source Code.
945-
946- The "source code" for a work means the preferred form of the work
947-for making modifications to it. "Object code" means any non-source
948-form of a work.
949-
950- A "Standard Interface" means an interface that either is an official
951-standard defined by a recognized standards body, or, in the case of
952-interfaces specified for a particular programming language, one that
953-is widely used among developers working in that language.
954-
955- The "System Libraries" of an executable work include anything, other
956-than the work as a whole, that (a) is included in the normal form of
957-packaging a Major Component, but which is not part of that Major
958-Component, and (b) serves only to enable use of the work with that
959-Major Component, or to implement a Standard Interface for which an
960-implementation is available to the public in source code form. A
961-"Major Component", in this context, means a major essential component
962-(kernel, window system, and so on) of the specific operating system
963-(if any) on which the executable work runs, or a compiler used to
964-produce the work, or an object code interpreter used to run it.
965-
966- The "Corresponding Source" for a work in object code form means all
967-the source code needed to generate, install, and (for an executable
968-work) run the object code and to modify the work, including scripts to
969-control those activities. However, it does not include the work's
970-System Libraries, or general-purpose tools or generally available free
971-programs which are used unmodified in performing those activities but
972-which are not part of the work. For example, Corresponding Source
973-includes interface definition files associated with source files for
974-the work, and the source code for shared libraries and dynamically
975-linked subprograms that the work is specifically designed to require,
976-such as by intimate data communication or control flow between those
977-subprograms and other parts of the work.
978-
979- The Corresponding Source need not include anything that users
980-can regenerate automatically from other parts of the Corresponding
981-Source.
982-
983- The Corresponding Source for a work in source code form is that
984-same work.
985-
986- 2. Basic Permissions.
987-
988- All rights granted under this License are granted for the term of
989-copyright on the Program, and are irrevocable provided the stated
990-conditions are met. This License explicitly affirms your unlimited
991-permission to run the unmodified Program. The output from running a
992-covered work is covered by this License only if the output, given its
993-content, constitutes a covered work. This License acknowledges your
994-rights of fair use or other equivalent, as provided by copyright law.
995-
996- You may make, run and propagate covered works that you do not
997-convey, without conditions so long as your license otherwise remains
998-in force. You may convey covered works to others for the sole purpose
999-of having them make modifications exclusively for you, or provide you
1000-with facilities for running those works, provided that you comply with
1001-the terms of this License in conveying all material for which you do
1002-not control copyright. Those thus making or running the covered works
1003-for you must do so exclusively on your behalf, under your direction
1004-and control, on terms that prohibit them from making any copies of
1005-your copyrighted material outside their relationship with you.
1006-
1007- Conveying under any other circumstances is permitted solely under
1008-the conditions stated below. Sublicensing is not allowed; section 10
1009-makes it unnecessary.
1010-
1011- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
1012-
1013- No covered work shall be deemed part of an effective technological
1014-measure under any applicable law fulfilling obligations under article
1015-11 of the WIPO copyright treaty adopted on 20 December 1996, or
1016-similar laws prohibiting or restricting circumvention of such
1017-measures.
1018-
1019- When you convey a covered work, you waive any legal power to forbid
1020-circumvention of technological measures to the extent such circumvention
1021-is effected by exercising rights under this License with respect to
1022-the covered work, and you disclaim any intention to limit operation or
1023-modification of the work as a means of enforcing, against the work's
1024-users, your or third parties' legal rights to forbid circumvention of
1025-technological measures.
1026-
1027- 4. Conveying Verbatim Copies.
1028-
1029- You may convey verbatim copies of the Program's source code as you
1030-receive it, in any medium, provided that you conspicuously and
1031-appropriately publish on each copy an appropriate copyright notice;
1032-keep intact all notices stating that this License and any
1033-non-permissive terms added in accord with section 7 apply to the code;
1034-keep intact all notices of the absence of any warranty; and give all
1035-recipients a copy of this License along with the Program.
1036-
1037- You may charge any price or no price for each copy that you convey,
1038-and you may offer support or warranty protection for a fee.
1039-
1040- 5. Conveying Modified Source Versions.
1041-
1042- You may convey a work based on the Program, or the modifications to
1043-produce it from the Program, in the form of source code under the
1044-terms of section 4, provided that you also meet all of these conditions:
1045-
1046- a) The work must carry prominent notices stating that you modified
1047- it, and giving a relevant date.
1048-
1049- b) The work must carry prominent notices stating that it is
1050- released under this License and any conditions added under section
1051- 7. This requirement modifies the requirement in section 4 to
1052- "keep intact all notices".
1053-
1054- c) You must license the entire work, as a whole, under this
1055- License to anyone who comes into possession of a copy. This
1056- License will therefore apply, along with any applicable section 7
1057- additional terms, to the whole of the work, and all its parts,
1058- regardless of how they are packaged. This License gives no
1059- permission to license the work in any other way, but it does not
1060- invalidate such permission if you have separately received it.
1061-
1062- d) If the work has interactive user interfaces, each must display
1063- Appropriate Legal Notices; however, if the Program has interactive
1064- interfaces that do not display Appropriate Legal Notices, your
1065- work need not make them do so.
1066-
1067- A compilation of a covered work with other separate and independent
1068-works, which are not by their nature extensions of the covered work,
1069-and which are not combined with it such as to form a larger program,
1070-in or on a volume of a storage or distribution medium, is called an
1071-"aggregate" if the compilation and its resulting copyright are not
1072-used to limit the access or legal rights of the compilation's users
1073-beyond what the individual works permit. Inclusion of a covered work
1074-in an aggregate does not cause this License to apply to the other
1075-parts of the aggregate.
1076-
1077- 6. Conveying Non-Source Forms.
1078-
1079- You may convey a covered work in object code form under the terms
1080-of sections 4 and 5, provided that you also convey the
1081-machine-readable Corresponding Source under the terms of this License,
1082-in one of these ways:
1083-
1084- a) Convey the object code in, or embodied in, a physical product
1085- (including a physical distribution medium), accompanied by the
1086- Corresponding Source fixed on a durable physical medium
1087- customarily used for software interchange.
1088-
1089- b) Convey the object code in, or embodied in, a physical product
1090- (including a physical distribution medium), accompanied by a
1091- written offer, valid for at least three years and valid for as
1092- long as you offer spare parts or customer support for that product
1093- model, to give anyone who possesses the object code either (1) a
1094- copy of the Corresponding Source for all the software in the
1095- product that is covered by this License, on a durable physical
1096- medium customarily used for software interchange, for a price no
1097- more than your reasonable cost of physically performing this
1098- conveying of source, or (2) access to copy the
1099- Corresponding Source from a network server at no charge.
1100-
1101- c) Convey individual copies of the object code with a copy of the
1102- written offer to provide the Corresponding Source. This
1103- alternative is allowed only occasionally and noncommercially, and
1104- only if you received the object code with such an offer, in accord
1105- with subsection 6b.
1106-
1107- d) Convey the object code by offering access from a designated
1108- place (gratis or for a charge), and offer equivalent access to the
1109- Corresponding Source in the same way through the same place at no
1110- further charge. You need not require recipients to copy the
1111- Corresponding Source along with the object code. If the place to
1112- copy the object code is a network server, the Corresponding Source
1113- may be on a different server (operated by you or a third party)
1114- that supports equivalent copying facilities, provided you maintain
1115- clear directions next to the object code saying where to find the
1116- Corresponding Source. Regardless of what server hosts the
1117- Corresponding Source, you remain obligated to ensure that it is
1118- available for as long as needed to satisfy these requirements.
1119-
1120- e) Convey the object code using peer-to-peer transmission, provided
1121- you inform other peers where the object code and Corresponding
1122- Source of the work are being offered to the general public at no
1123- charge under subsection 6d.
1124-
1125- A separable portion of the object code, whose source code is excluded
1126-from the Corresponding Source as a System Library, need not be
1127-included in conveying the object code work.
1128-
1129- A "User Product" is either (1) a "consumer product", which means any
1130-tangible personal property which is normally used for personal, family,
1131-or household purposes, or (2) anything designed or sold for incorporation
1132-into a dwelling. In determining whether a product is a consumer product,
1133-doubtful cases shall be resolved in favor of coverage. For a particular
1134-product received by a particular user, "normally used" refers to a
1135-typical or common use of that class of product, regardless of the status
1136-of the particular user or of the way in which the particular user
1137-actually uses, or expects or is expected to use, the product. A product
1138-is a consumer product regardless of whether the product has substantial
1139-commercial, industrial or non-consumer uses, unless such uses represent
1140-the only significant mode of use of the product.
1141-
1142- "Installation Information" for a User Product means any methods,
1143-procedures, authorization keys, or other information required to install
1144-and execute modified versions of a covered work in that User Product from
1145-a modified version of its Corresponding Source. The information must
1146-suffice to ensure that the continued functioning of the modified object
1147-code is in no case prevented or interfered with solely because
1148-modification has been made.
1149-
1150- If you convey an object code work under this section in, or with, or
1151-specifically for use in, a User Product, and the conveying occurs as
1152-part of a transaction in which the right of possession and use of the
1153-User Product is transferred to the recipient in perpetuity or for a
1154-fixed term (regardless of how the transaction is characterized), the
1155-Corresponding Source conveyed under this section must be accompanied
1156-by the Installation Information. But this requirement does not apply
1157-if neither you nor any third party retains the ability to install
1158-modified object code on the User Product (for example, the work has
1159-been installed in ROM).
1160-
1161- The requirement to provide Installation Information does not include a
1162-requirement to continue to provide support service, warranty, or updates
1163-for a work that has been modified or installed by the recipient, or for
1164-the User Product in which it has been modified or installed. Access to a
1165-network may be denied when the modification itself materially and
1166-adversely affects the operation of the network or violates the rules and
1167-protocols for communication across the network.
1168-
1169- Corresponding Source conveyed, and Installation Information provided,
1170-in accord with this section must be in a format that is publicly
1171-documented (and with an implementation available to the public in
1172-source code form), and must require no special password or key for
1173-unpacking, reading or copying.
1174-
1175- 7. Additional Terms.
1176-
1177- "Additional permissions" are terms that supplement the terms of this
1178-License by making exceptions from one or more of its conditions.
1179-Additional permissions that are applicable to the entire Program shall
1180-be treated as though they were included in this License, to the extent
1181-that they are valid under applicable law. If additional permissions
1182-apply only to part of the Program, that part may be used separately
1183-under those permissions, but the entire Program remains governed by
1184-this License without regard to the additional permissions.
1185-
1186- When you convey a copy of a covered work, you may at your option
1187-remove any additional permissions from that copy, or from any part of
1188-it. (Additional permissions may be written to require their own
1189-removal in certain cases when you modify the work.) You may place
1190-additional permissions on material, added by you to a covered work,
1191-for which you have or can give appropriate copyright permission.
1192-
1193- Notwithstanding any other provision of this License, for material you
1194-add to a covered work, you may (if authorized by the copyright holders of
1195-that material) supplement the terms of this License with terms:
1196-
1197- a) Disclaiming warranty or limiting liability differently from the
1198- terms of sections 15 and 16 of this License; or
1199-
1200- b) Requiring preservation of specified reasonable legal notices or
1201- author attributions in that material or in the Appropriate Legal
1202- Notices displayed by works containing it; or
1203-
1204- c) Prohibiting misrepresentation of the origin of that material, or
1205- requiring that modified versions of such material be marked in
1206- reasonable ways as different from the original version; or
1207-
1208- d) Limiting the use for publicity purposes of names of licensors or
1209- authors of the material; or
1210-
1211- e) Declining to grant rights under trademark law for use of some
1212- trade names, trademarks, or service marks; or
1213-
1214- f) Requiring indemnification of licensors and authors of that
1215- material by anyone who conveys the material (or modified versions of
1216- it) with contractual assumptions of liability to the recipient, for
1217- any liability that these contractual assumptions directly impose on
1218- those licensors and authors.
1219-
1220- All other non-permissive additional terms are considered "further
1221-restrictions" within the meaning of section 10. If the Program as you
1222-received it, or any part of it, contains a notice stating that it is
1223-governed by this License along with a term that is a further
1224-restriction, you may remove that term. If a license document contains
1225-a further restriction but permits relicensing or conveying under this
1226-License, you may add to a covered work material governed by the terms
1227-of that license document, provided that the further restriction does
1228-not survive such relicensing or conveying.
1229-
1230- If you add terms to a covered work in accord with this section, you
1231-must place, in the relevant source files, a statement of the
1232-additional terms that apply to those files, or a notice indicating
1233-where to find the applicable terms.
1234-
1235- Additional terms, permissive or non-permissive, may be stated in the
1236-form of a separately written license, or stated as exceptions;
1237-the above requirements apply either way.
1238-
1239- 8. Termination.
1240-
1241- You may not propagate or modify a covered work except as expressly
1242-provided under this License. Any attempt otherwise to propagate or
1243-modify it is void, and will automatically terminate your rights under
1244-this License (including any patent licenses granted under the third
1245-paragraph of section 11).
1246-
1247- However, if you cease all violation of this License, then your
1248-license from a particular copyright holder is reinstated (a)
1249-provisionally, unless and until the copyright holder explicitly and
1250-finally terminates your license, and (b) permanently, if the copyright
1251-holder fails to notify you of the violation by some reasonable means
1252-prior to 60 days after the cessation.
1253-
1254- Moreover, your license from a particular copyright holder is
1255-reinstated permanently if the copyright holder notifies you of the
1256-violation by some reasonable means, this is the first time you have
1257-received notice of violation of this License (for any work) from that
1258-copyright holder, and you cure the violation prior to 30 days after
1259-your receipt of the notice.
1260-
1261- Termination of your rights under this section does not terminate the
1262-licenses of parties who have received copies or rights from you under
1263-this License. If your rights have been terminated and not permanently
1264-reinstated, you do not qualify to receive new licenses for the same
1265-material under section 10.
1266-
1267- 9. Acceptance Not Required for Having Copies.
1268-
1269- You are not required to accept this License in order to receive or
1270-run a copy of the Program. Ancillary propagation of a covered work
1271-occurring solely as a consequence of using peer-to-peer transmission
1272-to receive a copy likewise does not require acceptance. However,
1273-nothing other than this License grants you permission to propagate or
1274-modify any covered work. These actions infringe copyright if you do
1275-not accept this License. Therefore, by modifying or propagating a
1276-covered work, you indicate your acceptance of this License to do so.
1277-
1278- 10. Automatic Licensing of Downstream Recipients.
1279-
1280- Each time you convey a covered work, the recipient automatically
1281-receives a license from the original licensors, to run, modify and
1282-propagate that work, subject to this License. You are not responsible
1283-for enforcing compliance by third parties with this License.
1284-
1285- An "entity transaction" is a transaction transferring control of an
1286-organization, or substantially all assets of one, or subdividing an
1287-organization, or merging organizations. If propagation of a covered
1288-work results from an entity transaction, each party to that
1289-transaction who receives a copy of the work also receives whatever
1290-licenses to the work the party's predecessor in interest had or could
1291-give under the previous paragraph, plus a right to possession of the
1292-Corresponding Source of the work from the predecessor in interest, if
1293-the predecessor has it or can get it with reasonable efforts.
1294-
1295- You may not impose any further restrictions on the exercise of the
1296-rights granted or affirmed under this License. For example, you may
1297-not impose a license fee, royalty, or other charge for exercise of
1298-rights granted under this License, and you may not initiate litigation
1299-(including a cross-claim or counterclaim in a lawsuit) alleging that
1300-any patent claim is infringed by making, using, selling, offering for
1301-sale, or importing the Program or any portion of it.
1302-
1303- 11. Patents.
1304-
1305- A "contributor" is a copyright holder who authorizes use under this
1306-License of the Program or a work on which the Program is based. The
1307-work thus licensed is called the contributor's "contributor version".
1308-
1309- A contributor's "essential patent claims" are all patent claims
1310-owned or controlled by the contributor, whether already acquired or
1311-hereafter acquired, that would be infringed by some manner, permitted
1312-by this License, of making, using, or selling its contributor version,
1313-but do not include claims that would be infringed only as a
1314-consequence of further modification of the contributor version. For
1315-purposes of this definition, "control" includes the right to grant
1316-patent sublicenses in a manner consistent with the requirements of
1317-this License.
1318-
1319- Each contributor grants you a non-exclusive, worldwide, royalty-free
1320-patent license under the contributor's essential patent claims, to
1321-make, use, sell, offer for sale, import and otherwise run, modify and
1322-propagate the contents of its contributor version.
1323-
1324- In the following three paragraphs, a "patent license" is any express
1325-agreement or commitment, however denominated, not to enforce a patent
1326-(such as an express permission to practice a patent or covenant not to
1327-sue for patent infringement). To "grant" such a patent license to a
1328-party means to make such an agreement or commitment not to enforce a
1329-patent against the party.
1330-
1331- If you convey a covered work, knowingly relying on a patent license,
1332-and the Corresponding Source of the work is not available for anyone
1333-to copy, free of charge and under the terms of this License, through a
1334-publicly available network server or other readily accessible means,
1335-then you must either (1) cause the Corresponding Source to be so
1336-available, or (2) arrange to deprive yourself of the benefit of the
1337-patent license for this particular work, or (3) arrange, in a manner
1338-consistent with the requirements of this License, to extend the patent
1339-license to downstream recipients. "Knowingly relying" means you have
1340-actual knowledge that, but for the patent license, your conveying the
1341-covered work in a country, or your recipient's use of the covered work
1342-in a country, would infringe one or more identifiable patents in that
1343-country that you have reason to believe are valid.
1344-
1345- If, pursuant to or in connection with a single transaction or
1346-arrangement, you convey, or propagate by procuring conveyance of, a
1347-covered work, and grant a patent license to some of the parties
1348-receiving the covered work authorizing them to use, propagate, modify
1349-or convey a specific copy of the covered work, then the patent license
1350-you grant is automatically extended to all recipients of the covered
1351-work and works based on it.
1352-
1353- A patent license is "discriminatory" if it does not include within
1354-the scope of its coverage, prohibits the exercise of, or is
1355-conditioned on the non-exercise of one or more of the rights that are
1356-specifically granted under this License. You may not convey a covered
1357-work if you are a party to an arrangement with a third party that is
1358-in the business of distributing software, under which you make payment
1359-to the third party based on the extent of your activity of conveying
1360-the work, and under which the third party grants, to any of the
1361-parties who would receive the covered work from you, a discriminatory
1362-patent license (a) in connection with copies of the covered work
1363-conveyed by you (or copies made from those copies), or (b) primarily
1364-for and in connection with specific products or compilations that
1365-contain the covered work, unless you entered into that arrangement,
1366-or that patent license was granted, prior to 28 March 2007.
1367-
1368- Nothing in this License shall be construed as excluding or limiting
1369-any implied license or other defenses to infringement that may
1370-otherwise be available to you under applicable patent law.
1371-
1372- 12. No Surrender of Others' Freedom.
1373-
1374- If conditions are imposed on you (whether by court order, agreement or
1375-otherwise) that contradict the conditions of this License, they do not
1376-excuse you from the conditions of this License. If you cannot convey a
1377-covered work so as to satisfy simultaneously your obligations under this
1378-License and any other pertinent obligations, then as a consequence you may
1379-not convey it at all. For example, if you agree to terms that obligate you
1380-to collect a royalty for further conveying from those to whom you convey
1381-the Program, the only way you could satisfy both those terms and this
1382-License would be to refrain entirely from conveying the Program.
1383-
1384- 13. Use with the GNU Affero General Public License.
1385-
1386- Notwithstanding any other provision of this License, you have
1387-permission to link or combine any covered work with a work licensed
1388-under version 3 of the GNU Affero General Public License into a single
1389-combined work, and to convey the resulting work. The terms of this
1390-License will continue to apply to the part which is the covered work,
1391-but the special requirements of the GNU Affero General Public License,
1392-section 13, concerning interaction through a network will apply to the
1393-combination as such.
1394-
1395- 14. Revised Versions of this License.
1396-
1397- The Free Software Foundation may publish revised and/or new versions of
1398-the GNU General Public License from time to time. Such new versions will
1399-be similar in spirit to the present version, but may differ in detail to
1400-address new problems or concerns.
1401-
1402- Each version is given a distinguishing version number. If the
1403-Program specifies that a certain numbered version of the GNU General
1404-Public License "or any later version" applies to it, you have the
1405-option of following the terms and conditions either of that numbered
1406-version or of any later version published by the Free Software
1407-Foundation. If the Program does not specify a version number of the
1408-GNU General Public License, you may choose any version ever published
1409-by the Free Software Foundation.
1410-
1411- If the Program specifies that a proxy can decide which future
1412-versions of the GNU General Public License can be used, that proxy's
1413-public statement of acceptance of a version permanently authorizes you
1414-to choose that version for the Program.
1415-
1416- Later license versions may give you additional or different
1417-permissions. However, no additional obligations are imposed on any
1418-author or copyright holder as a result of your choosing to follow a
1419-later version.
1420-
1421- 15. Disclaimer of Warranty.
1422-
1423- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
1424-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
1425-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
1426-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
1427-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1428-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
1429-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
1430-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
1431-
1432- 16. Limitation of Liability.
1433-
1434- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
1435-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
1436-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
1437-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
1438-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
1439-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
1440-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
1441-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
1442-SUCH DAMAGES.
1443-
1444- 17. Interpretation of Sections 15 and 16.
1445-
1446- If the disclaimer of warranty and limitation of liability provided
1447-above cannot be given local legal effect according to their terms,
1448-reviewing courts shall apply local law that most closely approximates
1449-an absolute waiver of all civil liability in connection with the
1450-Program, unless a warranty or assumption of liability accompanies a
1451-copy of the Program in return for a fee.
1452-
1453- END OF TERMS AND CONDITIONS
1454-
1455- How to Apply These Terms to Your New Programs
1456-
1457- If you develop a new program, and you want it to be of the greatest
1458-possible use to the public, the best way to achieve this is to make it
1459-free software which everyone can redistribute and change under these terms.
1460-
1461- To do so, attach the following notices to the program. It is safest
1462-to attach them to the start of each source file to most effectively
1463-state the exclusion of warranty; and each file should have at least
1464-the "copyright" line and a pointer to where the full notice is found.
1465-
1466- <one line to give the program's name and a brief idea of what it does.>
1467- Copyright (C) <year> <name of author>
1468-
1469- This program is free software: you can redistribute it and/or modify
1470- it under the terms of the GNU General Public License as published by
1471- the Free Software Foundation, either version 3 of the License, or
1472- (at your option) any later version.
1473-
1474- This program is distributed in the hope that it will be useful,
1475- but WITHOUT ANY WARRANTY; without even the implied warranty of
1476- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1477- GNU General Public License for more details.
1478-
1479- You should have received a copy of the GNU General Public License
1480- along with this program. If not, see <http://www.gnu.org/licenses/>.
1481-
1482-Also add information on how to contact you by electronic and paper mail.
1483-
1484- If the program does terminal interaction, make it output a short
1485-notice like this when it starts in an interactive mode:
1486-
1487- <program> Copyright (C) <year> <name of author>
1488- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
1489- This is free software, and you are welcome to redistribute it
1490- under certain conditions; type `show c' for details.
1491-
1492-The hypothetical commands `show w' and `show c' should show the appropriate
1493-parts of the General Public License. Of course, your program's commands
1494-might be different; for a GUI interface, you would use an "about box".
1495-
1496- You should also get your employer (if you work as a programmer) or school,
1497-if any, to sign a "copyright disclaimer" for the program, if necessary.
1498-For more information on this, and how to apply and follow the GNU GPL, see
1499-<http://www.gnu.org/licenses/>.
1500-
1501- The GNU General Public License does not permit incorporating your program
1502-into proprietary programs. If your program is a subroutine library, you
1503-may consider it more useful to permit linking proprietary applications with
1504-the library. If this is what you want to do, use the GNU Lesser General
1505-Public License instead of this License. But first, please read
1506-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
1507
1508=== removed file 'MANIFEST.in'
1509--- MANIFEST.in 2015-01-21 20:14:24 +0000
1510+++ MANIFEST.in 1970-01-01 00:00:00 +0000
1511@@ -1,8 +0,0 @@
1512-include *.py MANIFEST.in ChangeLog
1513-global-include *.txt *.rst *.ini *.in *.conf *.cfg *.sh
1514-graft tools
1515-prune build
1516-prune dist
1517-prune .tox
1518-prune .bzr
1519-exclude .bzrignore
1520
1521=== removed file 'Makefile'
1522--- Makefile 2016-03-04 06:45:58 +0000
1523+++ Makefile 1970-01-01 00:00:00 +0000
1524@@ -1,82 +0,0 @@
1525-CWD=$(shell pwd)
1526-PYVER ?= 3
1527-noseopts ?= -v
1528-
1529-YAML_FILES=$(shell find cloudinit bin tests tools -name "*.yaml" -type f )
1530-YAML_FILES+=$(shell find doc/examples -name "cloud-config*.txt" -type f )
1531-
1532-CHANGELOG_VERSION=$(shell $(CWD)/tools/read-version)
1533-CODE_VERSION=$(shell python -c "from cloudinit import version; print version.version_string()")
1534-
1535-PIP_INSTALL := pip install
1536-
1537-ifeq ($(PYVER),3)
1538- pyflakes = pyflakes3
1539- unittests = unittest3
1540- yaml = yaml
1541-else
1542-ifeq ($(PYVER),2)
1543- pyflakes = pyflakes
1544- unittests = unittest
1545-else
1546- pyflakes = pyflakes pyflakes3
1547- unittests = unittest unittest3
1548-endif
1549-endif
1550-
1551-ifeq ($(distro),)
1552- distro = redhat
1553-endif
1554-
1555-all: check
1556-
1557-check: check_version pep8 $(pyflakes) test $(yaml)
1558-
1559-pep8:
1560- @$(CWD)/tools/run-pep8
1561-
1562-pyflakes:
1563- @$(CWD)/tools/run-pyflakes
1564-
1565-pyflakes3:
1566- @$(CWD)/tools/run-pyflakes3
1567-
1568-unittest: clean_pyc
1569- nosetests $(noseopts) tests/unittests
1570-
1571-unittest3: clean_pyc
1572- nosetests3 $(noseopts) tests/unittests
1573-
1574-pip-requirements:
1575- @echo "Installing cloud-init dependencies..."
1576- $(PIP_INSTALL) -r "$@.txt" -q
1577-
1578-pip-test-requirements:
1579- @echo "Installing cloud-init test dependencies..."
1580- $(PIP_INSTALL) -r "$@.txt" -q
1581-
1582-test: $(unittests)
1583-
1584-check_version:
1585- @if [ "$(CHANGELOG_VERSION)" != "$(CODE_VERSION)" ]; then \
1586- echo "Error: ChangeLog version $(CHANGELOG_VERSION)" \
1587- "not equal to code version $(CODE_VERSION)"; exit 2; \
1588- else true; fi
1589-
1590-clean_pyc:
1591- @find . -type f -name "*.pyc" -delete
1592-
1593-clean: clean_pyc
1594- rm -rf /var/log/cloud-init.log /var/lib/cloud/
1595-
1596-yaml:
1597- @$(CWD)/tools/validate-yaml.py $(YAML_FILES)
1598-
1599-rpm:
1600- ./packages/brpm --distro $(distro)
1601-
1602-deb:
1603- ./packages/bddeb
1604-
1605-.PHONY: test pyflakes pyflakes3 clean pep8 rpm deb yaml check_version
1606-.PHONY: pip-test-requirements pip-requirements clean_pyc unittest unittest3
1607
1608=== added file 'README'
1609--- README 1970-01-01 00:00:00 +0000
1610+++ README 2016-08-10 14:35:36 +0000
1611@@ -0,0 +1,11 @@
1612+cloud-init development has moved its revision control to git.
1613+It is available at
1614+ https://code.launchpad.net/cloud-init
1615+
1616+Clone with
1617+ git clone https://git.launchpad.net/cloud-init
1618+or
1619+ git clone git+ssh://git.launchpad.net/cloud-ini
1620+
1621+For more information see
1622+ https://git.launchpad.net/cloud-init/tree/HACKING.rst
1623
1624=== removed file 'TODO.rst'
1625--- TODO.rst 2014-07-07 20:03:32 +0000
1626+++ TODO.rst 1970-01-01 00:00:00 +0000
1627@@ -1,43 +0,0 @@
1628-==============================================
1629-Things that cloud-init may do (better) someday
1630-==============================================
1631-
1632-- Consider making ``failsafe`` ``DataSource``
1633- - sets the user password, writing it to console
1634-
1635-- Consider a ``previous`` ``DataSource``, if no other data source is
1636- found, fall back to the ``previous`` one that worked.
1637-- Rewrite ``cloud-init-query`` (currently not implemented)
1638-- Possibly have a ``DataSource`` expose explicit fields:
1639-
1640- - instance-id
1641- - hostname
1642- - mirror
1643- - release
1644- - ssh public keys
1645-
1646-- Remove the conversion of the ubuntu network interface format conversion
1647- to a RH/fedora format and replace it with a top level format that uses
1648- the netcf libraries format instead (which itself knows how to translate
1649- into the specific formats). See for example `netcf`_ which seems to be
1650- an active project that has this capability.
1651-- Replace the ``apt*`` modules with variants that now use the distro classes
1652- to perform distro independent packaging commands (wherever possible).
1653-- Replace some the LOG.debug calls with a LOG.info where appropriate instead
1654- of how right now there is really only 2 levels (``WARN`` and ``DEBUG``)
1655-- Remove the ``cc_`` prefix for config modules, either have them fully
1656- specified (ie ``cloudinit.config.resizefs``) or by default only look in
1657- the ``cloudinit.config`` namespace for these modules (or have a combination
1658- of the above), this avoids having to understand where your modules are
1659- coming from (which can be altered by the current python inclusion path)
1660-- Instead of just warning when a module is being ran on a ``unknown``
1661- distribution perhaps we should not run that module in that case? Or we might
1662- want to start reworking those modules so they will run on all
1663- distributions? Or if that is not the case, then maybe we want to allow
1664- fully specified python paths for modules and start encouraging
1665- packages of ``ubuntu`` modules, packages of ``rhel`` specific modules that
1666- people can add instead of having them all under the cloud-init ``root``
1667- tree? This might encourage more development of other modules instead of
1668- having to go edit the cloud-init code to accomplish this.
1669-
1670-.. _netcf: https://fedorahosted.org/netcf/
1671
1672=== removed directory 'bin'
1673=== removed file 'bin/cloud-init'
1674--- bin/cloud-init 2016-04-15 17:54:05 +0000
1675+++ bin/cloud-init 1970-01-01 00:00:00 +0000
1676@@ -1,673 +0,0 @@
1677-#!/usr/bin/python
1678-# vi: ts=4 expandtab
1679-#
1680-# Copyright (C) 2012 Canonical Ltd.
1681-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
1682-# Copyright (C) 2012 Yahoo! Inc.
1683-#
1684-# Author: Scott Moser <scott.moser@canonical.com>
1685-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
1686-# Author: Joshua Harlow <harlowja@yahoo-inc.com>
1687-#
1688-# This program is free software: you can redistribute it and/or modify
1689-# it under the terms of the GNU General Public License version 3, as
1690-# published by the Free Software Foundation.
1691-#
1692-# This program is distributed in the hope that it will be useful,
1693-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1694-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1695-# GNU General Public License for more details.
1696-#
1697-# You should have received a copy of the GNU General Public License
1698-# along with this program. If not, see <http://www.gnu.org/licenses/>.
1699-
1700-import argparse
1701-import json
1702-import os
1703-import sys
1704-import time
1705-import tempfile
1706-import traceback
1707-
1708-# This is more just for running from the bin folder so that
1709-# cloud-init binary can find the cloudinit module
1710-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(
1711- sys.argv[0]), os.pardir, os.pardir))
1712-if os.path.exists(os.path.join(possible_topdir, "cloudinit", "__init__.py")):
1713- sys.path.insert(0, possible_topdir)
1714-
1715-from cloudinit import patcher
1716-patcher.patch()
1717-
1718-from cloudinit import log as logging
1719-from cloudinit import netinfo
1720-from cloudinit import signal_handler
1721-from cloudinit import sources
1722-from cloudinit import stages
1723-from cloudinit import templater
1724-from cloudinit import util
1725-from cloudinit import reporting
1726-from cloudinit.reporting import events
1727-from cloudinit import version
1728-
1729-from cloudinit.settings import (PER_INSTANCE, PER_ALWAYS, PER_ONCE,
1730- CLOUD_CONFIG)
1731-
1732-
1733-# Pretty little cheetah formatted welcome message template
1734-WELCOME_MSG_TPL = ("Cloud-init v. ${version} running '${action}' at "
1735- "${timestamp}. Up ${uptime} seconds.")
1736-
1737-# Module section template
1738-MOD_SECTION_TPL = "cloud_%s_modules"
1739-
1740-# Things u can query on
1741-QUERY_DATA_TYPES = [
1742- 'data',
1743- 'data_raw',
1744- 'instance_id',
1745-]
1746-
1747-# Frequency shortname to full name
1748-# (so users don't have to remember the full name...)
1749-FREQ_SHORT_NAMES = {
1750- 'instance': PER_INSTANCE,
1751- 'always': PER_ALWAYS,
1752- 'once': PER_ONCE,
1753-}
1754-
1755-LOG = logging.getLogger()
1756-
1757-
1758-# Used for when a logger may not be active
1759-# and we still want to print exceptions...
1760-def print_exc(msg=''):
1761- if msg:
1762- sys.stderr.write("%s\n" % (msg))
1763- sys.stderr.write('-' * 60)
1764- sys.stderr.write("\n")
1765- traceback.print_exc(file=sys.stderr)
1766- sys.stderr.write('-' * 60)
1767- sys.stderr.write("\n")
1768-
1769-
1770-def welcome(action, msg=None):
1771- if not msg:
1772- msg = welcome_format(action)
1773- util.multi_log("%s\n" % (msg),
1774- console=False, stderr=True, log=LOG)
1775- return msg
1776-
1777-
1778-def welcome_format(action):
1779- tpl_params = {
1780- 'version': version.version_string(),
1781- 'uptime': util.uptime(),
1782- 'timestamp': util.time_rfc2822(),
1783- 'action': action,
1784- }
1785- return templater.render_string(WELCOME_MSG_TPL, tpl_params)
1786-
1787-
1788-def extract_fns(args):
1789- # Files are already opened so lets just pass that along
1790- # since it would of broke if it couldn't have
1791- # read that file already...
1792- fn_cfgs = []
1793- if args.files:
1794- for fh in args.files:
1795- # The realpath is more useful in logging
1796- # so lets resolve to that...
1797- fn_cfgs.append(os.path.realpath(fh.name))
1798- return fn_cfgs
1799-
1800-
1801-def run_module_section(mods, action_name, section):
1802- full_section_name = MOD_SECTION_TPL % (section)
1803- (which_ran, failures) = mods.run_section(full_section_name)
1804- total_attempted = len(which_ran) + len(failures)
1805- if total_attempted == 0:
1806- msg = ("No '%s' modules to run"
1807- " under section '%s'") % (action_name, full_section_name)
1808- sys.stderr.write("%s\n" % (msg))
1809- LOG.debug(msg)
1810- return []
1811- else:
1812- LOG.debug("Ran %s modules with %s failures",
1813- len(which_ran), len(failures))
1814- return failures
1815-
1816-
1817-def apply_reporting_cfg(cfg):
1818- if cfg.get('reporting'):
1819- reporting.update_configuration(cfg.get('reporting'))
1820-
1821-
1822-def main_init(name, args):
1823- deps = [sources.DEP_FILESYSTEM, sources.DEP_NETWORK]
1824- if args.local:
1825- deps = [sources.DEP_FILESYSTEM]
1826-
1827- if not args.local:
1828- # See doc/kernel-cmdline.txt
1829- #
1830- # This is used in maas datasource, in "ephemeral" (read-only root)
1831- # environment where the instance netboots to iscsi ro root.
1832- # and the entity that controls the pxe config has to configure
1833- # the maas datasource.
1834- #
1835- # Could be used elsewhere, only works on network based (not local).
1836- root_name = "%s.d" % (CLOUD_CONFIG)
1837- target_fn = os.path.join(root_name, "91_kernel_cmdline_url.cfg")
1838- util.read_write_cmdline_url(target_fn)
1839-
1840- # Cloud-init 'init' stage is broken up into the following sub-stages
1841- # 1. Ensure that the init object fetches its config without errors
1842- # 2. Setup logging/output redirections with resultant config (if any)
1843- # 3. Initialize the cloud-init filesystem
1844- # 4. Check if we can stop early by looking for various files
1845- # 5. Fetch the datasource
1846- # 6. Connect to the current instance location + update the cache
1847- # 7. Consume the userdata (handlers get activated here)
1848- # 8. Construct the modules object
1849- # 9. Adjust any subsequent logging/output redirections using the modules
1850- # objects config as it may be different from init object
1851- # 10. Run the modules for the 'init' stage
1852- # 11. Done!
1853- if not args.local:
1854- w_msg = welcome_format(name)
1855- else:
1856- w_msg = welcome_format("%s-local" % (name))
1857- init = stages.Init(ds_deps=deps, reporter=args.reporter)
1858- # Stage 1
1859- init.read_cfg(extract_fns(args))
1860- # Stage 2
1861- outfmt = None
1862- errfmt = None
1863- try:
1864- LOG.debug("Closing stdin")
1865- util.close_stdin()
1866- (outfmt, errfmt) = util.fixup_output(init.cfg, name)
1867- except:
1868- util.logexc(LOG, "Failed to setup output redirection!")
1869- print_exc("Failed to setup output redirection!")
1870- if args.debug:
1871- # Reset so that all the debug handlers are closed out
1872- LOG.debug(("Logging being reset, this logger may no"
1873- " longer be active shortly"))
1874- logging.resetLogging()
1875- logging.setupLogging(init.cfg)
1876- apply_reporting_cfg(init.cfg)
1877-
1878- # Any log usage prior to setupLogging above did not have local user log
1879- # config applied. We send the welcome message now, as stderr/out have
1880- # been redirected and log now configured.
1881- welcome(name, msg=w_msg)
1882-
1883- # Stage 3
1884- try:
1885- init.initialize()
1886- except Exception:
1887- util.logexc(LOG, "Failed to initialize, likely bad things to come!")
1888- # Stage 4
1889- path_helper = init.paths
1890- if not args.local:
1891- existing = "trust"
1892- sys.stderr.write("%s\n" % (netinfo.debug_info()))
1893- LOG.debug(("Checking to see if files that we need already"
1894- " exist from a previous run that would allow us"
1895- " to stop early."))
1896- stop_files = [
1897- os.path.join(path_helper.get_cpath("data"), "no-net"),
1898- path_helper.get_ipath_cur("obj_pkl"),
1899- ]
1900- existing_files = []
1901- for fn in stop_files:
1902- try:
1903- c = util.load_file(fn)
1904- if len(c):
1905- existing_files.append((fn, len(c)))
1906- except Exception:
1907- pass
1908- if existing_files:
1909- LOG.debug("Exiting early due to the existence of %s files",
1910- existing_files)
1911- return (None, [])
1912- else:
1913- LOG.debug("Execution continuing, no previous run detected that"
1914- " would allow us to stop early.")
1915- else:
1916- existing = "check"
1917- if util.get_cfg_option_bool(init.cfg, 'manual_cache_clean', False):
1918- existing = "trust"
1919-
1920- init.purge_cache()
1921- # Delete the non-net file as well
1922- util.del_file(os.path.join(path_helper.get_cpath("data"), "no-net"))
1923-
1924- # Stage 5
1925- try:
1926- init.fetch(existing=existing)
1927- except sources.DataSourceNotFoundException:
1928- # In the case of 'cloud-init init' without '--local' it is a bit
1929- # more likely that the user would consider it failure if nothing was
1930- # found. When using upstart it will also mentions job failure
1931- # in console log if exit code is != 0.
1932- if args.local:
1933- LOG.debug("No local datasource found")
1934- else:
1935- util.logexc(LOG, ("No instance datasource found!"
1936- " Likely bad things to come!"))
1937- if not args.force:
1938- init.apply_network_config()
1939- if args.local:
1940- return (None, [])
1941- else:
1942- return (None, ["No instance datasource found."])
1943-
1944- if args.local:
1945- if not init.ds_restored:
1946- # if local mode and the datasource was not restored from cache
1947- # (this is not first boot) then apply networking.
1948- init.apply_network_config()
1949- else:
1950- LOG.debug("skipping networking config from restored datasource.")
1951-
1952- # Stage 6
1953- iid = init.instancify()
1954- LOG.debug("%s will now be targeting instance id: %s", name, iid)
1955- init.update()
1956- # Stage 7
1957- try:
1958- # Attempt to consume the data per instance.
1959- # This may run user-data handlers and/or perform
1960- # url downloads and such as needed.
1961- (ran, _results) = init.cloudify().run('consume_data',
1962- init.consume_data,
1963- args=[PER_INSTANCE],
1964- freq=PER_INSTANCE)
1965- if not ran:
1966- # Just consume anything that is set to run per-always
1967- # if nothing ran in the per-instance code
1968- #
1969- # See: https://bugs.launchpad.net/bugs/819507 for a little
1970- # reason behind this...
1971- init.consume_data(PER_ALWAYS)
1972- except Exception:
1973- util.logexc(LOG, "Consuming user data failed!")
1974- return (init.datasource, ["Consuming user data failed!"])
1975-
1976- apply_reporting_cfg(init.cfg)
1977-
1978- # Stage 8 - re-read and apply relevant cloud-config to include user-data
1979- mods = stages.Modules(init, extract_fns(args), reporter=args.reporter)
1980- # Stage 9
1981- try:
1982- outfmt_orig = outfmt
1983- errfmt_orig = errfmt
1984- (outfmt, errfmt) = util.get_output_cfg(mods.cfg, name)
1985- if outfmt_orig != outfmt or errfmt_orig != errfmt:
1986- LOG.warn("Stdout, stderr changing to (%s, %s)", outfmt, errfmt)
1987- (outfmt, errfmt) = util.fixup_output(mods.cfg, name)
1988- except:
1989- util.logexc(LOG, "Failed to re-adjust output redirection!")
1990- logging.setupLogging(mods.cfg)
1991-
1992- # Stage 10
1993- return (init.datasource, run_module_section(mods, name, name))
1994-
1995-
1996-def main_modules(action_name, args):
1997- name = args.mode
1998- # Cloud-init 'modules' stages are broken up into the following sub-stages
1999- # 1. Ensure that the init object fetches its config without errors
2000- # 2. Get the datasource from the init object, if it does
2001- # not exist then that means the main_init stage never
2002- # worked, and thus this stage can not run.
2003- # 3. Construct the modules object
2004- # 4. Adjust any subsequent logging/output redirections using
2005- # the modules objects configuration
2006- # 5. Run the modules for the given stage name
2007- # 6. Done!
2008- w_msg = welcome_format("%s:%s" % (action_name, name))
2009- init = stages.Init(ds_deps=[], reporter=args.reporter)
2010- # Stage 1
2011- init.read_cfg(extract_fns(args))
2012- # Stage 2
2013- try:
2014- init.fetch(existing="trust")
2015- except sources.DataSourceNotFoundException:
2016- # There was no datasource found, theres nothing to do
2017- msg = ('Can not apply stage %s, no datasource found! Likely bad '
2018- 'things to come!' % name)
2019- util.logexc(LOG, msg)
2020- print_exc(msg)
2021- if not args.force:
2022- return [(msg)]
2023- # Stage 3
2024- mods = stages.Modules(init, extract_fns(args), reporter=args.reporter)
2025- # Stage 4
2026- try:
2027- LOG.debug("Closing stdin")
2028- util.close_stdin()
2029- util.fixup_output(mods.cfg, name)
2030- except:
2031- util.logexc(LOG, "Failed to setup output redirection!")
2032- if args.debug:
2033- # Reset so that all the debug handlers are closed out
2034- LOG.debug(("Logging being reset, this logger may no"
2035- " longer be active shortly"))
2036- logging.resetLogging()
2037- logging.setupLogging(mods.cfg)
2038- apply_reporting_cfg(init.cfg)
2039-
2040- # now that logging is setup and stdout redirected, send welcome
2041- welcome(name, msg=w_msg)
2042-
2043- # Stage 5
2044- return run_module_section(mods, name, name)
2045-
2046-
2047-def main_query(name, _args):
2048- raise NotImplementedError(("Action '%s' is not"
2049- " currently implemented") % (name))
2050-
2051-
2052-def main_single(name, args):
2053- # Cloud-init single stage is broken up into the following sub-stages
2054- # 1. Ensure that the init object fetches its config without errors
2055- # 2. Attempt to fetch the datasource (warn if it doesn't work)
2056- # 3. Construct the modules object
2057- # 4. Adjust any subsequent logging/output redirections using
2058- # the modules objects configuration
2059- # 5. Run the single module
2060- # 6. Done!
2061- mod_name = args.name
2062- w_msg = welcome_format(name)
2063- init = stages.Init(ds_deps=[], reporter=args.reporter)
2064- # Stage 1
2065- init.read_cfg(extract_fns(args))
2066- # Stage 2
2067- try:
2068- init.fetch(existing="trust")
2069- except sources.DataSourceNotFoundException:
2070- # There was no datasource found,
2071- # that might be bad (or ok) depending on
2072- # the module being ran (so continue on)
2073- util.logexc(LOG, ("Failed to fetch your datasource,"
2074- " likely bad things to come!"))
2075- print_exc(("Failed to fetch your datasource,"
2076- " likely bad things to come!"))
2077- if not args.force:
2078- return 1
2079- # Stage 3
2080- mods = stages.Modules(init, extract_fns(args), reporter=args.reporter)
2081- mod_args = args.module_args
2082- if mod_args:
2083- LOG.debug("Using passed in arguments %s", mod_args)
2084- mod_freq = args.frequency
2085- if mod_freq:
2086- LOG.debug("Using passed in frequency %s", mod_freq)
2087- mod_freq = FREQ_SHORT_NAMES.get(mod_freq)
2088- # Stage 4
2089- try:
2090- LOG.debug("Closing stdin")
2091- util.close_stdin()
2092- util.fixup_output(mods.cfg, None)
2093- except:
2094- util.logexc(LOG, "Failed to setup output redirection!")
2095- if args.debug:
2096- # Reset so that all the debug handlers are closed out
2097- LOG.debug(("Logging being reset, this logger may no"
2098- " longer be active shortly"))
2099- logging.resetLogging()
2100- logging.setupLogging(mods.cfg)
2101- apply_reporting_cfg(init.cfg)
2102-
2103- # now that logging is setup and stdout redirected, send welcome
2104- welcome(name, msg=w_msg)
2105-
2106- # Stage 5
2107- (which_ran, failures) = mods.run_single(mod_name,
2108- mod_args,
2109- mod_freq)
2110- if failures:
2111- LOG.warn("Ran %s but it failed!", mod_name)
2112- return 1
2113- elif not which_ran:
2114- LOG.warn("Did not run %s, does it exist?", mod_name)
2115- return 1
2116- else:
2117- # Guess it worked
2118- return 0
2119-
2120-
2121-def atomic_write_file(path, content, mode='w'):
2122- tf = None
2123- try:
2124- tf = tempfile.NamedTemporaryFile(dir=os.path.dirname(path),
2125- delete=False, mode=mode)
2126- tf.write(content)
2127- tf.close()
2128- os.rename(tf.name, path)
2129- except Exception as e:
2130- if tf is not None:
2131- os.unlink(tf.name)
2132- raise e
2133-
2134-
2135-def atomic_write_json(path, data):
2136- return atomic_write_file(path, json.dumps(data, indent=1) + "\n")
2137-
2138-
2139-def status_wrapper(name, args, data_d=None, link_d=None):
2140- if data_d is None:
2141- data_d = os.path.normpath("/var/lib/cloud/data")
2142- if link_d is None:
2143- link_d = os.path.normpath("/run/cloud-init")
2144-
2145- status_path = os.path.join(data_d, "status.json")
2146- status_link = os.path.join(link_d, "status.json")
2147- result_path = os.path.join(data_d, "result.json")
2148- result_link = os.path.join(link_d, "result.json")
2149-
2150- util.ensure_dirs((data_d, link_d,))
2151-
2152- (_name, functor) = args.action
2153-
2154- if name == "init":
2155- if args.local:
2156- mode = "init-local"
2157- else:
2158- mode = "init"
2159- elif name == "modules":
2160- mode = "modules-%s" % args.mode
2161- else:
2162- raise ValueError("unknown name: %s" % name)
2163-
2164- modes = ('init', 'init-local', 'modules-config', 'modules-final')
2165-
2166- status = None
2167- if mode == 'init-local':
2168- for f in (status_link, result_link, status_path, result_path):
2169- util.del_file(f)
2170- else:
2171- try:
2172- status = json.loads(util.load_file(status_path))
2173- except:
2174- pass
2175-
2176- if status is None:
2177- nullstatus = {
2178- 'errors': [],
2179- 'start': None,
2180- 'finished': None,
2181- }
2182- status = {'v1': {}}
2183- for m in modes:
2184- status['v1'][m] = nullstatus.copy()
2185- status['v1']['datasource'] = None
2186-
2187- v1 = status['v1']
2188- v1['stage'] = mode
2189- v1[mode]['start'] = time.time()
2190-
2191- atomic_write_json(status_path, status)
2192- util.sym_link(os.path.relpath(status_path, link_d), status_link,
2193- force=True)
2194-
2195- try:
2196- ret = functor(name, args)
2197- if mode in ('init', 'init-local'):
2198- (datasource, errors) = ret
2199- if datasource is not None:
2200- v1['datasource'] = str(datasource)
2201- else:
2202- errors = ret
2203-
2204- v1[mode]['errors'] = [str(e) for e in errors]
2205-
2206- except Exception as e:
2207- util.logexc(LOG, "failed of stage %s", mode)
2208- print_exc("failed run of stage %s" % mode)
2209- v1[mode]['errors'] = [str(e)]
2210-
2211- v1[mode]['finished'] = time.time()
2212- v1['stage'] = None
2213-
2214- atomic_write_json(status_path, status)
2215-
2216- if mode == "modules-final":
2217- # write the 'finished' file
2218- errors = []
2219- for m in modes:
2220- if v1[m]['errors']:
2221- errors.extend(v1[m].get('errors', []))
2222-
2223- atomic_write_json(result_path,
2224- {'v1': {'datasource': v1['datasource'],
2225- 'errors': errors}})
2226- util.sym_link(os.path.relpath(result_path, link_d), result_link,
2227- force=True)
2228-
2229- return len(v1[mode]['errors'])
2230-
2231-
2232-def main():
2233- parser = argparse.ArgumentParser()
2234-
2235- # Top level args
2236- parser.add_argument('--version', '-v', action='version',
2237- version='%(prog)s ' + (version.version_string()))
2238- parser.add_argument('--file', '-f', action='append',
2239- dest='files',
2240- help=('additional yaml configuration'
2241- ' files to use'),
2242- type=argparse.FileType('rb'))
2243- parser.add_argument('--debug', '-d', action='store_true',
2244- help=('show additional pre-action'
2245- ' logging (default: %(default)s)'),
2246- default=False)
2247- parser.add_argument('--force', action='store_true',
2248- help=('force running even if no datasource is'
2249- ' found (use at your own risk)'),
2250- dest='force',
2251- default=False)
2252-
2253- parser.set_defaults(reporter=None)
2254- subparsers = parser.add_subparsers()
2255-
2256- # Each action and its sub-options (if any)
2257- parser_init = subparsers.add_parser('init',
2258- help=('initializes cloud-init and'
2259- ' performs initial modules'))
2260- parser_init.add_argument("--local", '-l', action='store_true',
2261- help="start in local mode (default: %(default)s)",
2262- default=False)
2263- # This is used so that we can know which action is selected +
2264- # the functor to use to run this subcommand
2265- parser_init.set_defaults(action=('init', main_init))
2266-
2267- # These settings are used for the 'config' and 'final' stages
2268- parser_mod = subparsers.add_parser('modules',
2269- help=('activates modules using '
2270- 'a given configuration key'))
2271- parser_mod.add_argument("--mode", '-m', action='store',
2272- help=("module configuration name "
2273- "to use (default: %(default)s)"),
2274- default='config',
2275- choices=('init', 'config', 'final'))
2276- parser_mod.set_defaults(action=('modules', main_modules))
2277-
2278- # These settings are used when you want to query information
2279- # stored in the cloud-init data objects/directories/files
2280- parser_query = subparsers.add_parser('query',
2281- help=('query information stored '
2282- 'in cloud-init'))
2283- parser_query.add_argument("--name", '-n', action="store",
2284- help="item name to query on",
2285- required=True,
2286- choices=QUERY_DATA_TYPES)
2287- parser_query.set_defaults(action=('query', main_query))
2288-
2289- # This subcommand allows you to run a single module
2290- parser_single = subparsers.add_parser('single',
2291- help=('run a single module '))
2292- parser_single.set_defaults(action=('single', main_single))
2293- parser_single.add_argument("--name", '-n', action="store",
2294- help="module name to run",
2295- required=True)
2296- parser_single.add_argument("--frequency", action="store",
2297- help=("frequency of the module"),
2298- required=False,
2299- choices=list(FREQ_SHORT_NAMES.keys()))
2300- parser_single.add_argument("--report", action="store_true",
2301- help="enable reporting",
2302- required=False)
2303- parser_single.add_argument("module_args", nargs="*",
2304- metavar='argument',
2305- help=('any additional arguments to'
2306- ' pass to this module'))
2307- parser_single.set_defaults(action=('single', main_single))
2308-
2309- args = parser.parse_args()
2310-
2311- # Setup basic logging to start (until reinitialized)
2312- # iff in debug mode...
2313- if args.debug:
2314- logging.setupBasicLogging()
2315-
2316- # Setup signal handlers before running
2317- signal_handler.attach_handlers()
2318-
2319- if not hasattr(args, 'action'):
2320- parser.error('too few arguments')
2321- (name, functor) = args.action
2322- if name in ("modules", "init"):
2323- functor = status_wrapper
2324-
2325- report_on = True
2326- if name == "init":
2327- if args.local:
2328- rname, rdesc = ("init-local", "searching for local datasources")
2329- else:
2330- rname, rdesc = ("init-network",
2331- "searching for network datasources")
2332- elif name == "modules":
2333- rname, rdesc = ("modules-%s" % args.mode,
2334- "running modules for %s" % args.mode)
2335- elif name == "single":
2336- rname, rdesc = ("single/%s" % args.name,
2337- "running single module %s" % args.name)
2338- report_on = args.report
2339-
2340- args.reporter = events.ReportEventStack(
2341- rname, rdesc, reporting_enabled=report_on)
2342- with args.reporter:
2343- return util.log_time(
2344- logfunc=LOG.debug, msg="cloud-init mode '%s'" % name,
2345- get_uptime=True, func=functor, args=(name, args))
2346-
2347-
2348-if __name__ == '__main__':
2349- sys.exit(main())
2350
2351=== removed file 'cloudinit/__init__.py'
2352--- cloudinit/__init__.py 2012-06-29 18:29:37 +0000
2353+++ cloudinit/__init__.py 1970-01-01 00:00:00 +0000
2354@@ -1,21 +0,0 @@
2355-# vi: ts=4 expandtab
2356-#
2357-# Copyright (C) 2012 Canonical Ltd.
2358-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
2359-# Copyright (C) 2012 Yahoo! Inc.
2360-#
2361-# Author: Scott Moser <scott.moser@canonical.com>
2362-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
2363-# Author: Joshua Harlow <harlowja@yahoo-inc.com>
2364-#
2365-# This program is free software: you can redistribute it and/or modify
2366-# it under the terms of the GNU General Public License version 3, as
2367-# published by the Free Software Foundation.
2368-#
2369-# This program is distributed in the hope that it will be useful,
2370-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2371-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2372-# GNU General Public License for more details.
2373-#
2374-# You should have received a copy of the GNU General Public License
2375-# along with this program. If not, see <http://www.gnu.org/licenses/>.
2376
2377=== removed file 'cloudinit/cloud.py'
2378--- cloudinit/cloud.py 2015-08-31 17:33:30 +0000
2379+++ cloudinit/cloud.py 1970-01-01 00:00:00 +0000
2380@@ -1,109 +0,0 @@
2381-# vi: ts=4 expandtab
2382-#
2383-# Copyright (C) 2012 Canonical Ltd.
2384-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
2385-# Copyright (C) 2012 Yahoo! Inc.
2386-#
2387-# Author: Scott Moser <scott.moser@canonical.com>
2388-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
2389-# Author: Joshua Harlow <harlowja@yahoo-inc.com>
2390-#
2391-# This program is free software: you can redistribute it and/or modify
2392-# it under the terms of the GNU General Public License version 3, as
2393-# published by the Free Software Foundation.
2394-#
2395-# This program is distributed in the hope that it will be useful,
2396-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2397-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2398-# GNU General Public License for more details.
2399-#
2400-# You should have received a copy of the GNU General Public License
2401-# along with this program. If not, see <http://www.gnu.org/licenses/>.
2402-
2403-import copy
2404-import os
2405-
2406-from cloudinit import log as logging
2407-from cloudinit.reporting import events
2408-
2409-LOG = logging.getLogger(__name__)
2410-
2411-# This class is the high level wrapper that provides
2412-# access to cloud-init objects without exposing the stage objects
2413-# to handler and or module manipulation. It allows for cloud
2414-# init to restrict what those types of user facing code may see
2415-# and or adjust (which helps avoid code messing with each other)
2416-#
2417-# It also provides util functions that avoid having to know
2418-# how to get a certain member from this submembers as well
2419-# as providing a backwards compatible object that can be maintained
2420-# while the stages/other objects can be worked on independently...
2421-
2422-
2423-class Cloud(object):
2424- def __init__(self, datasource, paths, cfg, distro, runners, reporter=None):
2425- self.datasource = datasource
2426- self.paths = paths
2427- self.distro = distro
2428- self._cfg = cfg
2429- self._runners = runners
2430- if reporter is None:
2431- reporter = events.ReportEventStack(
2432- name="unnamed-cloud-reporter",
2433- description="unnamed-cloud-reporter",
2434- reporting_enabled=False)
2435- self.reporter = reporter
2436-
2437- # If a 'user' manipulates logging or logging services
2438- # it is typically useful to cause the logging to be
2439- # setup again.
2440- def cycle_logging(self):
2441- logging.resetLogging()
2442- logging.setupLogging(self.cfg)
2443-
2444- @property
2445- def cfg(self):
2446- # Ensure that not indirectly modified
2447- return copy.deepcopy(self._cfg)
2448-
2449- def run(self, name, functor, args, freq=None, clear_on_fail=False):
2450- return self._runners.run(name, functor, args, freq, clear_on_fail)
2451-
2452- def get_template_filename(self, name):
2453- fn = self.paths.template_tpl % (name)
2454- if not os.path.isfile(fn):
2455- LOG.warn("No template found at %s for template named %s", fn, name)
2456- return None
2457- return fn
2458-
2459- # The rest of thes are just useful proxies
2460- def get_userdata(self, apply_filter=True):
2461- return self.datasource.get_userdata(apply_filter)
2462-
2463- def get_instance_id(self):
2464- return self.datasource.get_instance_id()
2465-
2466- @property
2467- def launch_index(self):
2468- return self.datasource.launch_index
2469-
2470- def get_public_ssh_keys(self):
2471- return self.datasource.get_public_ssh_keys()
2472-
2473- def get_locale(self):
2474- return self.datasource.get_locale()
2475-
2476- def get_hostname(self, fqdn=False):
2477- return self.datasource.get_hostname(fqdn=fqdn)
2478-
2479- def device_name_to_device(self, name):
2480- return self.datasource.device_name_to_device(name)
2481-
2482- def get_ipath_cur(self, name=None):
2483- return self.paths.get_ipath_cur(name)
2484-
2485- def get_cpath(self, name=None):
2486- return self.paths.get_cpath(name)
2487-
2488- def get_ipath(self, name=None):
2489- return self.paths.get_ipath(name)
2490
2491=== removed file 'cloudinit/config/__init__.py'
2492--- cloudinit/config/__init__.py 2013-01-15 21:08:43 +0000
2493+++ cloudinit/config/__init__.py 1970-01-01 00:00:00 +0000
2494@@ -1,58 +0,0 @@
2495-# vi: ts=4 expandtab
2496-#
2497-# Copyright (C) 2008-2010 Canonical Ltd.
2498-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
2499-#
2500-# Author: Chuck Short <chuck.short@canonical.com>
2501-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
2502-#
2503-# This program is free software: you can redistribute it and/or modify
2504-# it under the terms of the GNU General Public License version 3, as
2505-# published by the Free Software Foundation.
2506-#
2507-# This program is distributed in the hope that it will be useful,
2508-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2509-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2510-# GNU General Public License for more details.
2511-#
2512-# You should have received a copy of the GNU General Public License
2513-# along with this program. If not, see <http://www.gnu.org/licenses/>.
2514-#
2515-
2516-from cloudinit.settings import (PER_INSTANCE, FREQUENCIES)
2517-
2518-from cloudinit import log as logging
2519-
2520-LOG = logging.getLogger(__name__)
2521-
2522-# This prefix is used to make it less
2523-# of a chance that when importing
2524-# we will not find something else with the same
2525-# name in the lookup path...
2526-MOD_PREFIX = "cc_"
2527-
2528-
2529-def form_module_name(name):
2530- canon_name = name.replace("-", "_")
2531- if canon_name.lower().endswith(".py"):
2532- canon_name = canon_name[0:(len(canon_name) - 3)]
2533- canon_name = canon_name.strip()
2534- if not canon_name:
2535- return None
2536- if not canon_name.startswith(MOD_PREFIX):
2537- canon_name = '%s%s' % (MOD_PREFIX, canon_name)
2538- return canon_name
2539-
2540-
2541-def fixup_module(mod, def_freq=PER_INSTANCE):
2542- if not hasattr(mod, 'frequency'):
2543- setattr(mod, 'frequency', def_freq)
2544- else:
2545- freq = mod.frequency
2546- if freq and freq not in FREQUENCIES:
2547- LOG.warn("Module %s has an unknown frequency %s", mod, freq)
2548- if not hasattr(mod, 'distros'):
2549- setattr(mod, 'distros', [])
2550- if not hasattr(mod, 'osfamilies'):
2551- setattr(mod, 'osfamilies', [])
2552- return mod
2553
2554=== removed file 'cloudinit/config/cc_apt_configure.py'
2555--- cloudinit/config/cc_apt_configure.py 2016-05-12 17:56:26 +0000
2556+++ cloudinit/config/cc_apt_configure.py 1970-01-01 00:00:00 +0000
2557@@ -1,292 +0,0 @@
2558-# vi: ts=4 expandtab
2559-#
2560-# Copyright (C) 2009-2010 Canonical Ltd.
2561-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
2562-#
2563-# Author: Scott Moser <scott.moser@canonical.com>
2564-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
2565-#
2566-# This program is free software: you can redistribute it and/or modify
2567-# it under the terms of the GNU General Public License version 3, as
2568-# published by the Free Software Foundation.
2569-#
2570-# This program is distributed in the hope that it will be useful,
2571-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2572-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2573-# GNU General Public License for more details.
2574-#
2575-# You should have received a copy of the GNU General Public License
2576-# along with this program. If not, see <http://www.gnu.org/licenses/>.
2577-
2578-import glob
2579-import os
2580-import re
2581-
2582-from cloudinit import templater
2583-from cloudinit import util
2584-
2585-distros = ['ubuntu', 'debian']
2586-
2587-PROXY_TPL = "Acquire::HTTP::Proxy \"%s\";\n"
2588-APT_CONFIG_FN = "/etc/apt/apt.conf.d/94cloud-init-config"
2589-APT_PROXY_FN = "/etc/apt/apt.conf.d/95cloud-init-proxy"
2590-
2591-# this will match 'XXX:YYY' (ie, 'cloud-archive:foo' or 'ppa:bar')
2592-ADD_APT_REPO_MATCH = r"^[\w-]+:\w"
2593-
2594-# A temporary shell program to get a given gpg key
2595-# from a given keyserver
2596-EXPORT_GPG_KEYID = """
2597- k=${1} ks=${2};
2598- exec 2>/dev/null
2599- [ -n "$k" ] || exit 1;
2600- armour=$(gpg --list-keys --armour "${k}")
2601- if [ -z "${armour}" ]; then
2602- gpg --keyserver ${ks} --recv $k >/dev/null &&
2603- armour=$(gpg --export --armour "${k}") &&
2604- gpg --batch --yes --delete-keys "${k}"
2605- fi
2606- [ -n "${armour}" ] && echo "${armour}"
2607-"""
2608-
2609-
2610-def handle(name, cfg, cloud, log, _args):
2611- if util.is_false(cfg.get('apt_configure_enabled', True)):
2612- log.debug("Skipping module named %s, disabled by config.", name)
2613- return
2614-
2615- release = get_release()
2616- mirrors = find_apt_mirror_info(cloud, cfg)
2617- if not mirrors or "primary" not in mirrors:
2618- log.debug(("Skipping module named %s,"
2619- " no package 'mirror' located"), name)
2620- return
2621-
2622- # backwards compatibility
2623- mirror = mirrors["primary"]
2624- mirrors["mirror"] = mirror
2625-
2626- log.debug("Mirror info: %s" % mirrors)
2627-
2628- if not util.get_cfg_option_bool(cfg,
2629- 'apt_preserve_sources_list', False):
2630- generate_sources_list(release, mirrors, cloud, log)
2631- old_mirrors = cfg.get('apt_old_mirrors',
2632- {"primary": "archive.ubuntu.com/ubuntu",
2633- "security": "security.ubuntu.com/ubuntu"})
2634- rename_apt_lists(old_mirrors, mirrors)
2635-
2636- try:
2637- apply_apt_config(cfg, APT_PROXY_FN, APT_CONFIG_FN)
2638- except Exception as e:
2639- log.warn("failed to proxy or apt config info: %s", e)
2640-
2641- # Process 'apt_sources'
2642- if 'apt_sources' in cfg:
2643- params = mirrors
2644- params['RELEASE'] = release
2645- params['MIRROR'] = mirror
2646-
2647- matchcfg = cfg.get('add_apt_repo_match', ADD_APT_REPO_MATCH)
2648- if matchcfg:
2649- matcher = re.compile(matchcfg).search
2650- else:
2651- def matcher(x):
2652- return False
2653-
2654- errors = add_sources(cfg['apt_sources'], params,
2655- aa_repo_match=matcher)
2656- for e in errors:
2657- log.warn("Add source error: %s", ':'.join(e))
2658-
2659- dconf_sel = util.get_cfg_option_str(cfg, 'debconf_selections', False)
2660- if dconf_sel:
2661- log.debug("Setting debconf selections per cloud config")
2662- try:
2663- util.subp(('debconf-set-selections', '-'), dconf_sel)
2664- except Exception:
2665- util.logexc(log, "Failed to run debconf-set-selections")
2666-
2667-
2668-# get gpg keyid from keyserver
2669-def getkeybyid(keyid, keyserver):
2670- with util.ExtendedTemporaryFile(suffix='.sh', mode="w+", ) as fh:
2671- fh.write(EXPORT_GPG_KEYID)
2672- fh.flush()
2673- cmd = ['/bin/sh', fh.name, keyid, keyserver]
2674- (stdout, _stderr) = util.subp(cmd)
2675- return stdout.strip()
2676-
2677-
2678-def mirror2lists_fileprefix(mirror):
2679- string = mirror
2680- # take off http:// or ftp://
2681- if string.endswith("/"):
2682- string = string[0:-1]
2683- pos = string.find("://")
2684- if pos >= 0:
2685- string = string[pos + 3:]
2686- string = string.replace("/", "_")
2687- return string
2688-
2689-
2690-def rename_apt_lists(old_mirrors, new_mirrors, lists_d="/var/lib/apt/lists"):
2691- for (name, omirror) in old_mirrors.items():
2692- nmirror = new_mirrors.get(name)
2693- if not nmirror:
2694- continue
2695- oprefix = os.path.join(lists_d, mirror2lists_fileprefix(omirror))
2696- nprefix = os.path.join(lists_d, mirror2lists_fileprefix(nmirror))
2697- if oprefix == nprefix:
2698- continue
2699- olen = len(oprefix)
2700- for filename in glob.glob("%s_*" % oprefix):
2701- util.rename(filename, "%s%s" % (nprefix, filename[olen:]))
2702-
2703-
2704-def get_release():
2705- (stdout, _stderr) = util.subp(['lsb_release', '-cs'])
2706- return stdout.strip()
2707-
2708-
2709-def generate_sources_list(codename, mirrors, cloud, log):
2710- template_fn = cloud.get_template_filename('sources.list.%s' %
2711- (cloud.distro.name))
2712- if not template_fn:
2713- template_fn = cloud.get_template_filename('sources.list')
2714- if not template_fn:
2715- log.warn("No template found, not rendering /etc/apt/sources.list")
2716- return
2717-
2718- params = {'codename': codename}
2719- for k in mirrors:
2720- params[k] = mirrors[k]
2721- templater.render_to_file(template_fn, '/etc/apt/sources.list', params)
2722-
2723-
2724-def add_sources(srclist, template_params=None, aa_repo_match=None):
2725- """
2726- add entries in /etc/apt/sources.list.d for each abbreviated
2727- sources.list entry in 'srclist'. When rendering template, also
2728- include the values in dictionary searchList
2729- """
2730- if template_params is None:
2731- template_params = {}
2732-
2733- if aa_repo_match is None:
2734- def aa_repo_match(x):
2735- return False
2736-
2737- errorlist = []
2738- for ent in srclist:
2739- if 'source' not in ent:
2740- errorlist.append(["", "missing source"])
2741- continue
2742-
2743- source = ent['source']
2744- source = templater.render_string(source, template_params)
2745-
2746- if aa_repo_match(source):
2747- try:
2748- util.subp(["add-apt-repository", source])
2749- except util.ProcessExecutionError as e:
2750- errorlist.append([source,
2751- ("add-apt-repository failed. " + str(e))])
2752- continue
2753-
2754- if 'filename' not in ent:
2755- ent['filename'] = 'cloud_config_sources.list'
2756-
2757- if not ent['filename'].startswith("/"):
2758- ent['filename'] = os.path.join("/etc/apt/sources.list.d/",
2759- ent['filename'])
2760-
2761- if ('keyid' in ent and 'key' not in ent):
2762- ks = "keyserver.ubuntu.com"
2763- if 'keyserver' in ent:
2764- ks = ent['keyserver']
2765- try:
2766- ent['key'] = getkeybyid(ent['keyid'], ks)
2767- except Exception:
2768- errorlist.append([source, "failed to get key from %s" % ks])
2769- continue
2770-
2771- if 'key' in ent:
2772- try:
2773- util.subp(('apt-key', 'add', '-'), ent['key'])
2774- except Exception:
2775- errorlist.append([source, "failed add key"])
2776-
2777- try:
2778- contents = "%s\n" % (source)
2779- util.write_file(ent['filename'], contents, omode="ab")
2780- except Exception:
2781- errorlist.append([source,
2782- "failed write to file %s" % ent['filename']])
2783-
2784- return errorlist
2785-
2786-
2787-def find_apt_mirror_info(cloud, cfg):
2788- """find an apt_mirror given the cloud and cfg provided."""
2789-
2790- mirror = None
2791-
2792- # this is less preferred way of specifying mirror preferred would be to
2793- # use the distro's search or package_mirror.
2794- mirror = cfg.get("apt_mirror", None)
2795-
2796- search = cfg.get("apt_mirror_search", None)
2797- if not mirror and search:
2798- mirror = util.search_for_mirror(search)
2799-
2800- if (not mirror and
2801- util.get_cfg_option_bool(cfg, "apt_mirror_search_dns", False)):
2802- mydom = ""
2803- doms = []
2804-
2805- # if we have a fqdn, then search its domain portion first
2806- (_hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud)
2807- mydom = ".".join(fqdn.split(".")[1:])
2808- if mydom:
2809- doms.append(".%s" % mydom)
2810-
2811- doms.extend((".localdomain", "",))
2812-
2813- mirror_list = []
2814- distro = cloud.distro.name
2815- mirrorfmt = "http://%s-mirror%s/%s" % (distro, "%s", distro)
2816- for post in doms:
2817- mirror_list.append(mirrorfmt % (post))
2818-
2819- mirror = util.search_for_mirror(mirror_list)
2820-
2821- mirror_info = cloud.datasource.get_package_mirror_info()
2822-
2823- # this is a bit strange.
2824- # if mirror is set, then one of the legacy options above set it
2825- # but they do not cover security. so we need to get that from
2826- # get_package_mirror_info
2827- if mirror:
2828- mirror_info.update({'primary': mirror})
2829-
2830- return mirror_info
2831-
2832-
2833-def apply_apt_config(cfg, proxy_fname, config_fname):
2834- # Set up any apt proxy
2835- cfgs = (('apt_proxy', 'Acquire::HTTP::Proxy "%s";'),
2836- ('apt_http_proxy', 'Acquire::HTTP::Proxy "%s";'),
2837- ('apt_ftp_proxy', 'Acquire::FTP::Proxy "%s";'),
2838- ('apt_https_proxy', 'Acquire::HTTPS::Proxy "%s";'))
2839-
2840- proxies = [fmt % cfg.get(name) for (name, fmt) in cfgs if cfg.get(name)]
2841- if len(proxies):
2842- util.write_file(proxy_fname, '\n'.join(proxies) + '\n')
2843- elif os.path.isfile(proxy_fname):
2844- util.del_file(proxy_fname)
2845-
2846- if cfg.get('apt_config', None):
2847- util.write_file(config_fname, cfg.get('apt_config'))
2848- elif os.path.isfile(config_fname):
2849- util.del_file(config_fname)
2850
2851=== removed file 'cloudinit/config/cc_apt_pipelining.py'
2852--- cloudinit/config/cc_apt_pipelining.py 2015-05-01 09:38:56 +0000
2853+++ cloudinit/config/cc_apt_pipelining.py 1970-01-01 00:00:00 +0000
2854@@ -1,57 +0,0 @@
2855-# vi: ts=4 expandtab
2856-#
2857-# Copyright (C) 2011 Canonical Ltd.
2858-#
2859-# Author: Ben Howard <ben.howard@canonical.com>
2860-#
2861-# This program is free software: you can redistribute it and/or modify
2862-# it under the terms of the GNU General Public License version 3, as
2863-# published by the Free Software Foundation.
2864-#
2865-# This program is distributed in the hope that it will be useful,
2866-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2867-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2868-# GNU General Public License for more details.
2869-#
2870-# You should have received a copy of the GNU General Public License
2871-# along with this program. If not, see <http://www.gnu.org/licenses/>.
2872-
2873-from cloudinit.settings import PER_INSTANCE
2874-from cloudinit import util
2875-
2876-frequency = PER_INSTANCE
2877-
2878-distros = ['ubuntu', 'debian']
2879-
2880-DEFAULT_FILE = "/etc/apt/apt.conf.d/90cloud-init-pipelining"
2881-
2882-APT_PIPE_TPL = ("//Written by cloud-init per 'apt_pipelining'\n"
2883- 'Acquire::http::Pipeline-Depth "%s";\n')
2884-
2885-# Acquire::http::Pipeline-Depth can be a value
2886-# from 0 to 5 indicating how many outstanding requests APT should send.
2887-# A value of zero MUST be specified if the remote host does not properly linger
2888-# on TCP connections - otherwise data corruption will occur.
2889-
2890-
2891-def handle(_name, cfg, _cloud, log, _args):
2892-
2893- apt_pipe_value = util.get_cfg_option_str(cfg, "apt_pipelining", False)
2894- apt_pipe_value_s = str(apt_pipe_value).lower().strip()
2895-
2896- if apt_pipe_value_s == "false":
2897- write_apt_snippet("0", log, DEFAULT_FILE)
2898- elif apt_pipe_value_s in ("none", "unchanged", "os"):
2899- return
2900- elif apt_pipe_value_s in [str(b) for b in range(0, 6)]:
2901- write_apt_snippet(apt_pipe_value_s, log, DEFAULT_FILE)
2902- else:
2903- log.warn("Invalid option for apt_pipeling: %s", apt_pipe_value)
2904-
2905-
2906-def write_apt_snippet(setting, log, f_name):
2907- """Writes f_name with apt pipeline depth 'setting'."""
2908-
2909- file_contents = APT_PIPE_TPL % (setting)
2910- util.write_file(f_name, file_contents)
2911- log.debug("Wrote %s with apt pipeline depth setting %s", f_name, setting)
2912
2913=== removed file 'cloudinit/config/cc_bootcmd.py'
2914--- cloudinit/config/cc_bootcmd.py 2016-05-12 17:56:26 +0000
2915+++ cloudinit/config/cc_bootcmd.py 1970-01-01 00:00:00 +0000
2916@@ -1,54 +0,0 @@
2917-# vi: ts=4 expandtab
2918-#
2919-# Copyright (C) 2009-2011 Canonical Ltd.
2920-# Copyright (C) 2012, 2013 Hewlett-Packard Development Company, L.P.
2921-#
2922-# Author: Scott Moser <scott.moser@canonical.com>
2923-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
2924-#
2925-# This program is free software: you can redistribute it and/or modify
2926-# it under the terms of the GNU General Public License version 3, as
2927-# published by the Free Software Foundation.
2928-#
2929-# This program is distributed in the hope that it will be useful,
2930-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2931-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2932-# GNU General Public License for more details.
2933-#
2934-# You should have received a copy of the GNU General Public License
2935-# along with this program. If not, see <http://www.gnu.org/licenses/>.
2936-
2937-import os
2938-
2939-from cloudinit.settings import PER_ALWAYS
2940-from cloudinit import util
2941-
2942-frequency = PER_ALWAYS
2943-
2944-
2945-def handle(name, cfg, cloud, log, _args):
2946-
2947- if "bootcmd" not in cfg:
2948- log.debug(("Skipping module named %s,"
2949- " no 'bootcmd' key in configuration"), name)
2950- return
2951-
2952- with util.ExtendedTemporaryFile(suffix=".sh") as tmpf:
2953- try:
2954- content = util.shellify(cfg["bootcmd"])
2955- tmpf.write(util.encode_text(content))
2956- tmpf.flush()
2957- except Exception:
2958- util.logexc(log, "Failed to shellify bootcmd")
2959- raise
2960-
2961- try:
2962- env = os.environ.copy()
2963- iid = cloud.get_instance_id()
2964- if iid:
2965- env['INSTANCE_ID'] = str(iid)
2966- cmd = ['/bin/sh', tmpf.name]
2967- util.subp(cmd, env=env, capture=False)
2968- except Exception:
2969- util.logexc(log, "Failed to run bootcmd module %s", name)
2970- raise
2971
2972=== removed file 'cloudinit/config/cc_byobu.py'
2973--- cloudinit/config/cc_byobu.py 2014-08-26 18:50:11 +0000
2974+++ cloudinit/config/cc_byobu.py 1970-01-01 00:00:00 +0000
2975@@ -1,80 +0,0 @@
2976-# vi: ts=4 expandtab
2977-#
2978-# Copyright (C) 2009-2010 Canonical Ltd.
2979-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
2980-#
2981-# Author: Scott Moser <scott.moser@canonical.com>
2982-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
2983-#
2984-# This program is free software: you can redistribute it and/or modify
2985-# it under the terms of the GNU General Public License version 3, as
2986-# published by the Free Software Foundation.
2987-#
2988-# This program is distributed in the hope that it will be useful,
2989-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2990-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2991-# GNU General Public License for more details.
2992-#
2993-# You should have received a copy of the GNU General Public License
2994-# along with this program. If not, see <http://www.gnu.org/licenses/>.
2995-
2996-# Ensure this is aliased to a name not 'distros'
2997-# since the module attribute 'distros'
2998-# is a list of distros that are supported, not a sub-module
2999-from cloudinit import distros as ds
3000-
3001-from cloudinit import util
3002-
3003-distros = ['ubuntu', 'debian']
3004-
3005-
3006-def handle(name, cfg, cloud, log, args):
3007- if len(args) != 0:
3008- value = args[0]
3009- else:
3010- value = util.get_cfg_option_str(cfg, "byobu_by_default", "")
3011-
3012- if not value:
3013- log.debug("Skipping module named %s, no 'byobu' values found", name)
3014- return
3015-
3016- if value == "user" or value == "system":
3017- value = "enable-%s" % value
3018-
3019- valid = ("enable-user", "enable-system", "enable",
3020- "disable-user", "disable-system", "disable")
3021- if value not in valid:
3022- log.warn("Unknown value %s for byobu_by_default", value)
3023-
3024- mod_user = value.endswith("-user")
3025- mod_sys = value.endswith("-system")
3026- if value.startswith("enable"):
3027- bl_inst = "install"
3028- dc_val = "byobu byobu/launch-by-default boolean true"
3029- mod_sys = True
3030- else:
3031- if value == "disable":
3032- mod_user = True
3033- mod_sys = True
3034- bl_inst = "uninstall"
3035- dc_val = "byobu byobu/launch-by-default boolean false"
3036-
3037- shcmd = ""
3038- if mod_user:
3039- (users, _groups) = ds.normalize_users_groups(cfg, cloud.distro)
3040- (user, _user_config) = ds.extract_default(users)
3041- if not user:
3042- log.warn(("No default byobu user provided, "
3043- "can not launch %s for the default user"), bl_inst)
3044- else:
3045- shcmd += " sudo -Hu \"%s\" byobu-launcher-%s" % (user, bl_inst)
3046- shcmd += " || X=$(($X+1)); "
3047- if mod_sys:
3048- shcmd += "echo \"%s\" | debconf-set-selections" % dc_val
3049- shcmd += " && dpkg-reconfigure byobu --frontend=noninteractive"
3050- shcmd += " || X=$(($X+1)); "
3051-
3052- if len(shcmd):
3053- cmd = ["/bin/sh", "-c", "%s %s %s" % ("X=0;", shcmd, "exit $X")]
3054- log.debug("Setting byobu to %s", value)
3055- util.subp(cmd, capture=False)
3056
3057=== removed file 'cloudinit/config/cc_ca_certs.py'
3058--- cloudinit/config/cc_ca_certs.py 2015-01-23 02:21:04 +0000
3059+++ cloudinit/config/cc_ca_certs.py 1970-01-01 00:00:00 +0000
3060@@ -1,104 +0,0 @@
3061-# vi: ts=4 expandtab
3062-#
3063-# Author: Mike Milner <mike.milner@canonical.com>
3064-#
3065-# This program is free software: you can redistribute it and/or modify
3066-# it under the terms of the GNU General Public License version 3, as
3067-# published by the Free Software Foundation.
3068-#
3069-# This program is distributed in the hope that it will be useful,
3070-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3071-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3072-# GNU General Public License for more details.
3073-#
3074-# You should have received a copy of the GNU General Public License
3075-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3076-
3077-import os
3078-
3079-from cloudinit import util
3080-
3081-CA_CERT_PATH = "/usr/share/ca-certificates/"
3082-CA_CERT_FILENAME = "cloud-init-ca-certs.crt"
3083-CA_CERT_CONFIG = "/etc/ca-certificates.conf"
3084-CA_CERT_SYSTEM_PATH = "/etc/ssl/certs/"
3085-CA_CERT_FULL_PATH = os.path.join(CA_CERT_PATH, CA_CERT_FILENAME)
3086-
3087-distros = ['ubuntu', 'debian']
3088-
3089-
3090-def update_ca_certs():
3091- """
3092- Updates the CA certificate cache on the current machine.
3093- """
3094- util.subp(["update-ca-certificates"], capture=False)
3095-
3096-
3097-def add_ca_certs(certs):
3098- """
3099- Adds certificates to the system. To actually apply the new certificates
3100- you must also call L{update_ca_certs}.
3101-
3102- @param certs: A list of certificate strings.
3103- """
3104- if certs:
3105- # First ensure they are strings...
3106- cert_file_contents = "\n".join([str(c) for c in certs])
3107- util.write_file(CA_CERT_FULL_PATH, cert_file_contents, mode=0o644)
3108-
3109- # Append cert filename to CA_CERT_CONFIG file.
3110- # We have to strip the content because blank lines in the file
3111- # causes subsequent entries to be ignored. (LP: #1077020)
3112- orig = util.load_file(CA_CERT_CONFIG)
3113- cur_cont = '\n'.join([l for l in orig.splitlines()
3114- if l != CA_CERT_FILENAME])
3115- out = "%s\n%s\n" % (cur_cont.rstrip(), CA_CERT_FILENAME)
3116- util.write_file(CA_CERT_CONFIG, out, omode="wb")
3117-
3118-
3119-def remove_default_ca_certs():
3120- """
3121- Removes all default trusted CA certificates from the system. To actually
3122- apply the change you must also call L{update_ca_certs}.
3123- """
3124- util.delete_dir_contents(CA_CERT_PATH)
3125- util.delete_dir_contents(CA_CERT_SYSTEM_PATH)
3126- util.write_file(CA_CERT_CONFIG, "", mode=0o644)
3127- debconf_sel = "ca-certificates ca-certificates/trust_new_crts select no"
3128- util.subp(('debconf-set-selections', '-'), debconf_sel)
3129-
3130-
3131-def handle(name, cfg, _cloud, log, _args):
3132- """
3133- Call to handle ca-cert sections in cloud-config file.
3134-
3135- @param name: The module name "ca-cert" from cloud.cfg
3136- @param cfg: A nested dict containing the entire cloud config contents.
3137- @param cloud: The L{CloudInit} object in use.
3138- @param log: Pre-initialized Python logger object to use for logging.
3139- @param args: Any module arguments from cloud.cfg
3140- """
3141- # If there isn't a ca-certs section in the configuration don't do anything
3142- if "ca-certs" not in cfg:
3143- log.debug(("Skipping module named %s,"
3144- " no 'ca-certs' key in configuration"), name)
3145- return
3146-
3147- ca_cert_cfg = cfg['ca-certs']
3148-
3149- # If there is a remove-defaults option set to true, remove the system
3150- # default trusted CA certs first.
3151- if ca_cert_cfg.get("remove-defaults", False):
3152- log.debug("Removing default certificates")
3153- remove_default_ca_certs()
3154-
3155- # If we are given any new trusted CA certs to add, add them.
3156- if "trusted" in ca_cert_cfg:
3157- trusted_certs = util.get_cfg_option_list(ca_cert_cfg, "trusted")
3158- if trusted_certs:
3159- log.debug("Adding %d certificates" % len(trusted_certs))
3160- add_ca_certs(trusted_certs)
3161-
3162- # Update the system with the new cert configuration.
3163- log.debug("Updating certificates")
3164- update_ca_certs()
3165
3166=== removed file 'cloudinit/config/cc_chef.py'
3167--- cloudinit/config/cc_chef.py 2016-04-13 16:24:46 +0000
3168+++ cloudinit/config/cc_chef.py 1970-01-01 00:00:00 +0000
3169@@ -1,342 +0,0 @@
3170-# vi: ts=4 expandtab
3171-#
3172-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
3173-#
3174-# Author: Avishai Ish-Shalom <avishai@fewbytes.com>
3175-# Author: Mike Moulton <mike@meltmedia.com>
3176-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
3177-#
3178-# This program is free software: you can redistribute it and/or modify
3179-# it under the terms of the GNU General Public License version 3, as
3180-# published by the Free Software Foundation.
3181-#
3182-# This program is distributed in the hope that it will be useful,
3183-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3184-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3185-# GNU General Public License for more details.
3186-#
3187-# You should have received a copy of the GNU General Public License
3188-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3189-
3190-"""
3191-**Summary:** module that configures, starts and installs chef.
3192-
3193-**Description:** This module enables chef to be installed (from packages or
3194-from gems, or from omnibus). Before this occurs chef configurations are
3195-written to disk (validation.pem, client.pem, firstboot.json, client.rb),
3196-and needed chef folders/directories are created (/etc/chef and /var/log/chef
3197-and so-on). Then once installing proceeds correctly if configured chef will
3198-be started (in daemon mode or in non-daemon mode) and then once that has
3199-finished (if ran in non-daemon mode this will be when chef finishes
3200-converging, if ran in daemon mode then no further actions are possible since
3201-chef will have forked into its own process) then a post run function can
3202-run that can do finishing activities (such as removing the validation pem
3203-file).
3204-
3205-It can be configured with the following option structure::
3206-
3207- chef:
3208- directories: (defaulting to /etc/chef, /var/log/chef, /var/lib/chef,
3209- /var/cache/chef, /var/backups/chef, /var/run/chef)
3210- validation_cert: (optional string to be written to file validation_key)
3211- special value 'system' means set use existing file
3212- validation_key: (optional the path for validation_cert. default
3213- /etc/chef/validation.pem)
3214- firstboot_path: (path to write run_list and initial_attributes keys that
3215- should also be present in this configuration, defaults
3216- to /etc/chef/firstboot.json)
3217- exec: boolean to run or not run chef (defaults to false, unless
3218- a gem installed is requested
3219- where this will then default
3220- to true)
3221-
3222- chef.rb template keys (if falsey, then will be skipped and not
3223- written to /etc/chef/client.rb)
3224-
3225- chef:
3226- client_key:
3227- environment:
3228- file_backup_path:
3229- file_cache_path:
3230- json_attribs:
3231- log_level:
3232- log_location:
3233- node_name:
3234- pid_file:
3235- server_url:
3236- show_time:
3237- ssl_verify_mode:
3238- validation_cert:
3239- validation_key:
3240- validation_name:
3241-"""
3242-
3243-import itertools
3244-import json
3245-import os
3246-
3247-from cloudinit import templater
3248-from cloudinit import url_helper
3249-from cloudinit import util
3250-
3251-import six
3252-
3253-RUBY_VERSION_DEFAULT = "1.8"
3254-
3255-CHEF_DIRS = tuple([
3256- '/etc/chef',
3257- '/var/log/chef',
3258- '/var/lib/chef',
3259- '/var/cache/chef',
3260- '/var/backups/chef',
3261- '/var/run/chef',
3262-])
3263-REQUIRED_CHEF_DIRS = tuple([
3264- '/etc/chef',
3265-])
3266-
3267-# Used if fetching chef from a omnibus style package
3268-OMNIBUS_URL = "https://www.getchef.com/chef/install.sh"
3269-OMNIBUS_URL_RETRIES = 5
3270-
3271-CHEF_VALIDATION_PEM_PATH = '/etc/chef/validation.pem'
3272-CHEF_FB_PATH = '/etc/chef/firstboot.json'
3273-CHEF_RB_TPL_DEFAULTS = {
3274- # These are ruby symbols...
3275- 'ssl_verify_mode': ':verify_none',
3276- 'log_level': ':info',
3277- # These are not symbols...
3278- 'log_location': '/var/log/chef/client.log',
3279- 'validation_key': CHEF_VALIDATION_PEM_PATH,
3280- 'validation_cert': None,
3281- 'client_key': "/etc/chef/client.pem",
3282- 'json_attribs': CHEF_FB_PATH,
3283- 'file_cache_path': "/var/cache/chef",
3284- 'file_backup_path': "/var/backups/chef",
3285- 'pid_file': "/var/run/chef/client.pid",
3286- 'show_time': True,
3287-}
3288-CHEF_RB_TPL_BOOL_KEYS = frozenset(['show_time'])
3289-CHEF_RB_TPL_PATH_KEYS = frozenset([
3290- 'log_location',
3291- 'validation_key',
3292- 'client_key',
3293- 'file_cache_path',
3294- 'json_attribs',
3295- 'file_cache_path',
3296- 'pid_file',
3297-])
3298-CHEF_RB_TPL_KEYS = list(CHEF_RB_TPL_DEFAULTS.keys())
3299-CHEF_RB_TPL_KEYS.extend(CHEF_RB_TPL_BOOL_KEYS)
3300-CHEF_RB_TPL_KEYS.extend(CHEF_RB_TPL_PATH_KEYS)
3301-CHEF_RB_TPL_KEYS.extend([
3302- 'server_url',
3303- 'node_name',
3304- 'environment',
3305- 'validation_name',
3306-])
3307-CHEF_RB_TPL_KEYS = frozenset(CHEF_RB_TPL_KEYS)
3308-CHEF_RB_PATH = '/etc/chef/client.rb'
3309-CHEF_EXEC_PATH = '/usr/bin/chef-client'
3310-CHEF_EXEC_DEF_ARGS = tuple(['-d', '-i', '1800', '-s', '20'])
3311-
3312-
3313-def is_installed():
3314- if not os.path.isfile(CHEF_EXEC_PATH):
3315- return False
3316- if not os.access(CHEF_EXEC_PATH, os.X_OK):
3317- return False
3318- return True
3319-
3320-
3321-def post_run_chef(chef_cfg, log):
3322- delete_pem = util.get_cfg_option_bool(chef_cfg,
3323- 'delete_validation_post_exec',
3324- default=False)
3325- if delete_pem and os.path.isfile(CHEF_VALIDATION_PEM_PATH):
3326- os.unlink(CHEF_VALIDATION_PEM_PATH)
3327-
3328-
3329-def get_template_params(iid, chef_cfg, log):
3330- params = CHEF_RB_TPL_DEFAULTS.copy()
3331- # Allow users to overwrite any of the keys they want (if they so choose),
3332- # when a value is None, then the value will be set to None and no boolean
3333- # or string version will be populated...
3334- for (k, v) in chef_cfg.items():
3335- if k not in CHEF_RB_TPL_KEYS:
3336- log.debug("Skipping unknown chef template key '%s'", k)
3337- continue
3338- if v is None:
3339- params[k] = None
3340- else:
3341- # This will make the value a boolean or string...
3342- if k in CHEF_RB_TPL_BOOL_KEYS:
3343- params[k] = util.get_cfg_option_bool(chef_cfg, k)
3344- else:
3345- params[k] = util.get_cfg_option_str(chef_cfg, k)
3346- # These ones are overwritten to be exact values...
3347- params.update({
3348- 'generated_by': util.make_header(),
3349- 'node_name': util.get_cfg_option_str(chef_cfg, 'node_name',
3350- default=iid),
3351- 'environment': util.get_cfg_option_str(chef_cfg, 'environment',
3352- default='_default'),
3353- # These two are mandatory...
3354- 'server_url': chef_cfg['server_url'],
3355- 'validation_name': chef_cfg['validation_name'],
3356- })
3357- return params
3358-
3359-
3360-def handle(name, cfg, cloud, log, _args):
3361- """Handler method activated by cloud-init."""
3362-
3363- # If there isn't a chef key in the configuration don't do anything
3364- if 'chef' not in cfg:
3365- log.debug(("Skipping module named %s,"
3366- " no 'chef' key in configuration"), name)
3367- return
3368- chef_cfg = cfg['chef']
3369-
3370- # Ensure the chef directories we use exist
3371- chef_dirs = util.get_cfg_option_list(chef_cfg, 'directories')
3372- if not chef_dirs:
3373- chef_dirs = list(CHEF_DIRS)
3374- for d in itertools.chain(chef_dirs, REQUIRED_CHEF_DIRS):
3375- util.ensure_dir(d)
3376-
3377- vkey_path = chef_cfg.get('validation_key', CHEF_VALIDATION_PEM_PATH)
3378- vcert = chef_cfg.get('validation_cert')
3379- # special value 'system' means do not overwrite the file
3380- # but still render the template to contain 'validation_key'
3381- if vcert:
3382- if vcert != "system":
3383- util.write_file(vkey_path, vcert)
3384- elif not os.path.isfile(vkey_path):
3385- log.warn("chef validation_cert provided as 'system', but "
3386- "validation_key path '%s' does not exist.",
3387- vkey_path)
3388-
3389- # Create the chef config from template
3390- template_fn = cloud.get_template_filename('chef_client.rb')
3391- if template_fn:
3392- iid = str(cloud.datasource.get_instance_id())
3393- params = get_template_params(iid, chef_cfg, log)
3394- # Do a best effort attempt to ensure that the template values that
3395- # are associated with paths have there parent directory created
3396- # before they are used by the chef-client itself.
3397- param_paths = set()
3398- for (k, v) in params.items():
3399- if k in CHEF_RB_TPL_PATH_KEYS and v:
3400- param_paths.add(os.path.dirname(v))
3401- util.ensure_dirs(param_paths)
3402- templater.render_to_file(template_fn, CHEF_RB_PATH, params)
3403- else:
3404- log.warn("No template found, not rendering to %s",
3405- CHEF_RB_PATH)
3406-
3407- # Set the firstboot json
3408- fb_filename = util.get_cfg_option_str(chef_cfg, 'firstboot_path',
3409- default=CHEF_FB_PATH)
3410- if not fb_filename:
3411- log.info("First boot path empty, not writing first boot json file")
3412- else:
3413- initial_json = {}
3414- if 'run_list' in chef_cfg:
3415- initial_json['run_list'] = chef_cfg['run_list']
3416- if 'initial_attributes' in chef_cfg:
3417- initial_attributes = chef_cfg['initial_attributes']
3418- for k in list(initial_attributes.keys()):
3419- initial_json[k] = initial_attributes[k]
3420- util.write_file(fb_filename, json.dumps(initial_json))
3421-
3422- # Try to install chef, if its not already installed...
3423- force_install = util.get_cfg_option_bool(chef_cfg,
3424- 'force_install', default=False)
3425- if not is_installed() or force_install:
3426- run = install_chef(cloud, chef_cfg, log)
3427- elif is_installed():
3428- run = util.get_cfg_option_bool(chef_cfg, 'exec', default=False)
3429- else:
3430- run = False
3431- if run:
3432- run_chef(chef_cfg, log)
3433- post_run_chef(chef_cfg, log)
3434-
3435-
3436-def run_chef(chef_cfg, log):
3437- log.debug('Running chef-client')
3438- cmd = [CHEF_EXEC_PATH]
3439- if 'exec_arguments' in chef_cfg:
3440- cmd_args = chef_cfg['exec_arguments']
3441- if isinstance(cmd_args, (list, tuple)):
3442- cmd.extend(cmd_args)
3443- elif isinstance(cmd_args, six.string_types):
3444- cmd.append(cmd_args)
3445- else:
3446- log.warn("Unknown type %s provided for chef"
3447- " 'exec_arguments' expected list, tuple,"
3448- " or string", type(cmd_args))
3449- cmd.extend(CHEF_EXEC_DEF_ARGS)
3450- else:
3451- cmd.extend(CHEF_EXEC_DEF_ARGS)
3452- util.subp(cmd, capture=False)
3453-
3454-
3455-def install_chef(cloud, chef_cfg, log):
3456- # If chef is not installed, we install chef based on 'install_type'
3457- install_type = util.get_cfg_option_str(chef_cfg, 'install_type',
3458- 'packages')
3459- run = util.get_cfg_option_bool(chef_cfg, 'exec', default=False)
3460- if install_type == "gems":
3461- # This will install and run the chef-client from gems
3462- chef_version = util.get_cfg_option_str(chef_cfg, 'version', None)
3463- ruby_version = util.get_cfg_option_str(chef_cfg, 'ruby_version',
3464- RUBY_VERSION_DEFAULT)
3465- install_chef_from_gems(ruby_version, chef_version, cloud.distro)
3466- # Retain backwards compat, by preferring True instead of False
3467- # when not provided/overriden...
3468- run = util.get_cfg_option_bool(chef_cfg, 'exec', default=True)
3469- elif install_type == 'packages':
3470- # This will install and run the chef-client from packages
3471- cloud.distro.install_packages(('chef',))
3472- elif install_type == 'omnibus':
3473- # This will install as a omnibus unified package
3474- url = util.get_cfg_option_str(chef_cfg, "omnibus_url", OMNIBUS_URL)
3475- retries = max(0, util.get_cfg_option_int(chef_cfg,
3476- "omnibus_url_retries",
3477- default=OMNIBUS_URL_RETRIES))
3478- content = url_helper.readurl(url=url, retries=retries)
3479- with util.tempdir() as tmpd:
3480- # Use tmpdir over tmpfile to avoid 'text file busy' on execute
3481- tmpf = "%s/chef-omnibus-install" % tmpd
3482- util.write_file(tmpf, content, mode=0o700)
3483- util.subp([tmpf], capture=False)
3484- else:
3485- log.warn("Unknown chef install type '%s'", install_type)
3486- run = False
3487- return run
3488-
3489-
3490-def get_ruby_packages(version):
3491- # return a list of packages needed to install ruby at version
3492- pkgs = ['ruby%s' % version, 'ruby%s-dev' % version]
3493- if version == "1.8":
3494- pkgs.extend(('libopenssl-ruby1.8', 'rubygems1.8'))
3495- return pkgs
3496-
3497-
3498-def install_chef_from_gems(ruby_version, chef_version, distro):
3499- distro.install_packages(get_ruby_packages(ruby_version))
3500- if not os.path.exists('/usr/bin/gem'):
3501- util.sym_link('/usr/bin/gem%s' % ruby_version, '/usr/bin/gem')
3502- if not os.path.exists('/usr/bin/ruby'):
3503- util.sym_link('/usr/bin/ruby%s' % ruby_version, '/usr/bin/ruby')
3504- if chef_version:
3505- util.subp(['/usr/bin/gem', 'install', 'chef',
3506- '-v %s' % chef_version, '--no-ri',
3507- '--no-rdoc', '--bindir', '/usr/bin', '-q'], capture=False)
3508- else:
3509- util.subp(['/usr/bin/gem', 'install', 'chef',
3510- '--no-ri', '--no-rdoc', '--bindir',
3511- '/usr/bin', '-q'], capture=False)
3512
3513=== removed file 'cloudinit/config/cc_debug.py'
3514--- cloudinit/config/cc_debug.py 2015-01-21 22:56:53 +0000
3515+++ cloudinit/config/cc_debug.py 1970-01-01 00:00:00 +0000
3516@@ -1,109 +0,0 @@
3517-# vi: ts=4 expandtab
3518-#
3519-# Copyright (C) 2013 Yahoo! Inc.
3520-#
3521-# This program is free software: you can redistribute it and/or modify
3522-# it under the terms of the GNU General Public License version 3, as
3523-# published by the Free Software Foundation.
3524-#
3525-# This program is distributed in the hope that it will be useful,
3526-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3527-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3528-# GNU General Public License for more details.
3529-#
3530-# You should have received a copy of the GNU General Public License
3531-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3532-
3533-"""
3534-**Summary:** helper to debug cloud-init *internal* datastructures.
3535-
3536-**Description:** This module will enable for outputting various internal
3537-information that cloud-init sources provide to either a file or to the output
3538-console/log location that this cloud-init has been configured with when
3539-running.
3540-
3541-It can be configured with the following option structure::
3542-
3543- debug:
3544- verbose: (defaulting to true)
3545- output: (location to write output, defaulting to console + log)
3546-
3547-.. note::
3548-
3549- Log configurations are not output.
3550-"""
3551-
3552-import copy
3553-
3554-from six import StringIO
3555-
3556-from cloudinit import type_utils
3557-from cloudinit import util
3558-
3559-SKIP_KEYS = frozenset(['log_cfgs'])
3560-
3561-
3562-def _make_header(text):
3563- header = StringIO()
3564- header.write("-" * 80)
3565- header.write("\n")
3566- header.write(text.center(80, ' '))
3567- header.write("\n")
3568- header.write("-" * 80)
3569- header.write("\n")
3570- return header.getvalue()
3571-
3572-
3573-def _dumps(obj):
3574- text = util.yaml_dumps(obj, explicit_start=False, explicit_end=False)
3575- return text.rstrip()
3576-
3577-
3578-def handle(name, cfg, cloud, log, args):
3579- """Handler method activated by cloud-init."""
3580-
3581- verbose = util.get_cfg_by_path(cfg, ('debug', 'verbose'), default=True)
3582- if args:
3583- # if args are provided (from cmdline) then explicitly set verbose
3584- out_file = args[0]
3585- verbose = True
3586- else:
3587- out_file = util.get_cfg_by_path(cfg, ('debug', 'output'))
3588-
3589- if not verbose:
3590- log.debug(("Skipping module named %s,"
3591- " verbose printing disabled"), name)
3592- return
3593- # Clean out some keys that we just don't care about showing...
3594- dump_cfg = copy.deepcopy(cfg)
3595- for k in SKIP_KEYS:
3596- dump_cfg.pop(k, None)
3597- all_keys = list(dump_cfg)
3598- for k in all_keys:
3599- if k.startswith("_"):
3600- dump_cfg.pop(k, None)
3601- # Now dump it...
3602- to_print = StringIO()
3603- to_print.write(_make_header("Config"))
3604- to_print.write(_dumps(dump_cfg))
3605- to_print.write("\n")
3606- to_print.write(_make_header("MetaData"))
3607- to_print.write(_dumps(cloud.datasource.metadata))
3608- to_print.write("\n")
3609- to_print.write(_make_header("Misc"))
3610- to_print.write("Datasource: %s\n" %
3611- (type_utils.obj_name(cloud.datasource)))
3612- to_print.write("Distro: %s\n" % (type_utils.obj_name(cloud.distro)))
3613- to_print.write("Hostname: %s\n" % (cloud.get_hostname(True)))
3614- to_print.write("Instance ID: %s\n" % (cloud.get_instance_id()))
3615- to_print.write("Locale: %s\n" % (cloud.get_locale()))
3616- to_print.write("Launch IDX: %s\n" % (cloud.launch_index))
3617- contents = to_print.getvalue()
3618- content_to_file = []
3619- for line in contents.splitlines():
3620- line = "ci-info: %s\n" % (line)
3621- content_to_file.append(line)
3622- if out_file:
3623- util.write_file(out_file, "".join(content_to_file), 0o644, "w")
3624- else:
3625- util.multi_log("".join(content_to_file), console=True, stderr=False)
3626
3627=== removed file 'cloudinit/config/cc_disable_ec2_metadata.py'
3628--- cloudinit/config/cc_disable_ec2_metadata.py 2012-06-23 04:02:04 +0000
3629+++ cloudinit/config/cc_disable_ec2_metadata.py 1970-01-01 00:00:00 +0000
3630@@ -1,36 +0,0 @@
3631-# vi: ts=4 expandtab
3632-#
3633-# Copyright (C) 2009-2010 Canonical Ltd.
3634-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
3635-#
3636-# Author: Scott Moser <scott.moser@canonical.com>
3637-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
3638-#
3639-# This program is free software: you can redistribute it and/or modify
3640-# it under the terms of the GNU General Public License version 3, as
3641-# published by the Free Software Foundation.
3642-#
3643-# This program is distributed in the hope that it will be useful,
3644-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3645-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3646-# GNU General Public License for more details.
3647-#
3648-# You should have received a copy of the GNU General Public License
3649-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3650-
3651-from cloudinit import util
3652-
3653-from cloudinit.settings import PER_ALWAYS
3654-
3655-frequency = PER_ALWAYS
3656-
3657-REJECT_CMD = ['route', 'add', '-host', '169.254.169.254', 'reject']
3658-
3659-
3660-def handle(name, cfg, _cloud, log, _args):
3661- disabled = util.get_cfg_option_bool(cfg, "disable_ec2_metadata", False)
3662- if disabled:
3663- util.subp(REJECT_CMD, capture=False)
3664- else:
3665- log.debug(("Skipping module named %s,"
3666- " disabling the ec2 route not enabled"), name)
3667
3668=== renamed file 'cloudinit/config/cc_disk_setup.py' => 'cloudinit/config/cc_disk_setup.py.THIS'
3669=== removed file 'cloudinit/config/cc_emit_upstart.py'
3670--- cloudinit/config/cc_emit_upstart.py 2016-05-12 17:56:26 +0000
3671+++ cloudinit/config/cc_emit_upstart.py 1970-01-01 00:00:00 +0000
3672@@ -1,69 +0,0 @@
3673-# vi: ts=4 expandtab
3674-#
3675-# Copyright (C) 2009-2011 Canonical Ltd.
3676-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
3677-#
3678-# Author: Scott Moser <scott.moser@canonical.com>
3679-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
3680-#
3681-# This program is free software: you can redistribute it and/or modify
3682-# it under the terms of the GNU General Public License version 3, as
3683-# published by the Free Software Foundation.
3684-#
3685-# This program is distributed in the hope that it will be useful,
3686-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3687-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3688-# GNU General Public License for more details.
3689-#
3690-# You should have received a copy of the GNU General Public License
3691-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3692-
3693-import os
3694-
3695-from cloudinit import log as logging
3696-from cloudinit.settings import PER_ALWAYS
3697-from cloudinit import util
3698-
3699-frequency = PER_ALWAYS
3700-
3701-distros = ['ubuntu', 'debian']
3702-LOG = logging.getLogger(__name__)
3703-
3704-
3705-def is_upstart_system():
3706- if not os.path.isfile("/sbin/initctl"):
3707- LOG.debug("no /sbin/initctl located")
3708- return False
3709-
3710- myenv = os.environ.copy()
3711- if 'UPSTART_SESSION' in myenv:
3712- del myenv['UPSTART_SESSION']
3713- check_cmd = ['initctl', 'version']
3714- try:
3715- (out, err) = util.subp(check_cmd, env=myenv)
3716- return 'upstart' in out
3717- except util.ProcessExecutionError as e:
3718- LOG.debug("'%s' returned '%s', not using upstart",
3719- ' '.join(check_cmd), e.exit_code)
3720- return False
3721-
3722-
3723-def handle(name, _cfg, cloud, log, args):
3724- event_names = args
3725- if not event_names:
3726- # Default to the 'cloud-config'
3727- # event for backwards compat.
3728- event_names = ['cloud-config']
3729-
3730- if not is_upstart_system():
3731- log.debug("not upstart system, '%s' disabled")
3732- return
3733-
3734- cfgpath = cloud.paths.get_ipath_cur("cloud_config")
3735- for n in event_names:
3736- cmd = ['initctl', 'emit', str(n), 'CLOUD_CFG=%s' % cfgpath]
3737- try:
3738- util.subp(cmd)
3739- except Exception as e:
3740- # TODO(harlowja), use log exception from utils??
3741- log.warn("Emission of upstart event %s failed due to: %s", n, e)
3742
3743=== removed file 'cloudinit/config/cc_fan.py'
3744--- cloudinit/config/cc_fan.py 2016-05-12 17:56:26 +0000
3745+++ cloudinit/config/cc_fan.py 1970-01-01 00:00:00 +0000
3746@@ -1,101 +0,0 @@
3747-# vi: ts=4 expandtab
3748-#
3749-# Copyright (C) 2015 Canonical Ltd.
3750-#
3751-# Author: Scott Moser <scott.moser@canonical.com>
3752-#
3753-# This program is free software: you can redistribute it and/or modify
3754-# it under the terms of the GNU General Public License version 3, as
3755-# published by the Free Software Foundation.
3756-#
3757-# This program is distributed in the hope that it will be useful,
3758-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3759-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3760-# GNU General Public License for more details.
3761-#
3762-# You should have received a copy of the GNU General Public License
3763-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3764-"""
3765-fan module allows configuration of Ubuntu Fan
3766- https://wiki.ubuntu.com/FanNetworking
3767-
3768-Example config:
3769- #cloud-config
3770- fan:
3771- config: |
3772- # fan 240
3773- 10.0.0.0/8 eth0/16 dhcp
3774- 10.0.0.0/8 eth1/16 dhcp off
3775- # fan 241
3776- 241.0.0.0/8 eth0/16 dhcp
3777- config_path: /etc/network/fan
3778-
3779-If cloud-init sees a 'fan' entry in cloud-config it will
3780- a.) write 'config_path' with the contents
3781- b.) install the package 'ubuntu-fan' if it is not installed
3782- c.) ensure the service is started (or restarted if was previously running)
3783-"""
3784-
3785-from cloudinit import log as logging
3786-from cloudinit.settings import PER_INSTANCE
3787-from cloudinit import util
3788-
3789-LOG = logging.getLogger(__name__)
3790-
3791-frequency = PER_INSTANCE
3792-
3793-BUILTIN_CFG = {
3794- 'config': None,
3795- 'config_path': '/etc/network/fan',
3796-}
3797-
3798-
3799-def stop_update_start(service, config_file, content, systemd=False):
3800- if systemd:
3801- cmds = {'stop': ['systemctl', 'stop', service],
3802- 'start': ['systemctl', 'start', service],
3803- 'enable': ['systemctl', 'enable', service]}
3804- else:
3805- cmds = {'stop': ['service', 'stop'],
3806- 'start': ['service', 'start']}
3807-
3808- def run(cmd, msg):
3809- try:
3810- return util.subp(cmd, capture=True)
3811- except util.ProcessExecutionError as e:
3812- LOG.warn("failed: %s (%s): %s", service, cmd, e)
3813- return False
3814-
3815- stop_failed = not run(cmds['stop'], msg='stop %s' % service)
3816- if not content.endswith('\n'):
3817- content += '\n'
3818- util.write_file(config_file, content, omode="w")
3819-
3820- ret = run(cmds['start'], msg='start %s' % service)
3821- if ret and stop_failed:
3822- LOG.warn("success: %s started", service)
3823-
3824- if 'enable' in cmds:
3825- ret = run(cmds['enable'], msg='enable %s' % service)
3826-
3827- return ret
3828-
3829-
3830-def handle(name, cfg, cloud, log, args):
3831- cfgin = cfg.get('fan')
3832- if not cfgin:
3833- cfgin = {}
3834- mycfg = util.mergemanydict([cfgin, BUILTIN_CFG])
3835-
3836- if not mycfg.get('config'):
3837- LOG.debug("%s: no 'fan' config entry. disabling", name)
3838- return
3839-
3840- util.write_file(mycfg.get('config_path'), mycfg.get('config'), omode="w")
3841- distro = cloud.distro
3842- if not util.which('fanctl'):
3843- distro.install_packages(['ubuntu-fan'])
3844-
3845- stop_update_start(
3846- service='ubuntu-fan', config_file=mycfg.get('config_path'),
3847- content=mycfg.get('config'), systemd=distro.uses_systemd())
3848
3849=== removed file 'cloudinit/config/cc_final_message.py'
3850--- cloudinit/config/cc_final_message.py 2016-05-12 17:56:26 +0000
3851+++ cloudinit/config/cc_final_message.py 1970-01-01 00:00:00 +0000
3852@@ -1,73 +0,0 @@
3853-# vi: ts=4 expandtab
3854-#
3855-# Copyright (C) 2011 Canonical Ltd.
3856-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
3857-#
3858-# Author: Scott Moser <scott.moser@canonical.com>
3859-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
3860-#
3861-# This program is free software: you can redistribute it and/or modify
3862-# it under the terms of the GNU General Public License version 3, as
3863-# published by the Free Software Foundation.
3864-#
3865-# This program is distributed in the hope that it will be useful,
3866-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3867-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3868-# GNU General Public License for more details.
3869-#
3870-# You should have received a copy of the GNU General Public License
3871-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3872-
3873-from cloudinit import templater
3874-from cloudinit import util
3875-from cloudinit import version
3876-
3877-from cloudinit.settings import PER_ALWAYS
3878-
3879-frequency = PER_ALWAYS
3880-
3881-# Jinja formated default message
3882-FINAL_MESSAGE_DEF = (
3883- "## template: jinja\n"
3884- "Cloud-init v. {{version}} finished at {{timestamp}}."
3885- " Datasource {{datasource}}. Up {{uptime}} seconds"
3886-)
3887-
3888-
3889-def handle(_name, cfg, cloud, log, args):
3890-
3891- msg_in = ''
3892- if len(args) != 0:
3893- msg_in = str(args[0])
3894- else:
3895- msg_in = util.get_cfg_option_str(cfg, "final_message", "")
3896-
3897- msg_in = msg_in.strip()
3898- if not msg_in:
3899- msg_in = FINAL_MESSAGE_DEF
3900-
3901- uptime = util.uptime()
3902- ts = util.time_rfc2822()
3903- cver = version.version_string()
3904- try:
3905- subs = {
3906- 'uptime': uptime,
3907- 'timestamp': ts,
3908- 'version': cver,
3909- 'datasource': str(cloud.datasource),
3910- }
3911- subs.update(dict([(k.upper(), v) for k, v in subs.items()]))
3912- util.multi_log("%s\n" % (templater.render_string(msg_in, subs)),
3913- console=False, stderr=True, log=log)
3914- except Exception:
3915- util.logexc(log, "Failed to render final message template")
3916-
3917- boot_fin_fn = cloud.paths.boot_finished
3918- try:
3919- contents = "%s - %s - v. %s\n" % (uptime, ts, cver)
3920- util.write_file(boot_fin_fn, contents)
3921- except Exception:
3922- util.logexc(log, "Failed to write boot finished file %s", boot_fin_fn)
3923-
3924- if cloud.datasource.is_disconnected:
3925- log.warn("Used fallback datasource")
3926
3927=== removed file 'cloudinit/config/cc_foo.py'
3928--- cloudinit/config/cc_foo.py 2012-06-21 16:12:16 +0000
3929+++ cloudinit/config/cc_foo.py 1970-01-01 00:00:00 +0000
3930@@ -1,52 +0,0 @@
3931-# vi: ts=4 expandtab
3932-#
3933-# Copyright (C) 2009-2010 Canonical Ltd.
3934-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
3935-#
3936-# Author: Scott Moser <scott.moser@canonical.com>
3937-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
3938-#
3939-# This program is free software: you can redistribute it and/or modify
3940-# it under the terms of the GNU General Public License version 3, as
3941-# published by the Free Software Foundation.
3942-#
3943-# This program is distributed in the hope that it will be useful,
3944-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3945-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3946-# GNU General Public License for more details.
3947-#
3948-# You should have received a copy of the GNU General Public License
3949-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3950-
3951-from cloudinit.settings import PER_INSTANCE
3952-
3953-# Modules are expected to have the following attributes.
3954-# 1. A required 'handle' method which takes the following params.
3955-# a) The name will not be this files name, but instead
3956-# the name specified in configuration (which is the name
3957-# which will be used to find this module).
3958-# b) A configuration object that is the result of the merging
3959-# of cloud configs configuration with legacy configuration
3960-# as well as any datasource provided configuration
3961-# c) A cloud object that can be used to access various
3962-# datasource and paths for the given distro and data provided
3963-# by the various datasource instance types.
3964-# d) A argument list that may or may not be empty to this module.
3965-# Typically those are from module configuration where the module
3966-# is defined with some extra configuration that will eventually
3967-# be translated from yaml into arguments to this module.
3968-# 2. A optional 'frequency' that defines how often this module should be ran.
3969-# Typically one of PER_INSTANCE, PER_ALWAYS, PER_ONCE. If not
3970-# provided PER_INSTANCE will be assumed.
3971-# See settings.py for these constants.
3972-# 3. A optional 'distros' array/set/tuple that defines the known distros
3973-# this module will work with (if not all of them). This is used to write
3974-# a warning out if a module is being ran on a untested distribution for
3975-# informational purposes. If non existent all distros are assumed and
3976-# no warning occurs.
3977-
3978-frequency = PER_INSTANCE
3979-
3980-
3981-def handle(name, _cfg, _cloud, log, _args):
3982- log.debug("Hi from module %s", name)
3983
3984=== removed file 'cloudinit/config/cc_growpart.py'
3985--- cloudinit/config/cc_growpart.py 2015-06-16 15:18:33 +0000
3986+++ cloudinit/config/cc_growpart.py 1970-01-01 00:00:00 +0000
3987@@ -1,300 +0,0 @@
3988-# vi: ts=4 expandtab
3989-#
3990-# Copyright (C) 2011 Canonical Ltd.
3991-# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
3992-#
3993-# Author: Scott Moser <scott.moser@canonical.com>
3994-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
3995-#
3996-# This program is free software: you can redistribute it and/or modify
3997-# it under the terms of the GNU General Public License version 3, as
3998-# published by the Free Software Foundation.
3999-#
4000-# This program is distributed in the hope that it will be useful,
4001-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4002-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4003-# GNU General Public License for more details.
4004-#
4005-# You should have received a copy of the GNU General Public License
4006-# along with this program. If not, see <http://www.gnu.org/licenses/>.
4007-
4008-import os
4009-import os.path
4010-import re
4011-import stat
4012-
4013-from cloudinit import log as logging
4014-from cloudinit.settings import PER_ALWAYS
4015-from cloudinit import util
4016-
4017-frequency = PER_ALWAYS
4018-
4019-DEFAULT_CONFIG = {
4020- 'mode': 'auto',
4021- 'devices': ['/'],
4022- 'ignore_growroot_disabled': False,
4023-}
4024-
4025-
4026-def enum(**enums):
4027- return type('Enum', (), enums)
4028-
4029-
4030-RESIZE = enum(SKIPPED="SKIPPED", CHANGED="CHANGED", NOCHANGE="NOCHANGE",
4031- FAILED="FAILED")
4032-
4033-LOG = logging.getLogger(__name__)
4034-
4035-
4036-def resizer_factory(mode):
4037- resize_class = None
4038- if mode == "auto":
4039- for (_name, resizer) in RESIZERS:
4040- cur = resizer()
4041- if cur.available():
4042- resize_class = cur
4043- break
4044-
4045- if not resize_class:
4046- raise ValueError("No resizers available")
4047-
4048- else:
4049- mmap = {}
4050- for (k, v) in RESIZERS:
4051- mmap[k] = v
4052-
4053- if mode not in mmap:
4054- raise TypeError("unknown resize mode %s" % mode)
4055-
4056- mclass = mmap[mode]()
4057- if mclass.available():
4058- resize_class = mclass
4059-
4060- if not resize_class:
4061- raise ValueError("mode %s not available" % mode)
4062-
4063- return resize_class
4064-
4065-
4066-class ResizeFailedException(Exception):
4067- pass
4068-
4069-
4070-class ResizeGrowPart(object):
4071- def available(self):
4072- myenv = os.environ.copy()
4073- myenv['LANG'] = 'C'
4074-
4075- try:
4076- (out, _err) = util.subp(["growpart", "--help"], env=myenv)
4077- if re.search(r"--update\s+", out, re.DOTALL):
4078- return True
4079-
4080- except util.ProcessExecutionError:
4081- pass
4082- return False
4083-
4084- def resize(self, diskdev, partnum, partdev):
4085- before = get_size(partdev)
4086- try:
4087- util.subp(["growpart", '--dry-run', diskdev, partnum])
4088- except util.ProcessExecutionError as e:
4089- if e.exit_code != 1:
4090- util.logexc(LOG, "Failed growpart --dry-run for (%s, %s)",
4091- diskdev, partnum)
4092- raise ResizeFailedException(e)
4093- return (before, before)
4094-
4095- try:
4096- util.subp(["growpart", diskdev, partnum])
4097- except util.ProcessExecutionError as e:
4098- util.logexc(LOG, "Failed: growpart %s %s", diskdev, partnum)
4099- raise ResizeFailedException(e)
4100-
4101- return (before, get_size(partdev))
4102-
4103-
4104-class ResizeGpart(object):
4105- def available(self):
4106- if not util.which('gpart'):
4107- return False
4108- return True
4109-
4110- def resize(self, diskdev, partnum, partdev):
4111- """
4112- GPT disks store metadata at the beginning (primary) and at the
4113- end (secondary) of the disk. When launching an image with a
4114- larger disk compared to the original image, the secondary copy
4115- is lost. Thus, the metadata will be marked CORRUPT, and need to
4116- be recovered.
4117- """
4118- try:
4119- util.subp(["gpart", "recover", diskdev])
4120- except util.ProcessExecutionError as e:
4121- if e.exit_code != 0:
4122- util.logexc(LOG, "Failed: gpart recover %s", diskdev)
4123- raise ResizeFailedException(e)
4124-
4125- before = get_size(partdev)
4126- try:
4127- util.subp(["gpart", "resize", "-i", partnum, diskdev])
4128- except util.ProcessExecutionError as e:
4129- util.logexc(LOG, "Failed: gpart resize -i %s %s", partnum, diskdev)
4130- raise ResizeFailedException(e)
4131-
4132- # Since growing the FS requires a reboot, make sure we reboot
4133- # first when this module has finished.
4134- open('/var/run/reboot-required', 'a').close()
4135-
4136- return (before, get_size(partdev))
4137-
4138-
4139-def get_size(filename):
4140- fd = os.open(filename, os.O_RDONLY)
4141- try:
4142- return os.lseek(fd, 0, os.SEEK_END)
4143- finally:
4144- os.close(fd)
4145-
4146-
4147-def device_part_info(devpath):
4148- # convert an entry in /dev/ to parent disk and partition number
4149-
4150- # input of /dev/vdb or /dev/disk/by-label/foo
4151- # rpath is hopefully a real-ish path in /dev (vda, sdb..)
4152- rpath = os.path.realpath(devpath)
4153-
4154- bname = os.path.basename(rpath)
4155- syspath = "/sys/class/block/%s" % bname
4156-
4157- # FreeBSD doesn't know of sysfs so just get everything we need from
4158- # the device, like /dev/vtbd0p2.
4159- if util.system_info()["platform"].startswith('FreeBSD'):
4160- m = re.search('^(/dev/.+)p([0-9])$', devpath)
4161- return (m.group(1), m.group(2))
4162-
4163- if not os.path.exists(syspath):
4164- raise ValueError("%s had no syspath (%s)" % (devpath, syspath))
4165-
4166- ptpath = os.path.join(syspath, "partition")
4167- if not os.path.exists(ptpath):
4168- raise TypeError("%s not a partition" % devpath)
4169-
4170- ptnum = util.load_file(ptpath).rstrip()
4171-
4172- # for a partition, real syspath is something like:
4173- # /sys/devices/pci0000:00/0000:00:04.0/virtio1/block/vda/vda1
4174- rsyspath = os.path.realpath(syspath)
4175- disksyspath = os.path.dirname(rsyspath)
4176-
4177- diskmajmin = util.load_file(os.path.join(disksyspath, "dev")).rstrip()
4178- diskdevpath = os.path.realpath("/dev/block/%s" % diskmajmin)
4179-
4180- # diskdevpath has something like 253:0
4181- # and udev has put links in /dev/block/253:0 to the device name in /dev/
4182- return (diskdevpath, ptnum)
4183-
4184-
4185-def devent2dev(devent):
4186- if devent.startswith("/dev/"):
4187- return devent
4188- else:
4189- result = util.get_mount_info(devent)
4190- if not result:
4191- raise ValueError("Could not determine device of '%s' % dev_ent")
4192- return result[0]
4193-
4194-
4195-def resize_devices(resizer, devices):
4196- # returns a tuple of tuples containing (entry-in-devices, action, message)
4197- info = []
4198- for devent in devices:
4199- try:
4200- blockdev = devent2dev(devent)
4201- except ValueError as e:
4202- info.append((devent, RESIZE.SKIPPED,
4203- "unable to convert to device: %s" % e,))
4204- continue
4205-
4206- try:
4207- statret = os.stat(blockdev)
4208- except OSError as e:
4209- info.append((devent, RESIZE.SKIPPED,
4210- "stat of '%s' failed: %s" % (blockdev, e),))
4211- continue
4212-
4213- if (not stat.S_ISBLK(statret.st_mode) and
4214- not stat.S_ISCHR(statret.st_mode)):
4215- info.append((devent, RESIZE.SKIPPED,
4216- "device '%s' not a block device" % blockdev,))
4217- continue
4218-
4219- try:
4220- (disk, ptnum) = device_part_info(blockdev)
4221- except (TypeError, ValueError) as e:
4222- info.append((devent, RESIZE.SKIPPED,
4223- "device_part_info(%s) failed: %s" % (blockdev, e),))
4224- continue
4225-
4226- try:
4227- (old, new) = resizer.resize(disk, ptnum, blockdev)
4228- if old == new:
4229- info.append((devent, RESIZE.NOCHANGE,
4230- "no change necessary (%s, %s)" % (disk, ptnum),))
4231- else:
4232- info.append((devent, RESIZE.CHANGED,
4233- "changed (%s, %s) from %s to %s" %
4234- (disk, ptnum, old, new),))
4235-
4236- except ResizeFailedException as e:
4237- info.append((devent, RESIZE.FAILED,
4238- "failed to resize: disk=%s, ptnum=%s: %s" %
4239- (disk, ptnum, e),))
4240-
4241- return info
4242-
4243-
4244-def handle(_name, cfg, _cloud, log, _args):
4245- if 'growpart' not in cfg:
4246- log.debug("No 'growpart' entry in cfg. Using default: %s" %
4247- DEFAULT_CONFIG)
4248- cfg['growpart'] = DEFAULT_CONFIG
4249-
4250- mycfg = cfg.get('growpart')
4251- if not isinstance(mycfg, dict):
4252- log.warn("'growpart' in config was not a dict")
4253- return
4254-
4255- mode = mycfg.get('mode', "auto")
4256- if util.is_false(mode):
4257- log.debug("growpart disabled: mode=%s" % mode)
4258- return
4259-
4260- if util.is_false(mycfg.get('ignore_growroot_disabled', False)):
4261- if os.path.isfile("/etc/growroot-disabled"):
4262- log.debug("growpart disabled: /etc/growroot-disabled exists")
4263- log.debug("use ignore_growroot_disabled to ignore")
4264- return
4265-
4266- devices = util.get_cfg_option_list(mycfg, "devices", ["/"])
4267- if not len(devices):
4268- log.debug("growpart: empty device list")
4269- return
4270-
4271- try:
4272- resizer = resizer_factory(mode)
4273- except (ValueError, TypeError) as e:
4274- log.debug("growpart unable to find resizer for '%s': %s" % (mode, e))
4275- if mode != "auto":
4276- raise e
4277- return
4278-
4279- resized = util.log_time(logfunc=log.debug, msg="resize_devices",
4280- func=resize_devices, args=(resizer, devices))
4281- for (entry, action, msg) in resized:
4282- if action == RESIZE.CHANGED:
4283- log.info("'%s' resized: %s" % (entry, msg))
4284- else:
4285- log.debug("'%s' %s: %s" % (entry, action, msg))
4286-
4287-RESIZERS = (('growpart', ResizeGrowPart), ('gpart', ResizeGpart))
4288
4289=== removed file 'cloudinit/config/cc_grub_dpkg.py'
4290--- cloudinit/config/cc_grub_dpkg.py 2016-05-12 17:56:26 +0000
4291+++ cloudinit/config/cc_grub_dpkg.py 1970-01-01 00:00:00 +0000
4292@@ -1,73 +0,0 @@
4293-# vi: ts=4 expandtab
4294-#
4295-# Copyright (C) 2009-2010 Canonical Ltd.
4296-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
4297-#
4298-# Author: Scott Moser <scott.moser@canonical.com>
4299-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
4300-#
4301-# This program is free software: you can redistribute it and/or modify
4302-# it under the terms of the GNU General Public License version 3, as
4303-# published by the Free Software Foundation.
4304-#
4305-# This program is distributed in the hope that it will be useful,
4306-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4307-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4308-# GNU General Public License for more details.
4309-#
4310-# You should have received a copy of the GNU General Public License
4311-# along with this program. If not, see <http://www.gnu.org/licenses/>.
4312-
4313-import os
4314-
4315-from cloudinit import util
4316-
4317-distros = ['ubuntu', 'debian']
4318-
4319-
4320-def handle(name, cfg, _cloud, log, _args):
4321-
4322- mycfg = cfg.get("grub_dpkg", cfg.get("grub-dpkg", {}))
4323- if not mycfg:
4324- mycfg = {}
4325-
4326- enabled = mycfg.get('enabled', True)
4327- if util.is_false(enabled):
4328- log.debug("%s disabled by config grub_dpkg/enabled=%s", name, enabled)
4329- return
4330-
4331- idevs = util.get_cfg_option_str(mycfg, "grub-pc/install_devices", None)
4332- idevs_empty = util.get_cfg_option_str(
4333- mycfg, "grub-pc/install_devices_empty", None)
4334-
4335- if ((os.path.exists("/dev/sda1") and not os.path.exists("/dev/sda")) or
4336- (os.path.exists("/dev/xvda1") and not os.path.exists("/dev/xvda"))):
4337- if idevs is None:
4338- idevs = ""
4339- if idevs_empty is None:
4340- idevs_empty = "true"
4341- else:
4342- if idevs_empty is None:
4343- idevs_empty = "false"
4344- if idevs is None:
4345- idevs = "/dev/sda"
4346- for dev in ("/dev/sda", "/dev/vda", "/dev/xvda",
4347- "/dev/sda1", "/dev/vda1", "/dev/xvda1"):
4348- if os.path.exists(dev):
4349- idevs = dev
4350- break
4351-
4352- # now idevs and idevs_empty are set to determined values
4353- # or, those set by user
4354-
4355- dconf_sel = (("grub-pc grub-pc/install_devices string %s\n"
4356- "grub-pc grub-pc/install_devices_empty boolean %s\n") %
4357- (idevs, idevs_empty))
4358-
4359- log.debug("Setting grub debconf-set-selections with '%s','%s'" %
4360- (idevs, idevs_empty))
4361-
4362- try:
4363- util.subp(['debconf-set-selections'], dconf_sel)
4364- except Exception:
4365- util.logexc(log, "Failed to run debconf-set-selections for grub-dpkg")
4366
4367=== removed file 'cloudinit/config/cc_keys_to_console.py'
4368--- cloudinit/config/cc_keys_to_console.py 2016-05-12 17:56:26 +0000
4369+++ cloudinit/config/cc_keys_to_console.py 1970-01-01 00:00:00 +0000
4370@@ -1,62 +0,0 @@
4371-# vi: ts=4 expandtab
4372-#
4373-# Copyright (C) 2011 Canonical Ltd.
4374-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
4375-#
4376-# Author: Scott Moser <scott.moser@canonical.com>
4377-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
4378-#
4379-# This program is free software: you can redistribute it and/or modify
4380-# it under the terms of the GNU General Public License version 3, as
4381-# published by the Free Software Foundation.
4382-#
4383-# This program is distributed in the hope that it will be useful,
4384-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4385-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4386-# GNU General Public License for more details.
4387-#
4388-# You should have received a copy of the GNU General Public License
4389-# along with this program. If not, see <http://www.gnu.org/licenses/>.
4390-
4391-import os
4392-
4393-from cloudinit.settings import PER_INSTANCE
4394-from cloudinit import util
4395-
4396-frequency = PER_INSTANCE
4397-
4398-# This is a tool that cloud init provides
4399-HELPER_TOOL_TPL = '%s/cloud-init/write-ssh-key-fingerprints'
4400-
4401-
4402-def _get_helper_tool_path(distro):
4403- try:
4404- base_lib = distro.usr_lib_exec
4405- except AttributeError:
4406- base_lib = '/usr/lib'
4407- return HELPER_TOOL_TPL % base_lib
4408-
4409-
4410-def handle(name, cfg, cloud, log, _args):
4411- helper_path = _get_helper_tool_path(cloud.distro)
4412- if not os.path.exists(helper_path):
4413- log.warn(("Unable to activate module %s,"
4414- " helper tool not found at %s"), name, helper_path)
4415- return
4416-
4417- fp_blacklist = util.get_cfg_option_list(cfg,
4418- "ssh_fp_console_blacklist", [])
4419- key_blacklist = util.get_cfg_option_list(cfg,
4420- "ssh_key_console_blacklist",
4421- ["ssh-dss"])
4422-
4423- try:
4424- cmd = [helper_path]
4425- cmd.append(','.join(fp_blacklist))
4426- cmd.append(','.join(key_blacklist))
4427- (stdout, _stderr) = util.subp(cmd)
4428- util.multi_log("%s\n" % (stdout.strip()),
4429- stderr=False, console=True)
4430- except Exception:
4431- log.warn("Writing keys to the system console failed!")
4432- raise
4433
4434=== removed file 'cloudinit/config/cc_landscape.py'
4435--- cloudinit/config/cc_landscape.py 2016-03-04 06:45:58 +0000
4436+++ cloudinit/config/cc_landscape.py 1970-01-01 00:00:00 +0000
4437@@ -1,99 +0,0 @@
4438-# vi: ts=4 expandtab
4439-#
4440-# Copyright (C) 2011 Canonical Ltd.
4441-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
4442-#
4443-# Author: Scott Moser <scott.moser@canonical.com>
4444-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
4445-#
4446-# This program is free software: you can redistribute it and/or modify
4447-# it under the terms of the GNU General Public License version 3, as
4448-# published by the Free Software Foundation.
4449-#
4450-# This program is distributed in the hope that it will be useful,
4451-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4452-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4453-# GNU General Public License for more details.
4454-#
4455-# You should have received a copy of the GNU General Public License
4456-# along with this program. If not, see <http://www.gnu.org/licenses/>.
4457-
4458-import os
4459-
4460-from six import StringIO
4461-
4462-from configobj import ConfigObj
4463-
4464-from cloudinit import type_utils
4465-from cloudinit import util
4466-
4467-from cloudinit.settings import PER_INSTANCE
4468-
4469-frequency = PER_INSTANCE
4470-
4471-LSC_CLIENT_CFG_FILE = "/etc/landscape/client.conf"
4472-LS_DEFAULT_FILE = "/etc/default/landscape-client"
4473-
4474-distros = ['ubuntu']
4475-
4476-# defaults taken from stock client.conf in landscape-client 11.07.1.1-0ubuntu2
4477-LSC_BUILTIN_CFG = {
4478- 'client': {
4479- 'log_level': "info",
4480- 'url': "https://landscape.canonical.com/message-system",
4481- 'ping_url': "http://landscape.canonical.com/ping",
4482- 'data_path': "/var/lib/landscape/client",
4483- }
4484-}
4485-
4486-
4487-def handle(_name, cfg, cloud, log, _args):
4488- """
4489- Basically turn a top level 'landscape' entry with a 'client' dict
4490- and render it to ConfigObj format under '[client]' section in
4491- /etc/landscape/client.conf
4492- """
4493-
4494- ls_cloudcfg = cfg.get("landscape", {})
4495-
4496- if not isinstance(ls_cloudcfg, (dict)):
4497- raise RuntimeError(("'landscape' key existed in config,"
4498- " but not a dictionary type,"
4499- " is a %s instead"),
4500- type_utils.obj_name(ls_cloudcfg))
4501- if not ls_cloudcfg:
4502- return
4503-
4504- cloud.distro.install_packages(('landscape-client',))
4505-
4506- merge_data = [
4507- LSC_BUILTIN_CFG,
4508- LSC_CLIENT_CFG_FILE,
4509- ls_cloudcfg,
4510- ]
4511- merged = merge_together(merge_data)
4512- contents = StringIO()
4513- merged.write(contents)
4514-
4515- util.ensure_dir(os.path.dirname(LSC_CLIENT_CFG_FILE))
4516- util.write_file(LSC_CLIENT_CFG_FILE, contents.getvalue())
4517- log.debug("Wrote landscape config file to %s", LSC_CLIENT_CFG_FILE)
4518-
4519- util.write_file(LS_DEFAULT_FILE, "RUN=1\n")
4520- util.subp(["service", "landscape-client", "restart"])
4521-
4522-
4523-def merge_together(objs):
4524- """
4525- merge together ConfigObj objects or things that ConfigObj() will take in
4526- later entries override earlier
4527- """
4528- cfg = ConfigObj({})
4529- for obj in objs:
4530- if not obj:
4531- continue
4532- if isinstance(obj, ConfigObj):
4533- cfg.merge(obj)
4534- else:
4535- cfg.merge(ConfigObj(obj))
4536- return cfg
4537
4538=== removed file 'cloudinit/config/cc_locale.py'
4539--- cloudinit/config/cc_locale.py 2015-03-04 19:49:44 +0000
4540+++ cloudinit/config/cc_locale.py 1970-01-01 00:00:00 +0000
4541@@ -1,37 +0,0 @@
4542-# vi: ts=4 expandtab
4543-#
4544-# Copyright (C) 2011 Canonical Ltd.
4545-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
4546-#
4547-# Author: Scott Moser <scott.moser@canonical.com>
4548-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
4549-#
4550-# This program is free software: you can redistribute it and/or modify
4551-# it under the terms of the GNU General Public License version 3, as
4552-# published by the Free Software Foundation.
4553-#
4554-# This program is distributed in the hope that it will be useful,
4555-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4556-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4557-# GNU General Public License for more details.
4558-#
4559-# You should have received a copy of the GNU General Public License
4560-# along with this program. If not, see <http://www.gnu.org/licenses/>.
4561-
4562-from cloudinit import util
4563-
4564-
4565-def handle(name, cfg, cloud, log, args):
4566- if len(args) != 0:
4567- locale = args[0]
4568- else:
4569- locale = util.get_cfg_option_str(cfg, "locale", cloud.get_locale())
4570-
4571- if util.is_false(locale):
4572- log.debug("Skipping module named %s, disabled by config: %s",
4573- name, locale)
4574- return
4575-
4576- log.debug("Setting locale to %s", locale)
4577- locale_cfgfile = util.get_cfg_option_str(cfg, "locale_configfile")
4578- cloud.distro.apply_locale(locale, locale_cfgfile)
4579
4580=== removed file 'cloudinit/config/cc_lxd.py'
4581--- cloudinit/config/cc_lxd.py 2016-05-12 17:56:26 +0000
4582+++ cloudinit/config/cc_lxd.py 1970-01-01 00:00:00 +0000
4583@@ -1,176 +0,0 @@
4584-# vi: ts=4 expandtab
4585-#
4586-# Copyright (C) 2016 Canonical Ltd.
4587-#
4588-# Author: Wesley Wiedenmeier <wesley.wiedenmeier@canonical.com>
4589-#
4590-# This program is free software: you can redistribute it and/or modify
4591-# it under the terms of the GNU General Public License version 3, as
4592-# published by the Free Software Foundation.
4593-#
4594-# This program is distributed in the hope that it will be useful,
4595-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4596-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4597-# GNU General Public License for more details.
4598-#
4599-# You should have received a copy of the GNU General Public License
4600-# along with this program. If not, see <http://www.gnu.org/licenses/>.
4601-
4602-"""
4603-This module initializes lxd using 'lxd init'
4604-
4605-Example config:
4606- #cloud-config
4607- lxd:
4608- init:
4609- network_address: <ip addr>
4610- network_port: <port>
4611- storage_backend: <zfs/dir>
4612- storage_create_device: <dev>
4613- storage_create_loop: <size>
4614- storage_pool: <name>
4615- trust_password: <password>
4616- bridge:
4617- mode: <new, existing or none>
4618- name: <name>
4619- ipv4_address: <ip addr>
4620- ipv4_netmask: <cidr>
4621- ipv4_dhcp_first: <ip addr>
4622- ipv4_dhcp_last: <ip addr>
4623- ipv4_dhcp_leases: <size>
4624- ipv4_nat: <bool>
4625- ipv6_address: <ip addr>
4626- ipv6_netmask: <cidr>
4627- ipv6_nat: <bool>
4628- domain: <domain>
4629-"""
4630-
4631-from cloudinit import util
4632-
4633-
4634-def handle(name, cfg, cloud, log, args):
4635- # Get config
4636- lxd_cfg = cfg.get('lxd')
4637- if not lxd_cfg:
4638- log.debug("Skipping module named %s, not present or disabled by cfg")
4639- return
4640- if not isinstance(lxd_cfg, dict):
4641- log.warn("lxd config must be a dictionary. found a '%s'",
4642- type(lxd_cfg))
4643- return
4644-
4645- # Grab the configuration
4646- init_cfg = lxd_cfg.get('init')
4647- if not isinstance(init_cfg, dict):
4648- log.warn("lxd/init config must be a dictionary. found a '%s'",
4649- type(init_cfg))
4650- init_cfg = {}
4651-
4652- bridge_cfg = lxd_cfg.get('bridge')
4653- if not isinstance(bridge_cfg, dict):
4654- log.warn("lxd/bridge config must be a dictionary. found a '%s'",
4655- type(bridge_cfg))
4656- bridge_cfg = {}
4657-
4658- # Install the needed packages
4659- packages = []
4660- if not util.which("lxd"):
4661- packages.append('lxd')
4662-
4663- if init_cfg.get("storage_backend") == "zfs" and not util.which('zfs'):
4664- packages.append('zfs')
4665-
4666- if len(packages):
4667- try:
4668- cloud.distro.install_packages(packages)
4669- except util.ProcessExecutionError as exc:
4670- log.warn("failed to install packages %s: %s", packages, exc)
4671- return
4672-
4673- # Set up lxd if init config is given
4674- if init_cfg:
4675- init_keys = (
4676- 'network_address', 'network_port', 'storage_backend',
4677- 'storage_create_device', 'storage_create_loop',
4678- 'storage_pool', 'trust_password')
4679- cmd = ['lxd', 'init', '--auto']
4680- for k in init_keys:
4681- if init_cfg.get(k):
4682- cmd.extend(["--%s=%s" %
4683- (k.replace('_', '-'), str(init_cfg[k]))])
4684- util.subp(cmd)
4685-
4686- # Set up lxd-bridge if bridge config is given
4687- dconf_comm = "debconf-communicate"
4688- if bridge_cfg and util.which(dconf_comm):
4689- debconf = bridge_to_debconf(bridge_cfg)
4690-
4691- # Update debconf database
4692- try:
4693- log.debug("Setting lxd debconf via " + dconf_comm)
4694- data = "\n".join(["set %s %s" % (k, v)
4695- for k, v in debconf.items()]) + "\n"
4696- util.subp(['debconf-communicate'], data)
4697- except Exception:
4698- util.logexc(log, "Failed to run '%s' for lxd with" % dconf_comm)
4699-
4700- # Remove the existing configuration file (forces re-generation)
4701- util.del_file("/etc/default/lxd-bridge")
4702-
4703- # Run reconfigure
4704- log.debug("Running dpkg-reconfigure for lxd")
4705- util.subp(['dpkg-reconfigure', 'lxd',
4706- '--frontend=noninteractive'])
4707- elif bridge_cfg:
4708- raise RuntimeError(
4709- "Unable to configure lxd bridge without %s." + dconf_comm)
4710-
4711-
4712-def bridge_to_debconf(bridge_cfg):
4713- debconf = {}
4714-
4715- if bridge_cfg.get("mode") == "none":
4716- debconf["lxd/setup-bridge"] = "false"
4717- debconf["lxd/bridge-name"] = ""
4718-
4719- elif bridge_cfg.get("mode") == "existing":
4720- debconf["lxd/setup-bridge"] = "false"
4721- debconf["lxd/use-existing-bridge"] = "true"
4722- debconf["lxd/bridge-name"] = bridge_cfg.get("name")
4723-
4724- elif bridge_cfg.get("mode") == "new":
4725- debconf["lxd/setup-bridge"] = "true"
4726- if bridge_cfg.get("name"):
4727- debconf["lxd/bridge-name"] = bridge_cfg.get("name")
4728-
4729- if bridge_cfg.get("ipv4_address"):
4730- debconf["lxd/bridge-ipv4"] = "true"
4731- debconf["lxd/bridge-ipv4-address"] = \
4732- bridge_cfg.get("ipv4_address")
4733- debconf["lxd/bridge-ipv4-netmask"] = \
4734- bridge_cfg.get("ipv4_netmask")
4735- debconf["lxd/bridge-ipv4-dhcp-first"] = \
4736- bridge_cfg.get("ipv4_dhcp_first")
4737- debconf["lxd/bridge-ipv4-dhcp-last"] = \
4738- bridge_cfg.get("ipv4_dhcp_last")
4739- debconf["lxd/bridge-ipv4-dhcp-leases"] = \
4740- bridge_cfg.get("ipv4_dhcp_leases")
4741- debconf["lxd/bridge-ipv4-nat"] = \
4742- bridge_cfg.get("ipv4_nat", "true")
4743-
4744- if bridge_cfg.get("ipv6_address"):
4745- debconf["lxd/bridge-ipv6"] = "true"
4746- debconf["lxd/bridge-ipv6-address"] = \
4747- bridge_cfg.get("ipv6_address")
4748- debconf["lxd/bridge-ipv6-netmask"] = \
4749- bridge_cfg.get("ipv6_netmask")
4750- debconf["lxd/bridge-ipv6-nat"] = \
4751- bridge_cfg.get("ipv6_nat", "false")
4752-
4753- if bridge_cfg.get("domain"):
4754- debconf["lxd/bridge-domain"] = bridge_cfg.get("domain")
4755-
4756- else:
4757- raise Exception("invalid bridge mode \"%s\"" % bridge_cfg.get("mode"))
4758-
4759- return debconf
4760
4761=== removed file 'cloudinit/config/cc_mcollective.py'
4762--- cloudinit/config/cc_mcollective.py 2015-01-21 22:56:53 +0000
4763+++ cloudinit/config/cc_mcollective.py 1970-01-01 00:00:00 +0000
4764@@ -1,88 +0,0 @@
4765-# vi: ts=4 expandtab
4766-#
4767-# Copyright (C) 2009-2011 Canonical Ltd.
4768-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
4769-#
4770-# Author: Marc Cluet <marc.cluet@canonical.com>
4771-# Based on code by Scott Moser <scott.moser@canonical.com>
4772-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
4773-#
4774-# This program is free software: you can redistribute it and/or modify
4775-# it under the terms of the GNU General Public License version 3, as
4776-# published by the Free Software Foundation.
4777-#
4778-# This program is distributed in the hope that it will be useful,
4779-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4780-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4781-# GNU General Public License for more details.
4782-#
4783-# You should have received a copy of the GNU General Public License
4784-# along with this program. If not, see <http://www.gnu.org/licenses/>.
4785-
4786-import six
4787-from six import StringIO
4788-
4789-# Used since this can maintain comments
4790-# and doesn't need a top level section
4791-from configobj import ConfigObj
4792-
4793-from cloudinit import util
4794-
4795-PUBCERT_FILE = "/etc/mcollective/ssl/server-public.pem"
4796-PRICERT_FILE = "/etc/mcollective/ssl/server-private.pem"
4797-SERVER_CFG = '/etc/mcollective/server.cfg'
4798-
4799-
4800-def handle(name, cfg, cloud, log, _args):
4801-
4802- # If there isn't a mcollective key in the configuration don't do anything
4803- if 'mcollective' not in cfg:
4804- log.debug(("Skipping module named %s, "
4805- "no 'mcollective' key in configuration"), name)
4806- return
4807-
4808- mcollective_cfg = cfg['mcollective']
4809-
4810- # Start by installing the mcollective package ...
4811- cloud.distro.install_packages(("mcollective",))
4812-
4813- # ... and then update the mcollective configuration
4814- if 'conf' in mcollective_cfg:
4815- # Read server.cfg values from the
4816- # original file in order to be able to mix the rest up
4817- mcollective_config = ConfigObj(SERVER_CFG)
4818- # See: http://tiny.cc/jh9agw
4819- for (cfg_name, cfg) in mcollective_cfg['conf'].items():
4820- if cfg_name == 'public-cert':
4821- util.write_file(PUBCERT_FILE, cfg, mode=0o644)
4822- mcollective_config['plugin.ssl_server_public'] = PUBCERT_FILE
4823- mcollective_config['securityprovider'] = 'ssl'
4824- elif cfg_name == 'private-cert':
4825- util.write_file(PRICERT_FILE, cfg, mode=0o600)
4826- mcollective_config['plugin.ssl_server_private'] = PRICERT_FILE
4827- mcollective_config['securityprovider'] = 'ssl'
4828- else:
4829- if isinstance(cfg, six.string_types):
4830- # Just set it in the 'main' section
4831- mcollective_config[cfg_name] = cfg
4832- elif isinstance(cfg, (dict)):
4833- # Iterate through the config items, create a section
4834- # if it is needed and then add/or create items as needed
4835- if cfg_name not in mcollective_config.sections:
4836- mcollective_config[cfg_name] = {}
4837- for (o, v) in cfg.items():
4838- mcollective_config[cfg_name][o] = v
4839- else:
4840- # Otherwise just try to convert it to a string
4841- mcollective_config[cfg_name] = str(cfg)
4842- # We got all our config as wanted we'll rename
4843- # the previous server.cfg and create our new one
4844- util.rename(SERVER_CFG, "%s.old" % (SERVER_CFG))
4845- # Now we got the whole file, write to disk...
4846- contents = StringIO()
4847- mcollective_config.write(contents)
4848- contents = contents.getvalue()
4849- util.write_file(SERVER_CFG, contents, mode=0o644)
4850-
4851- # Start mcollective
4852- util.subp(['service', 'mcollective', 'start'], capture=False)
4853
4854=== removed file 'cloudinit/config/cc_migrator.py'
4855--- cloudinit/config/cc_migrator.py 2014-02-05 15:36:47 +0000
4856+++ cloudinit/config/cc_migrator.py 1970-01-01 00:00:00 +0000
4857@@ -1,85 +0,0 @@
4858-# vi: ts=4 expandtab
4859-#
4860-# Copyright (C) 2012 Yahoo! Inc.
4861-#
4862-# Author: Joshua Harlow <harlowja@yahoo-inc.com>
4863-#
4864-# This program is free software: you can redistribute it and/or modify
4865-# it under the terms of the GNU General Public License version 3, as
4866-# published by the Free Software Foundation.
4867-#
4868-# This program is distributed in the hope that it will be useful,
4869-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4870-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4871-# GNU General Public License for more details.
4872-#
4873-# You should have received a copy of the GNU General Public License
4874-# along with this program. If not, see <http://www.gnu.org/licenses/>.
4875-
4876-import os
4877-import shutil
4878-
4879-from cloudinit import helpers
4880-from cloudinit import util
4881-
4882-from cloudinit.settings import PER_ALWAYS
4883-
4884-frequency = PER_ALWAYS
4885-
4886-
4887-def _migrate_canon_sems(cloud):
4888- paths = (cloud.paths.get_ipath('sem'), cloud.paths.get_cpath('sem'))
4889- am_adjusted = 0
4890- for sem_path in paths:
4891- if not sem_path or not os.path.exists(sem_path):
4892- continue
4893- for p in os.listdir(sem_path):
4894- full_path = os.path.join(sem_path, p)
4895- if os.path.isfile(full_path):
4896- (name, ext) = os.path.splitext(p)
4897- canon_name = helpers.canon_sem_name(name)
4898- if canon_name != name:
4899- new_path = os.path.join(sem_path, canon_name + ext)
4900- shutil.move(full_path, new_path)
4901- am_adjusted += 1
4902- return am_adjusted
4903-
4904-
4905-def _migrate_legacy_sems(cloud, log):
4906- legacy_adjust = {
4907- 'apt-update-upgrade': [
4908- 'apt-configure',
4909- 'package-update-upgrade-install',
4910- ],
4911- }
4912- paths = (cloud.paths.get_ipath('sem'), cloud.paths.get_cpath('sem'))
4913- for sem_path in paths:
4914- if not sem_path or not os.path.exists(sem_path):
4915- continue
4916- sem_helper = helpers.FileSemaphores(sem_path)
4917- for (mod_name, migrate_to) in legacy_adjust.items():
4918- possibles = [mod_name, helpers.canon_sem_name(mod_name)]
4919- old_exists = []
4920- for p in os.listdir(sem_path):
4921- (name, _ext) = os.path.splitext(p)
4922- if name in possibles and os.path.isfile(p):
4923- old_exists.append(p)
4924- for p in old_exists:
4925- util.del_file(os.path.join(sem_path, p))
4926- (_name, freq) = os.path.splitext(p)
4927- for m in migrate_to:
4928- log.debug("Migrating %s => %s with the same frequency",
4929- p, m)
4930- with sem_helper.lock(m, freq):
4931- pass
4932-
4933-
4934-def handle(name, cfg, cloud, log, _args):
4935- do_migrate = util.get_cfg_option_str(cfg, "migrate", True)
4936- if not util.translate_bool(do_migrate):
4937- log.debug("Skipping module named %s, migration disabled", name)
4938- return
4939- sems_moved = _migrate_canon_sems(cloud)
4940- log.debug("Migrated %s semaphore files to there canonicalized names",
4941- sems_moved)
4942- _migrate_legacy_sems(cloud, log)
4943
4944=== removed file 'cloudinit/config/cc_mounts.py'
4945--- cloudinit/config/cc_mounts.py 2016-05-12 17:56:26 +0000
4946+++ cloudinit/config/cc_mounts.py 1970-01-01 00:00:00 +0000
4947@@ -1,405 +0,0 @@
4948-# vi: ts=4 expandtab
4949-#
4950-# Copyright (C) 2009-2010 Canonical Ltd.
4951-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
4952-#
4953-# Author: Scott Moser <scott.moser@canonical.com>
4954-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
4955-#
4956-# This program is free software: you can redistribute it and/or modify
4957-# it under the terms of the GNU General Public License version 3, as
4958-# published by the Free Software Foundation.
4959-#
4960-# This program is distributed in the hope that it will be useful,
4961-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4962-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4963-# GNU General Public License for more details.
4964-#
4965-# You should have received a copy of the GNU General Public License
4966-# along with this program. If not, see <http://www.gnu.org/licenses/>.
4967-
4968-from string import whitespace
4969-
4970-import logging
4971-import os.path
4972-import re
4973-
4974-from cloudinit import type_utils
4975-from cloudinit import util
4976-
4977-# Shortname matches 'sda', 'sda1', 'xvda', 'hda', 'sdb', xvdb, vda, vdd1, sr0
4978-DEVICE_NAME_FILTER = r"^([x]{0,1}[shv]d[a-z][0-9]*|sr[0-9]+)$"
4979-DEVICE_NAME_RE = re.compile(DEVICE_NAME_FILTER)
4980-WS = re.compile("[%s]+" % (whitespace))
4981-FSTAB_PATH = "/etc/fstab"
4982-
4983-LOG = logging.getLogger(__name__)
4984-
4985-
4986-def is_meta_device_name(name):
4987- # return true if this is a metadata service name
4988- if name in ["ami", "root", "swap"]:
4989- return True
4990- # names 'ephemeral0' or 'ephemeral1'
4991- # 'ebs[0-9]' appears when '--block-device-mapping sdf=snap-d4d90bbc'
4992- for enumname in ("ephemeral", "ebs"):
4993- if name.startswith(enumname) and name.find(":") == -1:
4994- return True
4995- return False
4996-
4997-
4998-def _get_nth_partition_for_device(device_path, partition_number):
4999- potential_suffixes = [str(partition_number), 'p%s' % (partition_number,),
5000- '-part%s' % (partition_number,)]
The diff has been truncated for viewing.