├── .gitignore ├── .travis.yml ├── .yamllint ├── CHANGELOG.rst ├── CONTRIBUTING.rst ├── LICENSE ├── MANIFEST.in ├── README.rst ├── bootstrap-vz ├── bootstrap-vz-remote ├── bootstrap-vz-server ├── bootstrapvz ├── README.rst ├── __init__.py ├── base │ ├── __init__.py │ ├── bootstrapinfo.py │ ├── fs │ │ ├── __init__.py │ │ ├── exceptions.py │ │ ├── partitionmaps │ │ │ ├── __init__.py │ │ │ ├── abstract.py │ │ │ ├── gpt.py │ │ │ ├── msdos.py │ │ │ └── none.py │ │ ├── partitions │ │ │ ├── __init__.py │ │ │ ├── abstract.py │ │ │ ├── base.py │ │ │ ├── gpt.py │ │ │ ├── gpt_swap.py │ │ │ ├── mount.py │ │ │ ├── msdos.py │ │ │ ├── msdos_swap.py │ │ │ ├── single.py │ │ │ └── unformatted.py │ │ └── volume.py │ ├── log.py │ ├── main.py │ ├── manifest-schema.yml │ ├── manifest.py │ ├── metaschema.json │ ├── phase.py │ ├── pkg │ │ ├── __init__.py │ │ ├── exceptions.py │ │ ├── packagelist.py │ │ ├── preferenceslist.py │ │ └── sourceslist.py │ ├── task.py │ └── tasklist.py ├── common │ ├── __init__.py │ ├── assets │ │ ├── extlinux │ │ │ ├── boot.txt │ │ │ └── extlinux.conf │ │ ├── init.d │ │ │ ├── expand-root │ │ │ ├── jessie │ │ │ │ └── generate-ssh-hostkeys │ │ │ ├── ssh-generate-hostkeys │ │ │ └── wheezy │ │ │ │ └── generate-ssh-hostkeys │ │ ├── ssh-generate-hostkeys │ │ └── systemd │ │ │ ├── logind.conf │ │ │ └── ssh-generate-hostkeys.service │ ├── bytes.py │ ├── exceptions.py │ ├── fs │ │ ├── __init__.py │ │ ├── folder.py │ │ ├── logicalvolume.py │ │ ├── loopbackvolume.py │ │ ├── qcow2volume.py │ │ ├── qemuvolume.py │ │ ├── virtualdiskimage.py │ │ ├── virtualharddisk.py │ │ └── virtualmachinedisk.py │ ├── fsm_proxy.py │ ├── phases.py │ ├── releases.py │ ├── sectors.py │ ├── task_groups.py │ ├── tasks │ │ ├── __init__.py │ │ ├── apt.py │ │ ├── boot.py │ │ ├── bootstrap.py │ │ ├── cleanup.py │ │ ├── development.py │ │ ├── dpkg.py │ │ ├── extlinux.py │ │ ├── filesystem.py │ │ ├── folder.py │ │ ├── grub.py │ │ ├── host.py │ │ ├── image.py │ │ ├── initd.py │ │ ├── kernel.py │ │ ├── locale.py │ │ ├── logicalvolume.py │ │ ├── loopback.py │ │ ├── network-configuration.yml │ │ ├── network.py │ │ ├── packages.py │ │ ├── partitioning.py │ │ ├── security.py │ │ ├── ssh.py │ │ ├── volume.py │ │ └── workspace.py │ └── tools.py ├── plugins │ ├── README.rst │ ├── __init__.py │ ├── admin_user │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── ansible │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── apt_proxy │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── chef │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── cloud_init │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ │ └── cloud-init │ │ │ │ └── debian_cloud.cfg │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── commands │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── debconf │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── docker_daemon │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ │ ├── default │ │ │ │ └── docker │ │ │ └── init.d │ │ │ │ └── docker │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── ec2_launch │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── ec2_publish │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── expand_root │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ │ ├── expand-root │ │ │ └── expand-root.service │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── file_copy │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── google_cloud_repo │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── minimize_size │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ │ ├── apt-autoremove-suggests │ │ │ ├── apt-clean │ │ │ ├── apt-gzip-indexes │ │ │ ├── apt-languages │ │ │ ├── bootstrap-files-filter.sh │ │ │ └── bootstrap-script.sh │ │ ├── manifest-schema.yml │ │ └── tasks │ │ │ ├── __init__.py │ │ │ ├── apt.py │ │ │ ├── dpkg.py │ │ │ ├── mounts.py │ │ │ └── shrink.py │ ├── ntp │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── opennebula │ │ ├── README.rst │ │ ├── __init__.py │ │ └── tasks.py │ ├── pip3_install │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── pip_install │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── prebootstrapped │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── puppet │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ │ └── gpg-keyrings-PC1 │ │ │ │ ├── jessie │ │ │ │ └── puppetlabs-pc1-keyring.gpg │ │ │ │ ├── stretch │ │ │ │ └── puppetlabs-pc1-keyring.gpg │ │ │ │ └── wheezy │ │ │ │ └── puppetlabs-pc1-keyring.gpg │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── root_password │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── salt │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ ├── tmpfs_workspace │ │ ├── README.rst │ │ ├── __init__.py │ │ └── tasks.py │ ├── unattended_upgrades │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks.py │ └── vagrant │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ ├── Vagrantfile │ │ ├── authorized_keys │ │ ├── box.ovf │ │ └── metadata.json │ │ ├── manifest-schema.yml │ │ └── tasks.py ├── providers │ ├── README.rst │ ├── __init__.py │ ├── azure │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ │ └── udev.diff │ │ ├── manifest-schema.yml │ │ └── tasks │ │ │ ├── __init__.py │ │ │ ├── boot.py │ │ │ ├── packages-kernels.yml │ │ │ └── packages.py │ ├── docker │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ │ └── docker-apt-speedup │ │ ├── manifest-schema.yml │ │ └── tasks │ │ │ ├── __init__.py │ │ │ ├── commands.py │ │ │ ├── image.py │ │ │ └── settings.py │ ├── ec2 │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ │ ├── bin │ │ │ │ └── growpart │ │ │ ├── certs │ │ │ │ └── cert-ec2.pem │ │ │ ├── ec2 │ │ │ │ ├── 53-ec2-network-interfaces.rules │ │ │ │ ├── ec2dhcp.sh │ │ │ │ ├── ec2net-functions │ │ │ │ └── ec2net.hotplug │ │ │ ├── grub.d │ │ │ │ └── 40_custom │ │ │ ├── init.d │ │ │ │ ├── ec2-get-credentials │ │ │ │ └── ec2-run-user-data │ │ │ └── sysctl.d │ │ │ │ └── tuning.conf │ │ ├── ebsvolume.py │ │ ├── manifest-schema-s3.yml │ │ ├── manifest-schema.yml │ │ └── tasks │ │ │ ├── __init__.py │ │ │ ├── ami-akis.yml │ │ │ ├── ami.py │ │ │ ├── boot.py │ │ │ ├── connection.py │ │ │ ├── ebs.py │ │ │ ├── filesystem.py │ │ │ ├── host.py │ │ │ ├── initd.py │ │ │ ├── network.py │ │ │ ├── packages-kernels.yml │ │ │ ├── packages.py │ │ │ └── tuning.py │ ├── gce │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── manifest-schema.yml │ │ └── tasks │ │ │ ├── __init__.py │ │ │ ├── apt.py │ │ │ ├── boot.py │ │ │ ├── configuration.py │ │ │ ├── image.py │ │ │ ├── packages-kernels.yml │ │ │ └── packages.py │ ├── kvm │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ │ └── noclear.conf │ │ ├── manifest-schema.yml │ │ └── tasks │ │ │ ├── __init__.py │ │ │ ├── boot.py │ │ │ ├── packages-kernels.yml │ │ │ ├── packages.py │ │ │ └── virtio.py │ ├── oracle │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── apiclient.py │ │ ├── manifest-schema.yml │ │ └── tasks │ │ │ ├── __init__.py │ │ │ ├── api.py │ │ │ ├── image.py │ │ │ ├── network.py │ │ │ ├── packages-kernels.yml │ │ │ └── packages.py │ └── virtualbox │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── assets │ │ └── install_guest_additions.sh │ │ ├── manifest-schema.yml │ │ └── tasks │ │ ├── __init__.py │ │ ├── boot.py │ │ ├── guest_additions.py │ │ ├── packages-kernels.yml │ │ └── packages.py └── remote │ ├── README.rst │ ├── __init__.py │ ├── build_servers │ ├── __init__.py │ ├── build-servers-schema.yml │ ├── build_server.py │ ├── callback.py │ ├── local.py │ └── remote.py │ ├── log.py │ ├── main.py │ └── server.py ├── docs ├── .gitignore ├── README.rst ├── __init__.py ├── _static │ ├── .gitignore │ ├── taskoverview.coffee │ └── taskoverview.less ├── api │ ├── base │ │ ├── fs.rst │ │ ├── index.rst │ │ └── pkg.rst │ ├── common │ │ ├── fs.rst │ │ ├── index.rst │ │ └── tasks │ │ │ └── index.rst │ └── index.rst ├── changelog.rst ├── conf.py ├── developers │ ├── contributing.rst │ ├── documentation.rst │ ├── index.rst │ ├── plugins.rst │ ├── switches.rst │ └── taskoverview.rst ├── index.rst ├── logging.rst ├── manifests │ ├── index.rst │ ├── official_ec2_manifests.rst │ └── official_gce_manifests.rst ├── plugins │ ├── .gitignore │ └── index.rst ├── providers │ ├── .gitignore │ └── index.rst ├── remote_bootstrapping.rst ├── supported_builds.rst ├── taskoverview.py ├── testing │ ├── index.rst │ ├── system_test_providers │ │ ├── .gitignore │ │ └── index.rst │ ├── system_tests.rst │ └── unit_tests.rst └── transform_github_links.py ├── manifests ├── README.rst ├── examples │ ├── azure │ │ ├── jessie.yml │ │ └── wheezy.yml │ ├── docker │ │ ├── jessie-minimized.yml │ │ ├── stretch-minimized.yml │ │ └── stretch.yml │ ├── ec2 │ │ ├── ebs-testing-amd64-pvm.yml │ │ ├── ebs-unstable-amd64-pvm-contrib.yml │ │ ├── ebs-unstable-amd64-pvm.yml │ │ └── s3-wheezy-amd64-pvm.yml │ ├── kvm │ │ ├── buster-cloudimg.yml │ │ ├── buster-console.yml │ │ ├── buster-virtio-partitions.yml │ │ ├── jessie-arm64-virtio.yml │ │ ├── jessie-lvm.yml │ │ ├── jessie-puppet.yaml │ │ ├── jessie-qcow2.yml │ │ ├── jessie-virtio.yml │ │ ├── stretch-cloudimg.yml │ │ ├── stretch-console.yml │ │ ├── stretch-puppet.yaml │ │ ├── stretch-virtio-partitions.yml │ │ ├── wheezy-virtio.yml │ │ └── wheezy.yml │ └── virtualbox │ │ ├── jessie-vagrant.yml │ │ ├── stretch-vagrant.yml │ │ ├── wheezy-vagrant.yml │ │ └── wheezy.yml └── official │ ├── ec2 │ ├── README.rst │ ├── ebs-jessie-amd64-hvm.yml │ ├── ebs-stretch-amd64-hvm.yml │ ├── ebs-wheezy-amd64-hvm-cn-north-1.yml │ ├── ebs-wheezy-amd64-hvm.yml │ ├── ebs-wheezy-amd64-pvm-cn-north-1.yml │ ├── ebs-wheezy-amd64-pvm.yml │ ├── ebs-wheezy-i386-pvm.yml │ └── s3-wheezy-amd64-pvm-cn-north-1.yml │ ├── gce │ ├── README.rst │ ├── buster-minimal.yml │ ├── buster.yml │ ├── deprecated │ │ ├── wheezy-backports.yml │ │ └── wheezy.yml │ ├── jessie-minimal.yml │ ├── jessie.yml │ ├── stretch-minimal.yml │ └── stretch.yml │ └── oracle │ └── jessie.yml ├── pylintrc ├── setup.py ├── tests ├── README.rst ├── __init__.py ├── integration │ ├── __init__.py │ └── dry_run_tests.py ├── system │ ├── README.rst │ ├── __init__.py │ ├── docker_tests.py │ ├── ec2_ebs_hvm_tests.py │ ├── ec2_ebs_pvm_tests.py │ ├── ec2_s3_pvm_tests.py │ ├── manifests │ │ ├── __init__.py │ │ ├── base.yml │ │ ├── extlinux.yml │ │ ├── gpt.yml │ │ ├── grub.yml │ │ ├── msdos.yml │ │ ├── oldstable64.yml │ │ ├── partitioned.yml │ │ ├── root_password.yml │ │ ├── single_partition.yml │ │ ├── stable64.yml │ │ ├── stable86.yml │ │ ├── unpartitioned.yml │ │ └── unstable64.yml │ ├── providers │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── docker │ │ │ ├── README.rst │ │ │ ├── __init__.py │ │ │ └── image.py │ │ ├── ec2 │ │ │ ├── README.rst │ │ │ ├── __init__.py │ │ │ └── images.py │ │ └── virtualbox │ │ │ ├── README.rst │ │ │ ├── __init__.py │ │ │ ├── image.py │ │ │ └── instance.py │ ├── tools │ │ ├── __init__.py │ │ └── exceptions.py │ └── virtualbox_tests.py └── unit │ ├── README.rst │ ├── __init__.py │ ├── bytes_tests.py │ ├── manifests_tests.py │ ├── releases_tests.py │ ├── sectors_tests.py │ ├── subprocess.sh │ └── tools_tests.py └── tox.ini /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | # Jekyll-generated files 3 | /Gemfile.lock 4 | /_site/ 5 | # When developing for ec2 `vagrant provision' is quite handy 6 | /Vagrantfile 7 | /.vagrant/ 8 | # Building the package 9 | /build/ 10 | /dist/ 11 | /bootstrap_vz.egg-info/ 12 | # Testing 13 | /.coverage 14 | /.tox/ 15 | /build-servers.yml 16 | /integration.html 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: False 2 | language: python 3 | python: 4 | - "2.7" 5 | install: 6 | - "pip install tox" 7 | script: 8 | - "tox" 9 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | line-length: 6 | max: 160 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013-2014 Anders Ingemann 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include manifests/* 3 | recursive-include bootstrapvz *.json 4 | recursive-include bootstrapvz *.yml 5 | recursive-include bootstrapvz/common/assets * 6 | recursive-include bootstrapvz/providers/*/assets * 7 | recursive-include bootstrapvz/plugins/*/assets * 8 | -------------------------------------------------------------------------------- /bootstrap-vz: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | if __name__ == '__main__': 4 | from bootstrapvz.base.main import main 5 | main() 6 | -------------------------------------------------------------------------------- /bootstrap-vz-remote: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | if __name__ == '__main__': 4 | from bootstrapvz.remote.main import main 5 | main() 6 | -------------------------------------------------------------------------------- /bootstrap-vz-server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | if __name__ == '__main__': 4 | from bootstrapvz.remote.server import main 5 | main() 6 | -------------------------------------------------------------------------------- /bootstrapvz/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | __version__ = '0.9.11' 4 | -------------------------------------------------------------------------------- /bootstrapvz/base/fs/exceptions.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class VolumeError(Exception): 4 | """Raised when an error occurs while interacting with the volume 5 | """ 6 | pass 7 | 8 | 9 | class PartitionError(Exception): 10 | """Raised when an error occurs while interacting with the partitions on the volume 11 | """ 12 | pass 13 | -------------------------------------------------------------------------------- /bootstrapvz/base/fs/partitionmaps/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/base/fs/partitionmaps/__init__.py -------------------------------------------------------------------------------- /bootstrapvz/base/fs/partitions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/base/fs/partitions/__init__.py -------------------------------------------------------------------------------- /bootstrapvz/base/fs/partitions/gpt.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common.tools import log_check_call 2 | from .base import BasePartition 3 | 4 | 5 | class GPTPartition(BasePartition): 6 | """Represents a GPT partition 7 | """ 8 | 9 | def __init__(self, size, filesystem, format_command, mountopts, name, previous): 10 | """ 11 | :param Bytes size: Size of the partition 12 | :param str filesystem: Filesystem the partition should be formatted with 13 | :param list format_command: Optional format command, valid variables are fs, device_path and size 14 | :param str name: The name of the partition 15 | :param BasePartition previous: The partition that preceeds this one 16 | """ 17 | self.name = name 18 | super(GPTPartition, self).__init__(size, filesystem, format_command, mountopts, previous) 19 | 20 | def _before_create(self, e): 21 | # Create the partition and then set the name of the partition afterwards 22 | super(GPTPartition, self)._before_create(e) 23 | # partition name only works for gpt, for msdos that becomes the part-type (primary, extended, logical) 24 | name_command = 'name {idx} {name}'.format(idx=self.get_index(), name=self.name) 25 | log_check_call(['parted', '--script', e.volume.device_path, 26 | '--', name_command]) 27 | -------------------------------------------------------------------------------- /bootstrapvz/base/fs/partitions/gpt_swap.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common.tools import log_check_call 2 | from .gpt import GPTPartition 3 | 4 | 5 | class GPTSwapPartition(GPTPartition): 6 | """Represents a GPT swap partition 7 | """ 8 | 9 | def __init__(self, size, previous): 10 | """ 11 | :param Bytes size: Size of the partition 12 | :param BasePartition previous: The partition that preceeds this one 13 | """ 14 | super(GPTSwapPartition, self).__init__(size, 'swap', None, None, 'swap', previous) 15 | 16 | def _before_format(self, e): 17 | log_check_call(['mkswap', self.device_path]) 18 | -------------------------------------------------------------------------------- /bootstrapvz/base/fs/partitions/msdos.py: -------------------------------------------------------------------------------- 1 | from .base import BasePartition 2 | 3 | 4 | class MSDOSPartition(BasePartition): 5 | """Represents an MS-DOS partition 6 | """ 7 | def __init__(self, size, filesystem, format_command, mountopts, name, previous): 8 | """ 9 | :param Bytes size: Size of the partition 10 | :param str filesystem: Filesystem the partition should be formatted with 11 | :param list format_command: Optional format command, valid variables are fs, device_path and size 12 | :param str name: The name of the partition 13 | :param BasePartition previous: The partition that preceeds this one 14 | """ 15 | self.name = name 16 | super(MSDOSPartition, self).__init__(size, filesystem, format_command, mountopts, previous) 17 | -------------------------------------------------------------------------------- /bootstrapvz/base/fs/partitions/msdos_swap.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common.tools import log_check_call 2 | from .msdos import MSDOSPartition 3 | 4 | 5 | class MSDOSSwapPartition(MSDOSPartition): 6 | """Represents a MS-DOS swap partition 7 | """ 8 | 9 | def __init__(self, size, previous): 10 | """ 11 | :param Bytes size: Size of the partition 12 | :param BasePartition previous: The partition that preceeds this one 13 | """ 14 | super(MSDOSSwapPartition, self).__init__(size, 'swap', None, None, 'swap', previous) 15 | 16 | def _before_format(self, e): 17 | log_check_call(['mkswap', self.device_path]) 18 | -------------------------------------------------------------------------------- /bootstrapvz/base/fs/partitions/single.py: -------------------------------------------------------------------------------- 1 | from .abstract import AbstractPartition 2 | 3 | 4 | class SinglePartition(AbstractPartition): 5 | """Represents a single virtual partition on an unpartitioned volume 6 | """ 7 | 8 | def get_start(self): 9 | """Gets the starting byte of this partition 10 | 11 | :return: The starting byte of this partition 12 | :rtype: Sectors 13 | """ 14 | from bootstrapvz.common.sectors import Sectors 15 | return Sectors(0, self.size.sector_size) 16 | -------------------------------------------------------------------------------- /bootstrapvz/base/fs/partitions/unformatted.py: -------------------------------------------------------------------------------- 1 | from .base import BasePartition 2 | 3 | 4 | class UnformattedPartition(BasePartition): 5 | """Represents an unformatted partition 6 | It cannot be mounted 7 | """ 8 | 9 | # The states for our state machine. It can only be mapped, not mounted. 10 | events = [{'name': 'create', 'src': 'nonexistent', 'dst': 'unmapped'}, 11 | {'name': 'map', 'src': 'unmapped', 'dst': 'mapped'}, 12 | {'name': 'unmap', 'src': 'mapped', 'dst': 'unmapped'}, 13 | ] 14 | 15 | def __init__(self, size, previous): 16 | """ 17 | :param Bytes size: Size of the partition 18 | :param BasePartition previous: The partition that preceeds this one 19 | """ 20 | super(UnformattedPartition, self).__init__(size, None, None, None, previous) 21 | -------------------------------------------------------------------------------- /bootstrapvz/base/phase.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Phase(object): 4 | """The Phase class represents a phase a task may be in. 5 | It has no function other than to act as an anchor in the task graph. 6 | All phases are instantiated in common.phases 7 | """ 8 | 9 | def __init__(self, name, description): 10 | # The name of the phase 11 | self.name = name 12 | # The description of the phase (currently not used anywhere) 13 | self.description = description 14 | 15 | def pos(self): 16 | """Gets the position of the phase 17 | 18 | :return: The positional index of the phase in relation to the other phases 19 | :rtype: int 20 | """ 21 | from bootstrapvz.common.phases import order 22 | return next(i for i, phase in enumerate(order) if phase is self) 23 | 24 | def __cmp__(self, other): 25 | """Compares the phase order in relation to the other phases 26 | :return int: 27 | """ 28 | return self.pos() - other.pos() 29 | 30 | def __str__(self): 31 | """ 32 | :return: String representation of the phase 33 | :rtype: str 34 | """ 35 | return self.name 36 | -------------------------------------------------------------------------------- /bootstrapvz/base/pkg/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/base/pkg/__init__.py -------------------------------------------------------------------------------- /bootstrapvz/base/pkg/exceptions.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class PackageError(Exception): 4 | """Raised when an error occurrs while handling the packageslist 5 | """ 6 | pass 7 | 8 | 9 | class SourceError(Exception): 10 | """Raised when an error occurs while handling the sourceslist 11 | """ 12 | pass 13 | -------------------------------------------------------------------------------- /bootstrapvz/base/task.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Task(object): 4 | """The task class represents a task that can be run. 5 | It is merely a wrapper for the run function and should never be instantiated. 6 | """ 7 | # The phase this task is located in. 8 | phase = None 9 | # List of tasks that should run before this task is run 10 | predecessors = [] 11 | # List of tasks that should run after this task has run 12 | successors = [] 13 | 14 | class __metaclass__(type): 15 | """Metaclass to control how the class is coerced into a string 16 | """ 17 | def __repr__(cls): 18 | """ 19 | :return str: The full module path to the Task 20 | """ 21 | return cls.__module__ + '.' + cls.__name__ 22 | 23 | def __str__(cls): 24 | """ 25 | :return: The full module path to the Task 26 | :rtype: str 27 | """ 28 | return repr(cls) 29 | 30 | @classmethod 31 | def run(cls, info): 32 | """The run function, all work is done inside this function 33 | 34 | :param BootstrapInformation info: The bootstrap info object. 35 | """ 36 | pass 37 | -------------------------------------------------------------------------------- /bootstrapvz/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/common/__init__.py -------------------------------------------------------------------------------- /bootstrapvz/common/assets/extlinux/boot.txt: -------------------------------------------------------------------------------- 1 | Wait 5 seconds or press ENTER to 2 | -------------------------------------------------------------------------------- /bootstrapvz/common/assets/extlinux/extlinux.conf: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | default l0 6 | prompt 1 7 | timeout 50 8 | 9 | 10 | label l0 11 | menu label Debian GNU/Linux, kernel {kernel_version} 12 | linux {boot_prefix}/vmlinuz-{kernel_version} 13 | append initrd={boot_prefix}/initrd.img-{kernel_version} root=UUID={root_uuid} ro quiet console=ttyS0 14 | 15 | label l0r 16 | menu label Debian GNU/Linux, kernel {kernel_version} (recovery mode) 17 | linux {boot_prefix}/vmlinuz-{kernel_version} 18 | append initrd={boot_prefix}/initrd.img-{kernel_version} root=UUID={root_uuid} ro console=ttyS0 single 19 | text help 20 | This option boots the system into recovery mode (single-user) 21 | endtext 22 | -------------------------------------------------------------------------------- /bootstrapvz/common/assets/init.d/ssh-generate-hostkeys: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: ssh-generate-hostkeys 4 | # Required-Start: $local_fs $syslog 5 | # Required-Stop: 6 | # X-Start-Before: ssh 7 | # Default-Start: 2 3 4 5 8 | # Default-Stop: 9 | # Short-Description: Generate ssh host keys if they do not exist 10 | # Description: Generate ssh host keys if they do not exist. 11 | # This file was created by bootstrap-vz. 12 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 13 | # legal notices and disclaimers. 14 | ### END INIT INFO 15 | 16 | set -e 17 | 18 | DAEMON=/usr/local/sbin/ssh-generate-hostkeys 19 | 20 | [ -x "$DAEMON" ] || exit 0 21 | 22 | . /lib/lsb/init-functions 23 | 24 | case "$1" in 25 | start) 26 | $DAEMON 27 | exit $? 28 | ;; 29 | stop|restart|reload|force-reload|status) 30 | ;; 31 | *) 32 | echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2 33 | exit 1 34 | esac 35 | 36 | exit 0 37 | -------------------------------------------------------------------------------- /bootstrapvz/common/assets/ssh-generate-hostkeys: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This file was created by bootstrap-vz. 3 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 4 | # legal notices and disclaimers. 5 | 6 | # Generate ssh host keys if they do not exist. 7 | # Output the public keys to the console. This allows user to get host 8 | # keys securely through console log. 9 | 10 | set -eu 11 | 12 | prog="$(basename $0)" 13 | logger="logger -t ${prog}" 14 | 15 | echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" | ${logger} 16 | for key in ecdsa ed25519 rsa; do 17 | keyfile="/etc/ssh/ssh_host_${key}_key" 18 | if [ ! -f "${keyfile}" ]; then 19 | /usr/bin/ssh-keygen -f "${keyfile}" -t "${key}" -C 'host' -N '' 20 | fi 21 | /usr/bin/ssh-keygen -l -f "${keyfile}.pub" | ${logger} 22 | done 23 | echo "------END SSH HOST KEY FINGERPRINTS------" | ${logger} 24 | -------------------------------------------------------------------------------- /bootstrapvz/common/assets/systemd/logind.conf: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | [Login] 6 | # Disable all TTY getters 7 | NAutoVTs=0 8 | ReserveVT=0 9 | -------------------------------------------------------------------------------- /bootstrapvz/common/assets/systemd/ssh-generate-hostkeys.service: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | [Unit] 6 | Description=OpenBSD Secure Shell server Host Key Generation 7 | ConditionFileNotEmpty=|!/etc/ssh/ssh_host_ecdsa_key 8 | ConditionFileNotEmpty=|!/etc/ssh/ssh_host_ed25519_key 9 | ConditionFileNotEmpty=|!/etc/ssh/ssh_host_rsa_key 10 | Before=ssh.service 11 | 12 | [Service] 13 | ExecStart=/usr/local/sbin/ssh-generate-hostkeys 14 | Type=oneshot 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /bootstrapvz/common/exceptions.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class ManifestError(Exception): 4 | def __init__(self, message, manifest_path=None, data_path=None): 5 | super(ManifestError, self).__init__(message) 6 | self.message = message 7 | self.manifest_path = manifest_path 8 | self.data_path = data_path 9 | self.args = (self.message, self.manifest_path, self.data_path) 10 | 11 | def __str__(self): 12 | if self.data_path is not None: 13 | path = '.'.join(map(str, self.data_path)) 14 | return ('{msg}\n File path: {file}\n Data path: {datapath}' 15 | .format(msg=self.message, file=self.manifest_path, datapath=path)) 16 | return '{file}: {msg}'.format(msg=self.message, file=self.manifest_path) 17 | 18 | 19 | class TaskListError(Exception): 20 | def __init__(self, message): 21 | super(TaskListError, self).__init__(message) 22 | self.message = message 23 | self.args = (self.message,) 24 | 25 | def __str__(self): 26 | return 'Error in tasklist: ' + self.message 27 | 28 | 29 | class TaskError(Exception): 30 | pass 31 | 32 | 33 | class UnexpectedNumMatchesError(Exception): 34 | pass 35 | 36 | 37 | class UnitError(Exception): 38 | pass 39 | -------------------------------------------------------------------------------- /bootstrapvz/common/fs/__init__.py: -------------------------------------------------------------------------------- 1 | from contextlib import contextmanager 2 | 3 | 4 | def get_partitions(): 5 | import re 6 | regexp = re.compile(r'^ *(?P\d+) *(?P\d+) *(?P\d+) (?P\S+)$') 7 | matches = {} 8 | path = '/proc/partitions' 9 | with open(path) as partitions: 10 | next(partitions) 11 | next(partitions) 12 | for line in partitions: 13 | match = regexp.match(line) 14 | if match is None: 15 | raise RuntimeError('Unable to parse {line} in {path}'.format(line=line, path=path)) 16 | matches[match.group('dev_name')] = match.groupdict() 17 | return matches 18 | 19 | 20 | @contextmanager 21 | def unmounted(volume): 22 | from bootstrapvz.base.fs.partitionmaps.none import NoPartitions 23 | 24 | p_map = volume.partition_map 25 | root_dir = p_map.root.mount_dir 26 | p_map.root.unmount() 27 | if not isinstance(p_map, NoPartitions): 28 | p_map.unmap(volume) 29 | yield 30 | p_map.map(volume) 31 | else: 32 | yield 33 | p_map.root.mount(destination=root_dir) 34 | -------------------------------------------------------------------------------- /bootstrapvz/common/fs/folder.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base.fs.volume import Volume 2 | 3 | 4 | class Folder(Volume): 5 | 6 | # Override the states this volume can be in (i.e. we can't "format" or "attach" it) 7 | events = [{'name': 'create', 'src': 'nonexistent', 'dst': 'attached'}, 8 | {'name': 'delete', 'src': 'attached', 'dst': 'deleted'}, 9 | ] 10 | 11 | extension = 'chroot' 12 | 13 | def create(self, path): 14 | self.fsm.create(path=path) 15 | 16 | def _before_create(self, e): 17 | import os 18 | self.path = e.path 19 | os.mkdir(self.path) 20 | 21 | def _before_delete(self, e): 22 | from shutil import rmtree 23 | rmtree(self.path) 24 | del self.path 25 | -------------------------------------------------------------------------------- /bootstrapvz/common/fs/loopbackvolume.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base.fs.volume import Volume 2 | from ..tools import log_check_call 3 | 4 | 5 | class LoopbackVolume(Volume): 6 | 7 | extension = 'raw' 8 | 9 | def create(self, image_path): 10 | self.fsm.create(image_path=image_path) 11 | 12 | def _before_create(self, e): 13 | self.image_path = e.image_path 14 | size_opt = '--size={mib}M'.format(mib=self.size.bytes.get_qty_in('MiB')) 15 | log_check_call(['truncate', size_opt, self.image_path]) 16 | 17 | def _before_attach(self, e): 18 | [self.loop_device_path] = log_check_call(['losetup', '--show', '--find', '--partscan', self.image_path]) 19 | self.device_path = self.loop_device_path 20 | 21 | def _before_detach(self, e): 22 | log_check_call(['losetup', '--detach', self.loop_device_path]) 23 | del self.loop_device_path 24 | self.device_path = None 25 | 26 | def _before_delete(self, e): 27 | from os import remove 28 | remove(self.image_path) 29 | del self.image_path 30 | -------------------------------------------------------------------------------- /bootstrapvz/common/fs/qcow2volume.py: -------------------------------------------------------------------------------- 1 | from .qemuvolume import QEMUVolume 2 | 3 | 4 | class Qcow2Volume(QEMUVolume): 5 | 6 | extension = 'qcow2' 7 | qemu_format = 'qcow2' 8 | -------------------------------------------------------------------------------- /bootstrapvz/common/fs/virtualdiskimage.py: -------------------------------------------------------------------------------- 1 | from .qemuvolume import QEMUVolume 2 | 3 | 4 | class VirtualDiskImage(QEMUVolume): 5 | 6 | extension = 'vdi' 7 | qemu_format = 'vdi' 8 | # VDI format does not have an URI (check here: https://forums.virtualbox.org/viewtopic.php?p=275185#p275185) 9 | ovf_uri = None 10 | 11 | def get_uuid(self): 12 | import uuid 13 | with open(self.image_path) as image: 14 | image.seek(392) 15 | return uuid.UUID(bytes_le=image.read(16)) 16 | -------------------------------------------------------------------------------- /bootstrapvz/common/fs/virtualharddisk.py: -------------------------------------------------------------------------------- 1 | from .qemuvolume import QEMUVolume 2 | from ..tools import log_check_call 3 | 4 | 5 | class VirtualHardDisk(QEMUVolume): 6 | 7 | extension = 'vhd' 8 | qemu_format = 'vpc' 9 | ovf_uri = 'http://go.microsoft.com/fwlink/?LinkId=137171' 10 | 11 | # Azure requires the image size to be a multiple of 1 MiB. 12 | # VHDs are dynamic by default, so we add the option 13 | # to make the image size fixed (subformat=fixed) 14 | def _before_create(self, e): 15 | self.image_path = e.image_path 16 | vol_size = str(self.size.bytes.get_qty_in('MiB')) + 'M' 17 | log_check_call(['qemu-img', 'create', '-o', 'subformat=fixed', '-f', self.qemu_format, self.image_path, vol_size]) 18 | 19 | def get_uuid(self): 20 | if not hasattr(self, 'uuid'): 21 | import uuid 22 | self.uuid = uuid.uuid4() 23 | return self.uuid 24 | -------------------------------------------------------------------------------- /bootstrapvz/common/fs/virtualmachinedisk.py: -------------------------------------------------------------------------------- 1 | from .qemuvolume import QEMUVolume 2 | 3 | 4 | class VirtualMachineDisk(QEMUVolume): 5 | 6 | extension = 'vmdk' 7 | qemu_format = 'vmdk' 8 | ovf_uri = 'http://www.vmware.com/specifications/vmdk.html#sparse' 9 | 10 | def get_uuid(self): 11 | if not hasattr(self, 'uuid'): 12 | import uuid 13 | self.uuid = uuid.uuid4() 14 | return self.uuid 15 | # import uuid 16 | # with open(self.image_path) as image: 17 | # line = '' 18 | # lines_read = 0 19 | # while 'ddb.uuid.image="' not in line: 20 | # line = image.read() 21 | # lines_read += 1 22 | # if lines_read > 100: 23 | # from common.exceptions import VolumeError 24 | # raise VolumeError('Unable to find UUID in VMDK file.') 25 | # import re 26 | # matches = re.search('ddb.uuid.image="(?P[^"]+)"', line) 27 | # return uuid.UUID(hex=matches.group('uuid')) 28 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/__init__.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common.tools import rel_path 2 | 3 | assets = rel_path(__file__, '../assets') 4 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/development.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from .. import phases 3 | 4 | 5 | class TriggerRollback(Task): 6 | phase = phases.cleaning 7 | 8 | description = 'Triggering a rollback by throwing an exception' 9 | 10 | @classmethod 11 | def run(cls, info): 12 | from ..exceptions import TaskError 13 | raise TaskError('Trigger rollback') 14 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/dpkg.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common.tasks import bootstrap 3 | from .. import phases 4 | import os.path 5 | 6 | 7 | class CreateDpkgCfg(Task): 8 | description = 'Creating /etc/dpkg/dpkg.cfg.d before bootstrapping' 9 | phase = phases.os_installation 10 | successors = [bootstrap.Bootstrap] 11 | 12 | @classmethod 13 | def run(cls, info): 14 | dpkgcfg_path = os.path.join(info.root, 'etc/dpkg/dpkg.cfg.d') 15 | if not os.path.exists(dpkgcfg_path): 16 | os.makedirs(dpkgcfg_path) 17 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/folder.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from . import volume 4 | from . import workspace 5 | 6 | 7 | class Create(Task): 8 | description = 'Creating volume folder' 9 | phase = phases.volume_creation 10 | successors = [volume.Attach] 11 | 12 | @classmethod 13 | def run(cls, info): 14 | import os.path 15 | info.root = os.path.join(info.workspace, 'root') 16 | info.volume.create(info.root) 17 | 18 | 19 | class Delete(Task): 20 | description = 'Deleting volume folder' 21 | phase = phases.cleaning 22 | successors = [workspace.DeleteWorkspace] 23 | 24 | @classmethod 25 | def run(cls, info): 26 | info.volume.delete() 27 | del info.root 28 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/image.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | 4 | 5 | class MoveImage(Task): 6 | description = 'Moving volume image' 7 | phase = phases.image_registration 8 | 9 | @classmethod 10 | def run(cls, info): 11 | image_name = info.manifest.name.format(**info.manifest_vars) 12 | filename = image_name + '.' + info.volume.extension 13 | 14 | import os.path 15 | destination = os.path.join(info.manifest.bootstrapper['workspace'], filename) 16 | import shutil 17 | shutil.move(info.volume.image_path, destination) 18 | info.volume.image_path = destination 19 | import logging 20 | log = logging.getLogger(__name__) 21 | log.info('The volume image has been moved to ' + destination) 22 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/logicalvolume.py: -------------------------------------------------------------------------------- 1 | import bootstrapvz.common.tasks.host as host 2 | import bootstrapvz.common.tasks.volume as volume 3 | from bootstrapvz.base import Task 4 | from bootstrapvz.common import phases 5 | 6 | 7 | class AddRequiredCommands(Task): 8 | description = 'Adding commands required for creating and mounting logical volumes' 9 | phase = phases.validation 10 | successors = [host.CheckExternalCommands] 11 | 12 | @classmethod 13 | def run(cls, info): 14 | from bootstrapvz.common.fs.logicalvolume import LogicalVolume 15 | if isinstance(info.volume, LogicalVolume): 16 | info.host_dependencies['lvcreate'] = 'lvm2' 17 | info.host_dependencies['losetup'] = 'mount' 18 | 19 | 20 | class Create(Task): 21 | description = 'Creating a Logical volume' 22 | phase = phases.volume_creation 23 | successors = [volume.Attach] 24 | 25 | @classmethod 26 | def run(cls, info): 27 | info.volume.create(volumegroup=info.manifest.volume['volumegroup'], 28 | logicalvolume=info.manifest.volume['logicalvolume']) 29 | 30 | 31 | class Delete(Task): 32 | description = 'Deleting a Logical volume' 33 | phase = phases.cleaning 34 | 35 | @classmethod 36 | def run(cls, info): 37 | info.volume.delete() 38 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/loopback.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from . import host 4 | from . import volume 5 | 6 | 7 | class AddRequiredCommands(Task): 8 | description = 'Adding commands required for creating loopback volumes' 9 | phase = phases.validation 10 | successors = [host.CheckExternalCommands] 11 | 12 | @classmethod 13 | def run(cls, info): 14 | from ..fs.loopbackvolume import LoopbackVolume 15 | from ..fs.qemuvolume import QEMUVolume 16 | if isinstance(info.volume, LoopbackVolume): 17 | info.host_dependencies['losetup'] = 'mount' 18 | info.host_dependencies['truncate'] = 'coreutils' 19 | if isinstance(info.volume, QEMUVolume): 20 | info.host_dependencies['qemu-img'] = 'qemu-utils' 21 | 22 | 23 | class Create(Task): 24 | description = 'Creating a loopback volume' 25 | phase = phases.volume_creation 26 | successors = [volume.Attach] 27 | 28 | @classmethod 29 | def run(cls, info): 30 | import os.path 31 | image_path = os.path.join(info.workspace, 'volume.' + info.volume.extension) 32 | info.volume.create(image_path) 33 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/network-configuration.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is a mapping of Debian release codenames to NIC configurations 3 | wheezy: | 4 | auto eth0 5 | iface eth0 inet dhcp 6 | jessie: | 7 | auto lo 8 | iface lo inet loopback 9 | auto eth0 10 | iface eth0 inet dhcp 11 | stretch: | 12 | auto eth0 13 | iface eth0 inet dhcp 14 | buster: | 15 | auto eth0 16 | iface eth0 inet dhcp 17 | sid: | 18 | auto eth0 19 | iface eth0 inet dhcp 20 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/security.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from .. import phases 3 | 4 | 5 | class EnableShadowConfig(Task): 6 | description = 'Enabling shadowconfig' 7 | phase = phases.system_modification 8 | 9 | @classmethod 10 | def run(cls, info): 11 | from ..tools import log_check_call 12 | log_check_call(['chroot', info.root, 'shadowconfig', 'on']) 13 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/volume.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from .. import phases 3 | from . import workspace 4 | 5 | 6 | class Attach(Task): 7 | description = 'Attaching the volume' 8 | phase = phases.volume_creation 9 | 10 | @classmethod 11 | def run(cls, info): 12 | info.volume.attach() 13 | 14 | 15 | class Detach(Task): 16 | description = 'Detaching the volume' 17 | phase = phases.volume_unmounting 18 | 19 | @classmethod 20 | def run(cls, info): 21 | info.volume.detach() 22 | 23 | 24 | class Delete(Task): 25 | description = 'Deleting the volume' 26 | phase = phases.cleaning 27 | successors = [workspace.DeleteWorkspace] 28 | 29 | @classmethod 30 | def run(cls, info): 31 | info.volume.delete() 32 | -------------------------------------------------------------------------------- /bootstrapvz/common/tasks/workspace.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from .. import phases 3 | 4 | 5 | class CreateWorkspace(Task): 6 | description = 'Creating workspace' 7 | phase = phases.preparation 8 | 9 | @classmethod 10 | def run(cls, info): 11 | import os 12 | os.makedirs(info.workspace) 13 | 14 | 15 | class DeleteWorkspace(Task): 16 | description = 'Deleting workspace' 17 | phase = phases.cleaning 18 | 19 | @classmethod 20 | def run(cls, info): 21 | import os 22 | os.rmdir(info.workspace) 23 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/README.rst: -------------------------------------------------------------------------------- 1 | Plugins are a key feature of bootstrap-vz. Despite their small size 2 | (most plugins do not exceed 100 source lines of code) they can modify 3 | the behavior of bootstrapped systems to a great extent. 4 | 5 | Below you will find documentation for all plugins available for 6 | bootstrap-vz. If you cannot find what you are looking for, consider 7 | `developing it yourself `__ and 8 | contribute to this list! 9 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/plugins/__init__.py -------------------------------------------------------------------------------- /bootstrapvz/plugins/admin_user/__init__.py: -------------------------------------------------------------------------------- 1 | def validate_manifest(data, validator, error): 2 | from bootstrapvz.common.tools import rel_path 3 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 4 | 5 | 6 | def resolve_tasks(taskset, manifest): 7 | import logging 8 | from . import tasks 9 | from bootstrapvz.common.tasks import ssh 10 | 11 | from bootstrapvz.common.releases import jessie 12 | if manifest.release < jessie: 13 | taskset.update([ssh.DisableRootLogin]) 14 | 15 | if 'password' in manifest.plugins['admin_user']: 16 | taskset.discard(ssh.DisableSSHPasswordAuthentication) 17 | taskset.add(tasks.AdminUserPassword) 18 | 19 | if 'pubkey' in manifest.plugins['admin_user']: 20 | taskset.add(tasks.CheckPublicKeyFile) 21 | taskset.add(tasks.AdminUserPublicKey) 22 | elif manifest.provider['name'] == 'ec2': 23 | taskset.add(tasks.AdminUserPublicKeyEC2) 24 | elif 'password' not in manifest.plugins['admin_user']: 25 | logging.getLogger(__name__).warn("No SSH key and no password set") 26 | 27 | taskset.update([tasks.AddSudoPackage, 28 | tasks.CreateAdminUser, 29 | tasks.PasswordlessSudo, 30 | ]) 31 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/admin_user/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Admin user plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | admin_user: 10 | type: object 11 | properties: 12 | username: {type: string} 13 | password: {type: string} 14 | pubkey: {$ref: '#/definitions/path'} 15 | required: [username] 16 | additionalProperties: false 17 | definitions: 18 | path: 19 | pattern: ^[^\0]+$ 20 | type: string 21 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ansible/__init__.py: -------------------------------------------------------------------------------- 1 | from . import tasks 2 | 3 | 4 | def validate_manifest(data, validator, error): 5 | from bootstrapvz.common.tools import rel_path 6 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 7 | 8 | 9 | def resolve_tasks(taskset, manifest): 10 | taskset.update([tasks.AddPackages, 11 | tasks.AddRequiredCommands, 12 | tasks.CheckPlaybookPath, 13 | tasks.RunAnsiblePlaybook, 14 | ]) 15 | 16 | if manifest.plugins['ansible'].get('extra_vars', {}).get('ansible_ssh_user', False): 17 | taskset.add(tasks.RemoveAnsibleSSHUserDir) 18 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ansible/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Ansible plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | ansible: 10 | type: object 11 | properties: 12 | extra_vars: 13 | type: object 14 | minItems: 1 15 | tags: 16 | type: array 17 | items: {type: string} 18 | minItems: 1 19 | skip_tags: 20 | type: array 21 | items: {type: string} 22 | minItems: 1 23 | opt_flags: 24 | type: array 25 | items: {type: string} 26 | minItems: 1 27 | groups: 28 | type: array 29 | host: {type: string} 30 | minItems: 1 31 | playbook: 32 | type: string 33 | pattern: ^[^\0]+$ 34 | required: [playbook] 35 | additionalProperties: false 36 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/apt_proxy/README.rst: -------------------------------------------------------------------------------- 1 | APT Proxy 2 | --------- 3 | 4 | This plugin creates a proxy configuration file for APT, so you could 5 | enjoy the benefits of using cached packages instead of downloading them 6 | from the mirror every time. You could just install ``apt-cacher-ng`` on 7 | the host machine and then add ``"address": "127.0.0.1"`` and 8 | ``"port": 3142`` to the manifest file. 9 | 10 | Settings 11 | ~~~~~~~~ 12 | 13 | - ``address``: The IP or host of the proxy server. 14 | ``required`` 15 | - ``port``: The port (integer) of the proxy server. 16 | ``required`` 17 | - ``username``: The username for authentication against the proxy server. 18 | This is ignored if ``password`` is not also set. 19 | ``optional`` 20 | - ``password``: The password for authentication against the proxy server. 21 | This is ignored if ``username`` is not also set. 22 | ``optional`` 23 | - ``persistent``: Whether the proxy configuration file should remain on 24 | the machine or not. 25 | Valid values: ``true``, ``false`` 26 | Default: ``false``. 27 | ``optional`` 28 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/apt_proxy/__init__.py: -------------------------------------------------------------------------------- 1 | def validate_manifest(data, validator, error): 2 | from bootstrapvz.common.tools import rel_path 3 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 4 | 5 | 6 | def resolve_tasks(taskset, manifest): 7 | from . import tasks 8 | taskset.add(tasks.CheckAptProxy) 9 | taskset.add(tasks.SetAptProxy) 10 | if not manifest.plugins['apt_proxy'].get('persistent', False): 11 | taskset.add(tasks.RemoveAptProxy) 12 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/apt_proxy/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: APT proxy plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | apt_proxy: 10 | type: object 11 | properties: 12 | address: {type: string} 13 | password: {type: string} 14 | port: {type: integer} 15 | persistent: {type: boolean} 16 | username: {type: string} 17 | required: [address, port] 18 | additionalProperties: false 19 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/chef/__init__.py: -------------------------------------------------------------------------------- 1 | from . import tasks 2 | 3 | 4 | def validate_manifest(data, validator, error): 5 | from bootstrapvz.common.tools import rel_path 6 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 7 | 8 | 9 | def resolve_tasks(taskset, manifest): 10 | taskset.add(tasks.AddPackages) 11 | if 'assets' in manifest.plugins['chef']: 12 | taskset.add(tasks.CheckAssetsPath) 13 | taskset.add(tasks.CopyChefAssets) 14 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/chef/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Chef plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | chef: 10 | type: object 11 | properties: 12 | assets: 13 | $ref: '#/definitions/absolute_path' 14 | required: [assets] 15 | additionalProperties: false 16 | definitions: 17 | absolute_path: 18 | pattern: ^/[^\0]+$ 19 | type: string 20 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/chef/tasks.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | import os 4 | 5 | 6 | class CheckAssetsPath(Task): 7 | description = 'Checking whether the assets path exist' 8 | phase = phases.validation 9 | 10 | @classmethod 11 | def run(cls, info): 12 | from bootstrapvz.common.exceptions import TaskError 13 | assets = info.manifest.plugins['chef']['assets'] 14 | if not os.path.exists(assets): 15 | msg = 'The assets directory {assets} does not exist.'.format(assets=assets) 16 | raise TaskError(msg) 17 | if not os.path.isdir(assets): 18 | msg = 'The assets path {assets} does not point to a directory.'.format(assets=assets) 19 | raise TaskError(msg) 20 | 21 | 22 | class AddPackages(Task): 23 | description = 'Add chef package' 24 | phase = phases.preparation 25 | 26 | @classmethod 27 | def run(cls, info): 28 | info.packages.add('chef') 29 | 30 | 31 | class CopyChefAssets(Task): 32 | description = 'Copying chef assets' 33 | phase = phases.system_modification 34 | 35 | @classmethod 36 | def run(cls, info): 37 | from bootstrapvz.common.tools import copy_tree 38 | copy_tree(info.manifest.plugins['chef']['assets'], os.path.join(info.root, 'etc/chef')) 39 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/cloud_init/README.rst: -------------------------------------------------------------------------------- 1 | cloud-init 2 | ---------- 3 | 4 | This plugin installs and configures 5 | `cloud-init `__ 6 | on the system. Depending on the release it installs it from either 7 | backports or the main repository. 8 | 9 | cloud-init is only compatible with Debian wheezy and upwards. 10 | 11 | Settings 12 | ~~~~~~~~ 13 | 14 | - ``username``: The username of the account to create. 15 | ``required`` 16 | - ``groups``: A list of strings specifying which additional groups the account 17 | should be added to. 18 | ``optional`` 19 | - ``disable_modules``: A list of strings specifying which cloud-init 20 | modules should be disabled. 21 | ``optional`` 22 | - ``metadata_sources``: A string that sets the 23 | `datasources `__ 24 | that cloud-init should try fetching metadata from (corresponds to 25 | debconf-set-selections values). The source is 26 | automatically set when using the ec2 provider. 27 | ``optional`` 28 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/cloud_init/assets/cloud-init/debian_cloud.cfg: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | apt_preserve_sources_list: true 6 | manage_etc_hosts: true 7 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/cloud_init/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: cloud-init plugin manifest 4 | type: object 5 | properties: 6 | system: 7 | type: object 8 | properties: 9 | release: 10 | type: string 11 | enum: 12 | - wheezy 13 | - oldstable 14 | - jessie 15 | - stable 16 | - stretch 17 | - buster 18 | - testing 19 | - sid 20 | - unstable 21 | plugins: 22 | type: object 23 | properties: 24 | cloud_init: 25 | type: object 26 | properties: 27 | username: {type: string} 28 | groups: 29 | type: array 30 | items: {type: string} 31 | uniqueItems: true 32 | metadata_sources: {type: string} 33 | disable_modules: 34 | type: array 35 | items: {type: string} 36 | uniqueItems: true 37 | enable_modules: 38 | type: object 39 | properties: 40 | cloud_init_modules: 41 | type: array 42 | properties: 43 | module: {type: string} 44 | position: {type: number} 45 | additionalProperties: false 46 | required: [username] 47 | additionalProperties: false 48 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/commands/README.rst: -------------------------------------------------------------------------------- 1 | Commands 2 | -------------- 3 | 4 | This plugin allows you to run arbitrary commands during the bootstrap process. 5 | The commands are run at an indeterminate point *after* packages have been 6 | installed, but *before* the volume has been unmounted. 7 | 8 | Settings 9 | ~~~~~~~~ 10 | 11 | - ``commands``: A list of lists containing strings. Each top-level item 12 | is a single command, while the strings inside each list comprise 13 | parts of a command. This allows for proper shell argument escaping. 14 | To circumvent escaping, simply put the entire command in a single 15 | string, the command will additionally be evaluated in a shell 16 | (e.g. globbing will work). 17 | In addition to the manifest variables ``{root}`` is also available. 18 | It points at the root of the image volume. 19 | ``chroot {root}`` should be used for the command to run in the images' environment. 20 | ``required`` 21 | ``manifest vars`` 22 | 23 | Example 24 | ~~~~~~~ 25 | 26 | Create an empty `index.html` in `/var/www` and delete all locales except english. 27 | 28 | .. code-block:: yaml 29 | 30 | commands: 31 | commands: 32 | - [touch, '{root}/var/www/index.html'] 33 | - ['chroot {root} rm -rf /usr/share/locale/[^en]*'] 34 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/commands/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def validate_manifest(data, validator, error): 4 | from bootstrapvz.common.tools import rel_path 5 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 6 | 7 | 8 | def resolve_tasks(taskset, manifest): 9 | from .tasks import ImageExecuteCommand 10 | taskset.add(ImageExecuteCommand) 11 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/commands/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Commands plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | commands: 10 | type: object 11 | properties: 12 | commands: 13 | items: 14 | items: 15 | type: string 16 | minItems: 1 17 | type: array 18 | minItems: 1 19 | type: array 20 | required: [commands] 21 | additionalProperties: false 22 | required: [commands] 23 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/commands/tasks.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.plugins.file_copy.tasks import MkdirCommand 4 | from bootstrapvz.plugins.file_copy.tasks import FileCopyCommand 5 | 6 | 7 | class ImageExecuteCommand(Task): 8 | description = 'Executing commands in the image' 9 | phase = phases.user_modification 10 | predecessors = [MkdirCommand, FileCopyCommand] 11 | 12 | @classmethod 13 | def run(cls, info): 14 | from bootstrapvz.common.tools import log_check_call 15 | for raw_command in info.manifest.plugins['commands']['commands']: 16 | command = map(lambda part: part.format(root=info.root, **info.manifest_vars), raw_command) 17 | shell = len(command) == 1 18 | log_check_call(command, shell=shell) 19 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/debconf/README.rst: -------------------------------------------------------------------------------- 1 | debconf 2 | ------- 3 | 4 | ``debconf(7)`` is the configuration system for Debian packages. 5 | It enables you to preconfigure packages before their installation. 6 | 7 | This plugin lets you specify debconf answers directly in the manifest. 8 | You should only specify answers for packages that will be installed; the plugin 9 | does not check that this is the case. 10 | 11 | Settings 12 | ~~~~~~~~ 13 | 14 | The ``debconf`` plugin directly takes an inline string::: 15 | 16 | plugins: 17 | debconf: >- 18 | d-i pkgsel/install-language-support boolean false 19 | popularity-contest popularity-contest/participate boolean false 20 | 21 | 22 | Consult ``debconf-set-selections(1)`` for a description of the data format. 23 | 24 | 25 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/debconf/__init__.py: -------------------------------------------------------------------------------- 1 | def validate_manifest(data, validator, error): 2 | from bootstrapvz.common.tools import log_check_call, rel_path 3 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 4 | 5 | log_check_call(['debconf-set-selections', '--checkonly'], 6 | stdin=data['plugins']['debconf']) 7 | 8 | 9 | def resolve_tasks(taskset, manifest): 10 | from . import tasks 11 | taskset.update([tasks.DebconfSetSelections]) 12 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/debconf/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | $schema: http://json-schema.org/schema# 2 | title: Manifest schema for the debconf plugin 3 | type: object 4 | properties: 5 | plugins: 6 | type: object 7 | properties: 8 | debconf: 9 | name: Debconf selections to set 10 | description: >- 11 | This value should be an inline string in the 12 | input format of debconf-set-selections(1). 13 | type: string 14 | required: [debconf] 15 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/debconf/tasks.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.common.tasks import packages 4 | from bootstrapvz.common.tools import log_check_call 5 | 6 | 7 | class DebconfSetSelections(Task): 8 | description = 'Set debconf(7) selections from the manifest' 9 | phase = phases.package_installation 10 | successors = [packages.InstallPackages] 11 | 12 | @classmethod 13 | def run(cls, info): 14 | log_check_call(['chroot', info.root, 'debconf-set-selections'], 15 | stdin=info.manifest.plugins['debconf']) 16 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/docker_daemon/README.rst: -------------------------------------------------------------------------------- 1 | Docker daemon 2 | ------------- 3 | 4 | Install `docker `__ daemon in the image. Uses 5 | init scripts for the official repository. 6 | 7 | This plugin can only be used if the distribution being bootstrapped is 8 | at least ``wheezy``, as Docker needs a kernel version ``3.8`` or higher, 9 | which is available at the ``wheezy-backports`` repository. There's also 10 | an architecture requirement, as it runs only on ``amd64``. 11 | 12 | Settings 13 | ~~~~~~~~ 14 | 15 | - ``version``: Selects the docker version to install. To select the 16 | latest version simply omit this setting. 17 | Default: ``latest`` 18 | ``optional`` 19 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/docker_daemon/__init__.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common.tools import rel_path 2 | from . import tasks 3 | from bootstrapvz.common.tasks import apt 4 | from bootstrapvz.common.releases import wheezy 5 | 6 | 7 | def validate_manifest(data, validator, error): 8 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 9 | 10 | from bootstrapvz.common.releases import get_release 11 | if get_release(data['system']['release']) == wheezy: 12 | # prefs is a generator of apt preferences across files in the manifest 13 | prefs = (item for vals in data.get('packages', {}).get('preferences', {}).values() for item in vals) 14 | if not any('linux-image' in item['package'] and 'wheezy-backports' in item['pin'] for item in prefs): 15 | msg = 'The backports kernel is required for the docker daemon to function properly' 16 | error(msg, ['packages', 'preferences']) 17 | 18 | 19 | def resolve_tasks(taskset, manifest): 20 | if manifest.release == wheezy: 21 | taskset.add(apt.AddBackports) 22 | taskset.add(tasks.AddDockerDeps) 23 | taskset.add(tasks.AddDockerBinary) 24 | taskset.add(tasks.AddDockerInit) 25 | taskset.add(tasks.EnableMemoryCgroup) 26 | if manifest.plugins['docker_daemon'].get('pull_images', []): 27 | taskset.add(tasks.PullDockerImages) 28 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/docker_daemon/assets/default/docker: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | # Docker Upstart and SysVinit configuration file 6 | 7 | # Customize location of Docker binary (especially for development testing). 8 | #DOCKER="/usr/local/bin/docker" 9 | 10 | # Use DOCKER_OPTS to modify the daemon startup options. 11 | #DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4" 12 | 13 | # Use DOCKER_NOFILE to set ulimit -n before starting Docker. 14 | #DOCKER_NOFILE=65536 15 | 16 | # Use DOCKER_LOCKEDMEMORY to set ulimit -l before starting Docker. 17 | #DOCKER_LOCKEDMEMORY=unlimited 18 | 19 | # If you need Docker to use an HTTP proxy, it can also be specified here. 20 | #export http_proxy="http://127.0.0.1:3128/" 21 | 22 | # This is also a handy place to tweak where Docker's temporary files go. 23 | #export TMPDIR="/mnt/bigdrive/docker-tmp" 24 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/docker_daemon/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Install Docker plugin manifest 4 | type: object 5 | properties: 6 | system: 7 | type: object 8 | properties: 9 | architecture: 10 | type: string 11 | enum: [amd64] 12 | release: 13 | type: string 14 | plugins: 15 | type: object 16 | properties: 17 | docker_daemon: 18 | type: object 19 | properties: 20 | version: 21 | pattern: '^\d\.\d{1,2}\.\d$' 22 | type: string 23 | docker_opts: 24 | type: string 25 | additionalProperties: false 26 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ec2_launch/README.rst: -------------------------------------------------------------------------------- 1 | ec2-launch 2 | ---------- 3 | This plugin is spinning up **AWS classic instance** from the AMI created with 4 | the template from which this plugin is invoked. 5 | 6 | Settings 7 | ~~~~~~~~ 8 | - ``security_group_ids``: A list of security groups (not VPC) to attach to the 9 | instance 10 | ``required`` 11 | - ``instance_type``: A string with AWS Classic capable instance to run 12 | (default: m3.medium) 13 | ``optional`` 14 | - ``ssh_key``: A string with the ssh key name to apply to the instance. 15 | ``required`` 16 | - ``print_public_ip``: A string with the path to write instance external IP to 17 | ``optional`` 18 | - ``tags``: 19 | ``optional`` 20 | - ``deregister_ami``: A boolean value describing if AMI should be kept after 21 | sinning up instance or not (default: false) 22 | ``optional`` 23 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ec2_launch/__init__.py: -------------------------------------------------------------------------------- 1 | def validate_manifest(data, validator, error): 2 | from bootstrapvz.common.tools import rel_path 3 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 4 | 5 | 6 | def resolve_tasks(taskset, manifest): 7 | from . import tasks 8 | taskset.add(tasks.LaunchEC2Instance) 9 | if 'print_public_ip' in manifest.plugins['ec2_launch']: 10 | taskset.add(tasks.PrintPublicIPAddress) 11 | if manifest.plugins['ec2_launch'].get('deregister_ami', False): 12 | taskset.add(tasks.DeregisterAMI) 13 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ec2_launch/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: EC2-launch plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | ec2_launch: 10 | type: object 11 | properties: 12 | security_group_ids: 13 | type: array 14 | items: {type: string} 15 | uniqueItems: true 16 | instance_type: {type: string} 17 | ssh_key: {type: string} 18 | print_public_ip: {type: string} 19 | tags: {type: object} 20 | deregister_ami: {type: boolean} 21 | additionalProperties: false 22 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ec2_publish/README.rst: -------------------------------------------------------------------------------- 1 | EC2 publish 2 | ----------- 3 | 4 | This plugin lets you publish an EC2 AMI to multiple regions, make AMIs public, 5 | and output the AMIs generated in each file. 6 | 7 | Settings 8 | ~~~~~~~~ 9 | 10 | - ``regions``: EC2 regions to copy the final image to. 11 | ``optional`` 12 | - ``public``: Whether the AMIs should be made public (i.e. available by ALL users). 13 | Valid values: ``true``, ``false`` 14 | Default: ``false``. 15 | ``optional`` 16 | - ``manifest_url``: URL to publish generated AMIs. 17 | Can be a path on the local filesystem, or a URL to S3 (https://bucket.s3-region.amazonaws.com/amis.json) 18 | ``optional`` 19 | 20 | 21 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ec2_publish/__init__.py: -------------------------------------------------------------------------------- 1 | def validate_manifest(data, validator, error): 2 | from bootstrapvz.common.tools import rel_path 3 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 4 | 5 | 6 | def resolve_tasks(taskset, manifest): 7 | from . import tasks 8 | taskset.add(tasks.CopyAmiToRegions) 9 | if 'manifest_url' in manifest.plugins['ec2_publish']: 10 | taskset.add(tasks.PublishAmiManifest) 11 | 12 | ami_public = manifest.plugins['ec2_publish'].get('public') 13 | if ami_public: 14 | taskset.add(tasks.PublishAmi) 15 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ec2_publish/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: EC2-publish plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | ec2_publish: 10 | type: object 11 | properties: 12 | regions: 13 | type: array 14 | items: {$ref: '#/definitions/aws-region'} 15 | uniqueItems: true 16 | manifest_url: {type: string} 17 | public: {type: boolean} 18 | additionalProperties: false 19 | definitions: 20 | aws-region: 21 | enum: 22 | - ap-northeast-1 23 | - ap-northeast-2 24 | - ap-southeast-1 25 | - ap-southeast-2 26 | - ca-central-1 27 | - eu-central-1 28 | - eu-west-1 29 | - sa-east-1 30 | - us-east-1 31 | - us-gov-west-1 32 | - us-west-1 33 | - us-west-2 34 | - cn-north-1 35 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/expand_root/README.rst: -------------------------------------------------------------------------------- 1 | Expand Root 2 | ----------- 3 | 4 | This plugin adds support to expand the root partition and filesystem dynamically on boot. It adds a shell script to call growpart and the proper filesystem expansion tool for a given device, partition, and filesystem. The growpart script is part of the cloud-guest-utils package in stretch and jessie-backports. The version of this script in jessie is broken in several ways and so this plugin installs the version from jessie-backports which works correctly. This plugin should not be used in conjunction with common.tasks.initd.AddExpandRoot and common.tasks.initd.AdjustExpandRootScript. It is meant to replace the existing internal common version of expand-root. 5 | 6 | Settings 7 | ~~~~~~~~ 8 | 9 | - ``filesystem_type``: The type of filesystem to grow, one of ext2, ext3, ext4, of xfs. 10 | - ``root_device``: The root device we are growing, /dev/sda as an example. 11 | - ``root_partition``: The root partition ID we are growing, 1 (which becomes /dev/sda1). This is specified so you could grow a different partition on the root_device if you have a multi partition setup and because growpart takes the partition number as a separate argument. 12 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/expand_root/__init__.py: -------------------------------------------------------------------------------- 1 | from . import tasks 2 | from bootstrapvz.common.tools import rel_path 3 | 4 | 5 | def validate_manifest(data, validator, error): 6 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 7 | 8 | 9 | def resolve_tasks(taskset, manifest): 10 | taskset.add(tasks.InstallGrowpart) 11 | taskset.add(tasks.InstallExpandRootScripts) 12 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/expand_root/assets/expand-root: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This file was created by bootstrap-vz. 3 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 4 | # legal notices and disclaimers. 5 | 6 | # Expands a partition and filesystem using growpart and an appropriate 7 | # filesystem tool for live filesystem expansion. Takes three arguments: 8 | # DEVICE, such as "/dev/sda" 9 | # PARTITION, such as "1" 10 | # FILESYSTEM, such as "ext4" 11 | 12 | DEVICE="${1}" 13 | PARTITION="${2}" 14 | FILESYSTEM="${3}" 15 | 16 | if [[ -z "${DEVICE}" || -z "${PARTITION}" || -z "${FILESYSTEM}" ]]; then 17 | echo "Requires: $0 DEVICE PARTITION FILESYSTEM" 18 | exit 1 19 | fi 20 | 21 | # Grow partition using growpart 22 | if [[ -x /usr/bin/growpart ]]; then 23 | echo "Growing partition ${DEVICE}${PARTITION}" 24 | /usr/bin/growpart "${DEVICE}" "${PARTITION}" 25 | else 26 | echo "/usr/bin/growpart was not found" 27 | exit 1 28 | fi 29 | 30 | echo "Resizing ${FILESYSTEM} filesystem on ${DEVICE}${PARTITION}" 31 | case "${FILESYSTEM}" in 32 | xfs) xfs_growfs / ;; 33 | ext2) resize2fs "${DEVICE}${PARTITION}" ;; 34 | ext3) resize2fs "${DEVICE}${PARTITION}" ;; 35 | ext4) resize2fs "${DEVICE}${PARTITION}" ;; 36 | *) echo "Unsupported filesystem, unable to expand size." ;; 37 | esac 38 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/expand_root/assets/expand-root.service: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | [Unit] 6 | Description=Expand the root partition and filesystem on boot 7 | After=local-fs.target 8 | Wants=local-fs.target 9 | 10 | [Service] 11 | ExecStart=/usr/local/sbin/expand-root DEVICE PARTITION FILESYSTEM 12 | Type=oneshot 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/expand_root/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Expand root plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | expand_root: 10 | type: object 11 | properties: 12 | filesystem_type: 13 | enum: 14 | - ext2 15 | - ext3 16 | - ext4 17 | - xfs 18 | root_device: {type: string} 19 | root_partition: {type: integer} 20 | required: 21 | - filesystem_type 22 | - root_device 23 | - root_partition 24 | additionalProperties: false 25 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/file_copy/README.rst: -------------------------------------------------------------------------------- 1 | File copy 2 | --------- 3 | 4 | This plugin lets you copy files from the host to the VM under construction, 5 | create directories, and set permissions and ownership. 6 | 7 | Note that this necessarily violates the `first development guideline`_. 8 | 9 | .. _first development guideline: https://github.com/andsens/bootstrap-vz/blob/master/CONTRIBUTING.rst#the-manifest-should-always-fully-describe-the-resulting-image 10 | 11 | 12 | Settings 13 | ~~~~~~~~ 14 | 15 | The ``file_copy`` plugin takes a (non-empty) ``files`` list, and optionally a ``mkdirs`` list. 16 | 17 | Files (items in the ``files`` list) must be objects with the following properties: 18 | 19 | - ``src`` and ``dst`` (required) are the source and destination paths. 20 | ``src`` is relative to the manifest, whereas ``dst`` is a path in the VM. 21 | - ``permissions`` (optional) is a permission string in a format appropriate for ``chmod(1)``. 22 | - ``owner`` and ``group`` (optional) are respectively a user and group specification, 23 | in a format appropriate for ``chown(1)`` and ``chgrp(1)``. 24 | 25 | Folders (items in the ``mkdirs`` list) must be objects with the following properties: 26 | - ``dir`` (required) is the path of the directory. 27 | - ``permissions``, ``owner`` and ``group`` are the same as for files. 28 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/file_copy/__init__.py: -------------------------------------------------------------------------------- 1 | from . import tasks 2 | 3 | 4 | def validate_manifest(data, validator, error): 5 | from bootstrapvz.common.tools import rel_path 6 | 7 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 8 | 9 | 10 | def resolve_tasks(taskset, manifest): 11 | if ('mkdirs' in manifest.plugins['file_copy']): 12 | taskset.add(tasks.MkdirCommand) 13 | if ('files' in manifest.plugins['file_copy']): 14 | taskset.add(tasks.ValidateFiles) 15 | taskset.add(tasks.FileCopyCommand) 16 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/google_cloud_repo/README.rst: -------------------------------------------------------------------------------- 1 | Google Cloud Repo 2 | ----------------- 3 | 4 | This plugin adds support to use Google Cloud apt repositories for Debian. It adds the public repo key and optionally will add an apt source list file and install a package containing the key in order to maintain the key over time. 5 | 6 | Settings 7 | ~~~~~~~~ 8 | 9 | - ``cleanup_bootstrap_key``: Deletes the bootstrap key by removing /etc/apt/trusted.gpg in favor of the package maintained version. This is only to avoid having multiple keys around in the apt-key list. This should only be used with enable_keyring_repo. 10 | - ``enable_keyring_repo``: Add a repository and package to maintain the repo public key over time. 11 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/google_cloud_repo/__init__.py: -------------------------------------------------------------------------------- 1 | from . import tasks 2 | from bootstrapvz.common.tools import rel_path 3 | 4 | 5 | def validate_manifest(data, validator, error): 6 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 7 | 8 | 9 | def resolve_tasks(taskset, manifest): 10 | taskset.add(tasks.AddGoogleCloudRepoKey) 11 | if manifest.plugins['google_cloud_repo'].get('enable_keyring_repo', False): 12 | taskset.add(tasks.AddGoogleCloudRepoKeyringRepo) 13 | taskset.add(tasks.InstallGoogleCloudRepoKeyringPackage) 14 | if manifest.plugins['google_cloud_repo'].get('cleanup_bootstrap_key', False): 15 | taskset.add(tasks.CleanupBootstrapRepoKey) 16 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/google_cloud_repo/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Google Cloud repository plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | google_cloud_repo: 10 | type: object 11 | properties: 12 | cleanup_bootstrap_key: {type: boolean} 13 | enable_keyring_repo: {type: boolean} 14 | additionalProperties: false 15 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/minimize_size/assets/apt-autoremove-suggests: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | # Since Docker users are looking for the smallest possible final images, the 6 | # following emerges as a very common pattern: 7 | # RUN apt-get update \ 8 | # && apt-get install -y \ 9 | # && \ 10 | # && apt-get purge -y --auto-remove 11 | # By default, APT will actually _keep_ packages installed via Recommends or 12 | # Depends if another package Suggests them, even and including if the package 13 | # that originally caused them to be installed is removed. Setting this to 14 | # "false" ensures that APT is appropriately aggressive about removing the 15 | # packages it added. 16 | # https://aptitude.alioth.debian.org/doc/en/ch02s05s05.html#configApt-AutoRemove-SuggestsImportant 17 | Apt::AutoRemove::SuggestsImportant "false"; 18 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/minimize_size/assets/apt-clean: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | # Since for most Docker users, package installs happen in "docker build" steps, 6 | # they essentially become individual layers due to the way Docker handles 7 | # layering, especially using CoW filesystems. What this means for us is that 8 | # the caches that APT keeps end up just wasting space in those layers, making 9 | # our layers unnecessarily large (especially since we'll normally never use 10 | # these caches again and will instead just "docker build" again and make a brand 11 | # new image). 12 | # Ideally, these would just be invoking "apt-get clean", but in our testing, 13 | # that ended up being cyclic and we got stuck on APT's lock, so we get this fun 14 | # creation that's essentially just "apt-get clean". 15 | DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; }; 16 | APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; }; 17 | Dir::Cache::pkgcache ""; 18 | Dir::Cache::srcpkgcache ""; 19 | # Note that we do realize this isn't the ideal way to do this, and are always 20 | # open to better suggestions (https://github.com/docker/docker/issues). 21 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/minimize_size/assets/apt-gzip-indexes: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | # Since Docker users using "RUN apt-get update && apt-get install -y ..." in 6 | # their Dockerfiles don't go delete the lists files afterwards, we want them to 7 | # be as small as possible on-disk, so we explicitly request "gz" versions and 8 | # tell Apt to keep them gzipped on-disk. 9 | # For comparison, an "apt-get update" layer without this on a pristine 10 | # "debian:wheezy" base image was "29.88 MB", where with this it was only 11 | # "8.273 MB". 12 | Acquire::GzipIndexes "true"; 13 | Acquire::CompressionTypes::Order:: "gz"; 14 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/minimize_size/assets/apt-languages: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | # In Docker, we don't often need the "Translations" files, so we're just wasting 6 | # time and space by downloading them, and this inhibits that. For users that do 7 | # need them, it's a simple matter to delete this file and "apt-get update". :) 8 | Acquire::Languages { ACQUIRE_LANGUAGES_FILTER }; 9 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/minimize_size/assets/bootstrap-files-filter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This file was created by bootstrap-vz. 3 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 4 | # legal notices and disclaimers. 5 | 6 | # First we filter out all paths not relating to the stuff we want to filter 7 | # After that we take out the paths that we *do* want to keep 8 | grep 'EXCLUDE_PATTERN' | grep --invert-match --fixed-strings 'INCLUDE_PATHS' 9 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/minimize_size/assets/bootstrap-script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This file was created by bootstrap-vz. 3 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 4 | # legal notices and disclaimers. 5 | 6 | # This script does not override anything defined in /usr/share/debootstrap/scripts 7 | # Instead we use it to redefine extract_dpkg_deb_data(), so that we may exclude 8 | # certain files during bootstrapping. 9 | 10 | extract_dpkg_deb_data () { 11 | local pkg="$1" 12 | local excludes_file="DEBOOTSTRAP_EXCLUDES_PATH" 13 | # List all files in $pkg and run them through the filter (avoid exit status >0 if no matches are found) 14 | dpkg-deb --fsys-tarfile "$pkg" | tar -t | BOOTSTRAP_FILES_FILTER_PATH > "$excludes_file" || true 15 | dpkg-deb --fsys-tarfile "$pkg" | tar --exclude-from "$excludes_file" -xf - 16 | rm "$excludes_file" 17 | } 18 | 19 | # Direct copypasta from the debootstrap script where it determines 20 | # which script to run. We do exactly the same but leave out the 21 | # if [ "$4" != "" ] part so that we can source the script that 22 | # should've been sourced in this scripts place. 23 | 24 | SCRIPT="$DEBOOTSTRAP_DIR/scripts/$SUITE" 25 | if [ -n "$VARIANT" ] && [ -e "${SCRIPT}.${VARIANT}" ]; then 26 | SCRIPT="${SCRIPT}.${VARIANT}" 27 | fi 28 | 29 | . $SCRIPT 30 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/minimize_size/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | properties: 4 | plugins: 5 | properties: 6 | minimize_size: 7 | properties: 8 | shrink: 9 | anyOf: 10 | - type: boolean 11 | - enum: [vmware-vdiskmanager, qemu-img, qemu-img-no-compression] 12 | zerofree: 13 | type: boolean 14 | apt: 15 | type: object 16 | properties: 17 | autoclean: 18 | type: boolean 19 | languages: 20 | type: array 21 | minItems: 1 22 | items: 23 | type: string 24 | gzip_indexes: 25 | type: boolean 26 | autoremove_suggests: 27 | type: boolean 28 | dpkg: 29 | type: object 30 | properties: 31 | locales: 32 | type: array 33 | items: 34 | type: string 35 | exclude_docs: 36 | type: boolean 37 | type: object 38 | additionalProperties: false 39 | type: object 40 | title: Minimize size plugin manifest 41 | type: object 42 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/minimize_size/tasks/__init__.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common.tools import rel_path 2 | 3 | assets = rel_path(__file__, '../assets') 4 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ntp/README.rst: -------------------------------------------------------------------------------- 1 | NTP 2 | --- 3 | 4 | This plugins installs the Network Time Protocol daemon and optionally 5 | defines which time servers it should use. 6 | 7 | Settings 8 | ~~~~~~~~ 9 | 10 | - ``servers``: A list of strings specifying which servers should be 11 | used to synchronize the machine clock. 12 | ``optional`` 13 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ntp/__init__.py: -------------------------------------------------------------------------------- 1 | def validate_manifest(data, validator, error): 2 | from bootstrapvz.common.tools import rel_path 3 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 4 | 5 | 6 | def resolve_tasks(taskset, manifest): 7 | from . import tasks 8 | taskset.add(tasks.AddNtpPackage) 9 | if manifest.plugins['ntp'].get('servers', False): 10 | taskset.add(tasks.SetNtpServers) 11 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ntp/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: NTP plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | ntp: 10 | type: object 11 | properties: 12 | servers: 13 | type: array 14 | items: {type: string} 15 | minItems: 1 16 | additionalProperties: false 17 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/ntp/tasks.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from bootstrapvz.base import Task 4 | from bootstrapvz.common import phases 5 | 6 | 7 | class AddNtpPackage(Task): 8 | description = 'Adding NTP Package' 9 | phase = phases.preparation 10 | 11 | @classmethod 12 | def run(cls, info): 13 | info.packages.add('ntp') 14 | 15 | 16 | class SetNtpServers(Task): 17 | description = 'Setting NTP servers' 18 | phase = phases.system_modification 19 | 20 | @classmethod 21 | def run(cls, info): 22 | import fileinput 23 | import os 24 | import re 25 | ntp_path = os.path.join(info.root, 'etc/ntp.conf') 26 | servers = list(info.manifest.plugins['ntp']['servers']) 27 | debian_ntp_server = re.compile(r'.*[0-9]\.debian\.pool\.ntp\.org.*') 28 | for line in fileinput.input(files=ntp_path, inplace=True): 29 | # Will write all the specified servers on the first match, then supress all other default servers 30 | if re.match(debian_ntp_server, line): 31 | while servers: 32 | print('server {server_address} iburst'.format(server_address=servers.pop(0))) 33 | else: 34 | print(line, end='') 35 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/opennebula/README.rst: -------------------------------------------------------------------------------- 1 | Open Nebula 2 | ----------- 3 | 4 | This plugin adds `OpenNebula 5 | contextualization `__ 6 | to the image, which sets up the network configuration and SSH keys. 7 | 8 | The virtual machine context should be configured as follows: 9 | 10 | .. code-block:: text 11 | 12 | ETH0_DNS $NETWORK[DNS, NETWORK_ID=2] 13 | ETH0_GATEWAY $NETWORK[GATEWAY, NETWORK_ID=2] 14 | ETH0_IP $NIC[IP, NETWORK_ID=2] 15 | ETH0_MASK $NETWORK[MASK, NETWORK_ID=2] 16 | ETH0_NETWORK $NETWORK[NETWORK, NETWORK_ID=2] 17 | FILES path_to_my_ssh_public_key.pub 18 | 19 | The plugin will install all *.pub* files in the root authorized\_keys 20 | file. When using the ec2 provider, the USER\_EC2\_DATA will be executed 21 | if present. 22 | 23 | Settings 24 | ~~~~~~~~ 25 | 26 | This plugin has no settings. To enable it add ``"opennebula":{}`` to the 27 | plugin section of the manifest. 28 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/opennebula/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def resolve_tasks(taskset, manifest): 4 | from . import tasks 5 | from bootstrapvz.common.tasks import apt 6 | from bootstrapvz.common.releases import wheezy 7 | if manifest.release == wheezy: 8 | taskset.add(apt.AddBackports) 9 | taskset.update([tasks.AddONEContextPackage]) 10 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/opennebula/tasks.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common.tasks import apt 3 | from bootstrapvz.common import phases 4 | 5 | 6 | class AddONEContextPackage(Task): 7 | description = 'Adding the OpenNebula context package' 8 | phase = phases.preparation 9 | predecessors = [apt.AddBackports] 10 | 11 | @classmethod 12 | def run(cls, info): 13 | target = None 14 | from bootstrapvz.common.releases import wheezy 15 | if info.manifest.release == wheezy: 16 | target = '{system.release}-backports' 17 | info.packages.add('opennebula-context', target) 18 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/pip3_install/README.rst: -------------------------------------------------------------------------------- 1 | Pip3 install 2 | ------------ 3 | 4 | Install packages from the Python Package Index via pip for python3 5 | 6 | Installs ``build-essential`` and ``python3-dev`` debian packages, so 7 | Python extension modules can be built. 8 | 9 | Settings 10 | ~~~~~~~~ 11 | 12 | - ``packages``: Python packages to install, a list of strings. The list 13 | can contain anything that ``pip install`` would accept as an 14 | argument, for example ``awscli==1.3.13``. 15 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/pip3_install/__init__.py: -------------------------------------------------------------------------------- 1 | from . import tasks 2 | 3 | 4 | def validate_manifest(data, validator, error): 5 | from bootstrapvz.common.tools import rel_path 6 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 7 | 8 | 9 | def resolve_tasks(taskset, manifest): 10 | taskset.add(tasks.AddPip3Package) 11 | taskset.add(tasks.Pip3InstallCommand) 12 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/pip3_install/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Pip3 install plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | pip_install: 10 | type: object 11 | properties: 12 | packages: 13 | type: array 14 | items: 15 | type: string 16 | minItems: 1 17 | uniqueItems: true 18 | additionalProperties: false 19 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/pip3_install/tasks.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | 4 | 5 | class AddPip3Package(Task): 6 | description = 'Adding `pip\' and Co. to the image packages' 7 | phase = phases.preparation 8 | 9 | @classmethod 10 | def run(cls, info): 11 | for package_name in ('build-essential', 'python3-dev', 'python3-pip'): 12 | info.packages.add(package_name) 13 | 14 | 15 | class Pip3InstallCommand(Task): 16 | description = 'Install python packages from pypi with pip' 17 | phase = phases.system_modification 18 | 19 | @classmethod 20 | def run(cls, info): 21 | from bootstrapvz.common.tools import log_check_call 22 | packages = info.manifest.plugins['pip3_install']['packages'] 23 | pip_install_command = ['chroot', info.root, 'pip3', 'install'] 24 | pip_install_command.extend(packages) 25 | log_check_call(pip_install_command) 26 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/pip_install/README.rst: -------------------------------------------------------------------------------- 1 | Pip install 2 | ----------- 3 | 4 | Install packages from the Python Package Index via pip. 5 | 6 | Installs ``build-essential`` and ``python-dev`` debian packages, so 7 | Python extension modules can be built. 8 | 9 | Settings 10 | ~~~~~~~~ 11 | 12 | - ``packages``: Python packages to install, a list of strings. The list 13 | can contain anything that ``pip install`` would accept as an 14 | argument, for example ``awscli==1.3.13``. 15 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/pip_install/__init__.py: -------------------------------------------------------------------------------- 1 | from . import tasks 2 | 3 | 4 | def validate_manifest(data, validator, error): 5 | from bootstrapvz.common.tools import rel_path 6 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 7 | 8 | 9 | def resolve_tasks(taskset, manifest): 10 | taskset.add(tasks.AddPipPackage) 11 | taskset.add(tasks.PipInstallCommand) 12 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/pip_install/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Pip install plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | pip_install: 10 | type: object 11 | properties: 12 | packages: 13 | type: array 14 | items: 15 | type: string 16 | minItems: 1 17 | uniqueItems: true 18 | additionalProperties: false 19 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/pip_install/tasks.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | 4 | 5 | class AddPipPackage(Task): 6 | description = 'Adding `pip\' and Co. to the image packages' 7 | phase = phases.preparation 8 | 9 | @classmethod 10 | def run(cls, info): 11 | for package_name in ('python-pip', 'build-essential', 'python-dev'): 12 | info.packages.add(package_name) 13 | 14 | 15 | class PipInstallCommand(Task): 16 | description = 'Install python packages from pypi with pip' 17 | phase = phases.system_modification 18 | 19 | @classmethod 20 | def run(cls, info): 21 | from bootstrapvz.common.tools import log_check_call 22 | packages = info.manifest.plugins['pip_install']['packages'] 23 | pip_install_command = ['chroot', info.root, 'pip', 'install'] 24 | pip_install_command.extend(packages) 25 | log_check_call(pip_install_command) 26 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/prebootstrapped/README.rst: -------------------------------------------------------------------------------- 1 | prebootstrapped 2 | --------------- 3 | 4 | When developing for bootstrap-vz, testing can be quite tedious since the 5 | bootstrapping process can take a while. The prebootstrapped plugin 6 | solves that problem by creating a snapshot of your volume right after 7 | all the software has been installed. The next time bootstrap-vz is run, 8 | the plugin replaces all volume preparation and bootstrapping tasks and 9 | recreates the volume from the snapshot instead. 10 | 11 | The plugin assumes that the users knows what he is doing (e.g. it 12 | doesn't check whether bootstrap-vz is being run with a partitioned 13 | volume configuration, while the snapshot is unpartitioned). 14 | 15 | When no snapshot or image is specified the plugin creates one and 16 | outputs its ID/path. Specifying an ID/path enables the second mode of 17 | operation which recreates the volume from the specified snapshot instead 18 | of creating it from scratch. 19 | 20 | Settings 21 | ~~~~~~~~ 22 | 23 | - ``snapshot``: ID of the EBS snapshot to use. This setting only works 24 | with the volume backing ``ebs``. 25 | - ``image``: Path to the loopbackvolume snapshot. This setting works 26 | with the volume backings ``raw``, ``s3``, ``vdi``, ``vmdk`` 27 | - ``folder``: Path to the folder copy. This setting works 28 | with the volume backing ``folder`` 29 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/prebootstrapped/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Prebootstrapped plugin manifest 4 | type: object 5 | properties: 6 | volume: 7 | type: object 8 | properties: 9 | backing: 10 | type: string 11 | enum: 12 | - raw 13 | - ebs 14 | - s3 15 | - vdi 16 | - vmdk 17 | - folder 18 | required: [backing] 19 | plugins: 20 | type: object 21 | properties: 22 | prebootstrapped: 23 | type: object 24 | properties: 25 | image: {type: string} 26 | snapshot: {type: string} 27 | folder: {type: string} 28 | additionalProperties: false 29 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/puppet/__init__.py: -------------------------------------------------------------------------------- 1 | from . import tasks 2 | 3 | 4 | def validate_manifest(data, validator, error): 5 | from bootstrapvz.common.tools import rel_path 6 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 7 | 8 | 9 | def resolve_tasks(taskset, manifest): 10 | taskset.add(tasks.CheckRequestedDebianRelease) 11 | taskset.add(tasks.AddPuppetlabsPC1SourcesList) 12 | taskset.add(tasks.InstallPuppetlabsPC1ReleaseKey) 13 | taskset.add(tasks.InstallPuppetAgent) 14 | if 'assets' in manifest.plugins['puppet']: 15 | taskset.add(tasks.CheckAssetsPath) 16 | taskset.add(tasks.CopyPuppetAssets) 17 | if 'manifest' in manifest.plugins['puppet']: 18 | taskset.add(tasks.CheckManifestPath) 19 | taskset.add(tasks.ApplyPuppetManifest) 20 | if 'install_modules' in manifest.plugins['puppet']: 21 | taskset.add(tasks.InstallModules) 22 | if manifest.plugins['puppet'].get('enable_agent', False): 23 | taskset.add(tasks.EnableAgent) 24 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/puppet/assets/gpg-keyrings-PC1/jessie/puppetlabs-pc1-keyring.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/plugins/puppet/assets/gpg-keyrings-PC1/jessie/puppetlabs-pc1-keyring.gpg -------------------------------------------------------------------------------- /bootstrapvz/plugins/puppet/assets/gpg-keyrings-PC1/stretch/puppetlabs-pc1-keyring.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/plugins/puppet/assets/gpg-keyrings-PC1/stretch/puppetlabs-pc1-keyring.gpg -------------------------------------------------------------------------------- /bootstrapvz/plugins/puppet/assets/gpg-keyrings-PC1/wheezy/puppetlabs-pc1-keyring.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/plugins/puppet/assets/gpg-keyrings-PC1/wheezy/puppetlabs-pc1-keyring.gpg -------------------------------------------------------------------------------- /bootstrapvz/plugins/puppet/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Puppet plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | puppet: 10 | type: object 11 | properties: 12 | assets: {$ref: '#/definitions/absolute_path'} 13 | enable_agent: {type: boolean} 14 | manifest: {$ref: '#/definitions/absolute_path'} 15 | install_modules: 16 | type: array 17 | minItems: 1 18 | items: 19 | type: array 20 | items: 21 | name: 22 | anyOf: 23 | - pattern: ^[^/]+(/[^/]+)?$ 24 | version: 25 | type: number 26 | required: [name] 27 | minItems: 1 28 | minProperties: 1 29 | additionalProperties: false 30 | definitions: 31 | absolute_path: 32 | pattern: ^/[^\0]+$ 33 | type: string 34 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/root_password/README.rst: -------------------------------------------------------------------------------- 1 | root password 2 | ------------- 3 | 4 | Sets the root password. This plugin removes the task that disables the 5 | SSH password authentication. 6 | 7 | Settings 8 | ~~~~~~~~ 9 | ``oneOf`` 10 | 11 | - ``password``: The password for the root user. 12 | - ``password-crypted``: The password for the root user[crypt(3) hash] 13 | 14 | The following command (available from the **whois** package) can be used 15 | to generate a SHA-512 based crypt(3) hash for a password: 16 | 17 | .. code-block:: shell 18 | 19 | mkpasswd -m sha-512 20 | 21 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/root_password/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def validate_manifest(data, validator, error): 4 | from bootstrapvz.common.tools import rel_path 5 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 6 | 7 | 8 | def resolve_tasks(taskset, manifest): 9 | from bootstrapvz.common.tasks import ssh 10 | from .tasks import SetRootPassword 11 | taskset.discard(ssh.DisableSSHPasswordAuthentication) 12 | taskset.add(ssh.EnableRootLogin) 13 | taskset.add(SetRootPassword) 14 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/root_password/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Root password plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | root_password: 10 | type: object 11 | oneOf: 12 | - required: [password] 13 | - required: [password-crypted] 14 | properties: 15 | password: {type: string} 16 | password-crypted: {type: string} 17 | additionalProperties: false 18 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/root_password/tasks.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | 4 | 5 | class SetRootPassword(Task): 6 | description = 'Setting the root password' 7 | phase = phases.system_modification 8 | 9 | @classmethod 10 | def run(cls, info): 11 | from bootstrapvz.common.tools import log_check_call 12 | password_crypted = info.manifest.plugins['root_password'].get('password-crypted', None) 13 | if password_crypted is not None: 14 | log_check_call(['chroot', info.root, '/usr/sbin/chpasswd', '--encrypted'], 15 | 'root:' + password_crypted) 16 | else: 17 | log_check_call(['chroot', info.root, '/usr/sbin/chpasswd'], 18 | 'root:' + info.manifest.plugins['root_password']['password']) 19 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/salt/README.rst: -------------------------------------------------------------------------------- 1 | Salt 2 | ---- 3 | 4 | Install `salt `__ minion in the image. Uses 5 | `salt-bootstrap `__ script 6 | to install. 7 | 8 | Settings 9 | ~~~~~~~~ 10 | 11 | - ``install_source``: Source to install salt codebase from. ``stable`` 12 | for current stable, ``daily`` for installing the daily build, and 13 | ``git`` to install from git repository. 14 | ``required`` 15 | - ``version``: Only needed if you are installing from ``git``. 16 | \ ``develop`` to install current development head, or provide any tag 17 | name or commit hash from `salt 18 | repo `__ 19 | ``optional`` 20 | - ``master``: Salt master FQDN or IP 21 | ``optional`` 22 | - ``grains``: Set `salt 23 | grains `__ 24 | for this minion. Accepts a map with grain name as key and the grain 25 | data as value. 26 | ``optional`` 27 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/salt/__init__.py: -------------------------------------------------------------------------------- 1 | from . import tasks 2 | 3 | 4 | def validate_manifest(data, validator, error): 5 | from bootstrapvz.common.tools import rel_path 6 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 7 | 8 | 9 | def resolve_tasks(taskset, manifest): 10 | taskset.add(tasks.InstallSaltDependencies) 11 | taskset.add(tasks.BootstrapSaltMinion) 12 | if 'grains' in manifest.plugins['salt']: 13 | taskset.add(tasks.SetSaltGrains) 14 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/salt/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Saltstack plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | salt: 10 | type: object 11 | properties: 12 | grains: 13 | type: object 14 | patternProperties: 15 | ^[^/\0]+$: {type: string} 16 | minItems: 1 17 | install_source: 18 | enum: 19 | - stable 20 | - daily 21 | - git 22 | master: {type: string} 23 | version: {type: string} 24 | required: [install_source] 25 | additionalProperties: false 26 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/tmpfs_workspace/README.rst: -------------------------------------------------------------------------------- 1 | tmpfs workspace 2 | --------------- 3 | 4 | The ``tmpfs workspace`` plugin mounts a tmpfs filesystem for the 5 | workspace temporary files. This is useful when the workspace directory 6 | is placed on a slow medium (e.g. a hard disk drive), the build process 7 | performs lots of local I/O (e.g. building a vagrant box), and there is 8 | enough RAM to store data necessary for the build process. For example, 9 | the ``stretch-vagrant.yml`` manifest file from the examples directory 10 | takes 33 minutes to build on the plugin author's home server. Using 11 | this plugin reduces this time to 3 minutes at the cost of 1.2GB of 12 | additional RAM usage. 13 | 14 | Settings 15 | ~~~~~~~~ 16 | 17 | This plugin has no settings. To enable it add ``"tmpfs_workspace":{}`` 18 | to the plugin section of the manifest. 19 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/tmpfs_workspace/__init__.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common.tasks.workspace import CreateWorkspace, DeleteWorkspace 2 | from .tasks import CreateTmpFsWorkspace, MountTmpFsWorkspace, UnmountTmpFsWorkspace, DeleteTmpFsWorkspace 3 | 4 | 5 | def resolve_tasks(taskset, manifest): 6 | taskset.discard(CreateWorkspace) 7 | taskset.discard(DeleteWorkspace) 8 | 9 | taskset.add(CreateTmpFsWorkspace) 10 | taskset.add(MountTmpFsWorkspace) 11 | taskset.add(UnmountTmpFsWorkspace) 12 | taskset.add(DeleteTmpFsWorkspace) 13 | 14 | 15 | def resolve_rollback_tasks(taskset, manifest, completed, counter_task): 16 | counter_task(taskset, MountTmpFsWorkspace, UnmountTmpFsWorkspace) 17 | counter_task(taskset, CreateTmpFsWorkspace, DeleteTmpFsWorkspace) 18 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/unattended_upgrades/README.rst: -------------------------------------------------------------------------------- 1 | Unattended upgrades 2 | ------------------- 3 | 4 | Enables the `unattended update/upgrade 5 | feature `__ in 6 | aptitude. Enable it to have your system automatically download and 7 | install security updates automatically with a set interval. 8 | 9 | Settings 10 | ~~~~~~~~ 11 | 12 | - ``update_interval``: Days between running ``apt-get update``. 13 | ``required`` 14 | - ``download_interval``: Days between running 15 | ``apt-get upgrade --download-only`` 16 | ``required`` 17 | - ``upgrade_interval``: Days between installing any security upgrades. 18 | ``required`` 19 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/unattended_upgrades/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def validate_manifest(data, validator, error): 4 | from bootstrapvz.common.tools import rel_path 5 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 6 | 7 | 8 | def resolve_tasks(taskset, manifest): 9 | from . import tasks 10 | taskset.add(tasks.AddUnattendedUpgradesPackage) 11 | taskset.add(tasks.EnablePeriodicUpgrades) 12 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/unattended_upgrades/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Unattended upgrades plugin manifest 4 | type: object 5 | properties: 6 | plugins: 7 | type: object 8 | properties: 9 | unattended_upgrades: 10 | type: object 11 | properties: 12 | download_interval: {type: integer} 13 | update_interval: {type: integer} 14 | upgrade_interval: {type: integer} 15 | required: 16 | - update_interval 17 | - download_interval 18 | - upgrade_interval 19 | additionalProperties: false 20 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/vagrant/README.rst: -------------------------------------------------------------------------------- 1 | Vagrant 2 | ------- 3 | 4 | Vagrant is a tool to quickly create virtualized environments. It uses 5 | "boxes" to make downloading and sharing those environments easier. A box 6 | is a tarball containing a virtual volumes accompanied by an `OVF 7 | specification `__ 8 | of the virtual machine. 9 | 10 | This plugin creates a vagrant box that is ready to be shared or 11 | deployed. At the moment it is only compatible with the VirtualBox 12 | and Libvirt providers. 13 | 14 | Settings 15 | ~~~~~~~~ 16 | 17 | - ``provider``: Specifies the provider of a resulting vagrant box. 18 | ``optional`` Valid values: ``virtualbox, libvirt`` Default: ``libvirt`` -------------------------------------------------------------------------------- /bootstrapvz/plugins/vagrant/assets/Vagrantfile: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | Vagrant::Config.run do |config| 6 | # This Vagrantfile is auto-generated by `vagrant package` to contain 7 | # the MAC address of the box. Custom configuration should be placed in 8 | # the actual `Vagrantfile` in this box. 9 | config.vm.base_mac = "[MAC_ADDRESS]" 10 | end 11 | 12 | # Load include vagrant file if it exists after the auto-generated 13 | # so it can override any of the settings 14 | include_vagrantfile = File.expand_path("../include/_Vagrantfile", __FILE__) 15 | load include_vagrantfile if File.exist?(include_vagrantfile) 16 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/vagrant/assets/authorized_keys: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key 2 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/vagrant/assets/metadata.json: -------------------------------------------------------------------------------- 1 | {"provider": "virtualbox"} 2 | -------------------------------------------------------------------------------- /bootstrapvz/plugins/vagrant/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Vagrant plugin manifest 4 | type: object 5 | properties: 6 | provider: 7 | type: object 8 | properties: 9 | name: 10 | type: string 11 | enum: [virtualbox, kvm] 12 | system: 13 | required: [hostname] 14 | volume: 15 | type: object 16 | properties: 17 | backing: 18 | type: string 19 | enum: [vmdk, qcow2] 20 | required: [backing] 21 | plugins: 22 | type: object 23 | properties: 24 | vagrant: 25 | type: object 26 | properties: 27 | provider: 28 | type: string 29 | enum: [virtualbox, libvirt] 30 | additionalProperties: false 31 | -------------------------------------------------------------------------------- /bootstrapvz/providers/README.rst: -------------------------------------------------------------------------------- 1 | Providers in bootstrap-vz represent various cloud providers and virtual machines. 2 | 3 | bootstrap-vz is an extensible platform with loose coupling and a significant 4 | amount of tooling, which allows for painless implementation of new providers. 5 | 6 | The virtualbox provider for example is implemented in only 89 lines of python, 7 | since most of the building blocks are a part of the common task library. 8 | Only the kernel and guest additions installation are specific to that provider. 9 | -------------------------------------------------------------------------------- /bootstrapvz/providers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/providers/__init__.py -------------------------------------------------------------------------------- /bootstrapvz/providers/azure/README.rst: -------------------------------------------------------------------------------- 1 | Azure 2 | ===== 3 | 4 | This provider generates raw images for Microsoft Azure computing 5 | platform. 6 | 7 | 8 | Manifest settings 9 | ----------------- 10 | 11 | Provider 12 | ~~~~~~~~ 13 | 14 | - ``waagent``: Waagent specific settings. 15 | ``required`` 16 | 17 | - ``conf``: Path to ``waagent.conf`` that should override the default 18 | ``optional`` 19 | - ``version``: Version of waagent to install. 20 | Waagent versions are available at: 21 | https://github.com/Azure/WALinuxAgent/releases 22 | ``required`` 23 | 24 | Example: 25 | 26 | .. code-block:: yaml 27 | 28 | --- 29 | provider: 30 | name: azure 31 | waagent: 32 | conf: /root/waagent.conf 33 | version: 2.0.4 34 | 35 | The Windows Azure Linux Agent can automatically configure swap space 36 | using the local resource disk that is attached to the VM after 37 | provisioning on Azure. Modify the following parameters in 38 | /etc/waagent.conf appropriately: 39 | 40 | :: 41 | 42 | ResourceDisk.Format=y 43 | ResourceDisk.Filesystem=ext4 44 | ResourceDisk.MountPoint=/mnt/resource 45 | ResourceDisk.EnableSwap=y 46 | ResourceDisk.SwapSizeMB=2048 ## NOTE: set this to whatever you need it to be. 47 | 48 | -------------------------------------------------------------------------------- /bootstrapvz/providers/azure/assets/udev.diff: -------------------------------------------------------------------------------- 1 | diff --git a/debian/extra/initramfs-tools/scripts/init-top/udev b/debian/extra/initramfs-tools/scripts/init-top/udev 2 | index 687911f..87f1121 100755 3 | --- a/debian/extra/initramfs-tools/scripts/init-top/udev 4 | +++ b/debian/extra/initramfs-tools/scripts/init-top/udev 5 | @@ -31,11 +31,5 @@ if [ -d /sys/bus/scsi ]; then 6 | udevadm settle || true 7 | fi 8 | 9 | -# If the rootdelay parameter has been set, we wait a bit for devices 10 | -# like usb/firewire disks to settle. 11 | -if [ "$ROOTDELAY" ]; then 12 | - sleep $ROOTDELAY 13 | -fi 14 | - 15 | # Leave udev running to process events that come in out-of-band (like USB 16 | # connections) 17 | -------------------------------------------------------------------------------- /bootstrapvz/providers/azure/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Azure manifest 4 | type: object 5 | properties: 6 | provider: 7 | type: object 8 | properties: 9 | waagent: 10 | type: object 11 | properties: 12 | conf: {type: string} 13 | version: {type: string} 14 | required: [version] 15 | required: [waagent] 16 | system: 17 | type: object 18 | properties: 19 | bootloader: 20 | type: string 21 | enum: 22 | - grub 23 | - extlinux 24 | volume: 25 | type: object 26 | properties: 27 | backing: 28 | type: string 29 | enum: [vhd] 30 | partitions: 31 | type: object 32 | properties: 33 | type: 34 | enum: 35 | - none 36 | - msdos 37 | - gpt 38 | required: [backing] 39 | -------------------------------------------------------------------------------- /bootstrapvz/providers/azure/tasks/__init__.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common.tools import rel_path 2 | 3 | assets = rel_path(__file__, '../assets') 4 | -------------------------------------------------------------------------------- /bootstrapvz/providers/azure/tasks/boot.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.common.tasks import grub 4 | from bootstrapvz.common.tasks import kernel 5 | import os 6 | 7 | 8 | class PatchUdev(Task): 9 | description = 'Patching udev configuration to remove ROOTDELAY sleep' 10 | phase = phases.system_modification 11 | successors = [kernel.UpdateInitramfs] 12 | 13 | @classmethod 14 | def run(cls, info): 15 | from bootstrapvz.common.tools import log_check_call 16 | from . import assets 17 | # c.f. http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=61e055638cea 18 | udev_file = os.path.join(info.root, 'usr/share/initramfs-tools/scripts/init-top/udev') 19 | diff_file = os.path.join(assets, 'udev.diff') 20 | log_check_call(['patch', '--no-backup-if-mismatch', udev_file, diff_file]) 21 | 22 | 23 | class ConfigureGrub(Task): 24 | description = 'Change grub configuration to allow for ttyS0 output' 25 | phase = phases.system_modification 26 | successors = [grub.WriteGrubConfig] 27 | 28 | @classmethod 29 | def run(cls, info): 30 | info.grub_config['GRUB_CMDLINE_LINUX'].extend([ 31 | 'console=tty0', 32 | 'console=ttyS0,115200n8', 33 | 'earlyprintk=ttyS0,115200', 34 | 'rootdelay=300', 35 | ]) 36 | -------------------------------------------------------------------------------- /bootstrapvz/providers/azure/tasks/packages-kernels.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is a mapping of Debian release codenames to processor architectures to kernel packages 3 | wheezy: 4 | amd64: linux-image-amd64 5 | i386: linux-image-686 6 | jessie: 7 | amd64: linux-image-amd64 8 | i386: linux-image-686-pae 9 | stretch: 10 | amd64: linux-image-amd64 11 | i386: linux-image-686-pae 12 | sid: 13 | amd64: linux-image-amd64 14 | i386: linux-image-686-pae 15 | -------------------------------------------------------------------------------- /bootstrapvz/providers/docker/assets/docker-apt-speedup: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | # For most Docker users, package installs happen during "docker build", which 6 | # doesn't survive power loss and gets restarted clean afterwards anyhow, so 7 | # this minor tweak gives us a nice speedup (much nicer on spinning disks, 8 | # obviously). 9 | force-unsafe-io 10 | -------------------------------------------------------------------------------- /bootstrapvz/providers/docker/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Docker manifest 4 | type: object 5 | properties: 6 | provider: 7 | type: object 8 | properties: 9 | labels: 10 | type: object 11 | properties: 12 | # https://github.com/projectatomic/ContainerApplicationGenericLabels 13 | distribution-scope: 14 | type: string 15 | enum: 16 | - private 17 | - authoritative-source-only 18 | - restricted 19 | - public 20 | patternProperties: 21 | ^.+$: {type: string} 22 | dockerfile: 23 | type: array 24 | items: 25 | # https://github.com/turtlebender/docker/blob/6e2662b3bad319679e17fe25d410f246820ab0e9/builder/job.go#L27 26 | type: string 27 | pattern: '^(ENTRYPOINT|CMD|USER|WORKDIR|ENV|VOLUME|EXPOSE|ONBUILD|LABEL|MAINTAINER)' 28 | system: 29 | type: object 30 | properties: 31 | bootloader: 32 | type: string 33 | enum: [none] 34 | volume: 35 | type: object 36 | properties: 37 | backing: 38 | type: string 39 | enum: [folder] 40 | partitions: 41 | type: object 42 | properties: 43 | type: 44 | type: string 45 | enum: [none] 46 | required: [backing] 47 | -------------------------------------------------------------------------------- /bootstrapvz/providers/docker/tasks/__init__.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common.tools import rel_path 2 | 3 | assets = rel_path(__file__, '../assets') 4 | -------------------------------------------------------------------------------- /bootstrapvz/providers/docker/tasks/commands.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.common.tasks import host 4 | 5 | 6 | class AddRequiredCommands(Task): 7 | description = 'Adding commands required for docker' 8 | phase = phases.validation 9 | successors = [host.CheckExternalCommands] 10 | 11 | @classmethod 12 | def run(cls, info): 13 | info.host_dependencies['docker'] = 'docker.io' 14 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/assets/ec2/53-ec2-network-interfaces.rules: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2012 Amazon.com, Inc. or its affiliates. 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"). 5 | # You may not use this file except in compliance with the License. 6 | # A copy of the License is located at 7 | # 8 | # http://aws.amazon.com/apache2.0/ 9 | # 10 | # or in the "license" file accompanying this file. This file is 11 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 12 | # OF ANY KIND, either express or implied. See the License for the 13 | # specific language governing permissions and limitations under the 14 | # License. 15 | 16 | # This file was created by bootstrap-vz. 17 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 18 | # legal notices and disclaimers. 19 | 20 | ACTION=="add", SUBSYSTEM=="net", KERNEL=="eth*", IMPORT{program}="/bin/sleep 1" 21 | SUBSYSTEM=="net", RUN+="/etc/sysconfig/network-scripts/ec2net.hotplug" 22 | 23 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/assets/ec2/ec2dhcp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2012 Amazon.com, Inc. or its affiliates. 4 | # All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"). 7 | # You may not use this file except in compliance with the License. 8 | # A copy of the License is located at 9 | # 10 | # http://aws.amazon.com/apache2.0/ 11 | # 12 | # or in the "license" file accompanying this file. This file is 13 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 14 | # OF ANY KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations under the 16 | # License. 17 | 18 | # This file was created by bootstrap-vz. 19 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 20 | # legal notices and disclaimers. 21 | 22 | INTERFACE="${interface}" 23 | PREFIX="${new_prefix}" 24 | . /etc/sysconfig/network-scripts/ec2net-functions 25 | 26 | ec2dhcp_config() { 27 | rewrite_rules 28 | rewrite_aliases 29 | } 30 | 31 | ec2dhcp_restore() { 32 | remove_aliases 33 | remove_rules 34 | } 35 | 36 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/assets/ec2/ec2net.hotplug: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2012 Amazon.com, Inc. or its affiliates. 4 | # All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"). 7 | # You may not use this file except in compliance with the License. 8 | # A copy of the License is located at 9 | # 10 | # http://aws.amazon.com/apache2.0/ 11 | # 12 | # or in the "license" file accompanying this file. This file is 13 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 14 | # OF ANY KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations under the 16 | # License. 17 | 18 | # This file was created by bootstrap-vz. 19 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 20 | # legal notices and disclaimers. 21 | 22 | # During init and before the network service is started, metadata is not 23 | # available. Exit without attempting to configure the elastic interface. 24 | if [ `/sbin/runlevel | /usr/bin/cut -d\ -f2` -ne 5 ]; then 25 | exit 26 | fi 27 | if [ -f /dev/.in_sysinit ]; then 28 | exit 29 | fi 30 | 31 | 32 | . /etc/sysconfig/network-scripts/ec2net-functions 33 | 34 | case $ACTION in 35 | add) 36 | plug_interface 37 | activate_primary 38 | ;; 39 | remove) 40 | deactivate_primary 41 | unplug_interface 42 | ;; 43 | esac 44 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/assets/sysctl.d/tuning.conf: -------------------------------------------------------------------------------- 1 | # This file was created by bootstrap-vz. 2 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 3 | # legal notices and disclaimers. 4 | 5 | vm.swappiness = 0 6 | vm.dirty_ratio = 80 7 | vm.dirty_background_ratio = 5 8 | vm.dirty_expire_centisecs = 12000 9 | net.core.somaxconn = 1000 10 | net.core.netdev_max_backlog = 5000 11 | net.core.rmem_max = 16777216 12 | net.core.wmem_max = 16777216 13 | net.ipv4.tcp_wmem = 4096 12582912 16777216 14 | net.ipv4.tcp_rmem = 4096 12582912 16777216 15 | net.ipv4.tcp_max_syn_backlog = 8096 16 | net.ipv4.tcp_slow_start_after_idle = 0 17 | net.ipv4.tcp_tw_reuse = 1 18 | net.ipv4.ip_local_port_range = 10240 65535 19 | kernel.sysrq = 0 20 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/manifest-schema-s3.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: EC2 manifest for instance store AMIs 4 | type: object 5 | properties: 6 | provider: 7 | type: object 8 | properties: 9 | credentials: 10 | type: object 11 | properties: 12 | certificate: {type: string} 13 | private-key: {type: string} 14 | user-id: 15 | type: string 16 | pattern: (^arn:aws:iam::\d*:user/\w.*$)|(^\d{4}-\d{4}-\d{4}$) 17 | bucket: {type: string} 18 | region: {$ref: '#/definitions/aws-region'} 19 | required: 20 | - bucket 21 | - region 22 | definitions: 23 | aws-region: 24 | enum: 25 | - ap-northeast-1 26 | - ap-northeast-2 27 | - ap-southeast-1 28 | - ap-southeast-2 29 | - ca-central-1 30 | - eu-central-1 31 | - eu-west-1 32 | - sa-east-1 33 | - us-east-1 34 | - us-gov-west-1 35 | - us-west-1 36 | - us-west-2 37 | - cn-north-1 38 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/tasks/__init__.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common.tools import rel_path 2 | 3 | assets = rel_path(__file__, '../assets') 4 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/tasks/ami-akis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is a mapping of EC2 regions to processor architectures to Amazon Kernel Images 3 | # Source: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedKernels.html#AmazonKernelImageIDs 4 | ap-northeast-1: 5 | amd64: aki-176bf516 6 | i386: aki-136bf512 7 | ap-southeast-1: 8 | amd64: aki-503e7402 9 | i386: aki-ae3973fc 10 | ap-southeast-2: 11 | amd64: aki-c362fff9 12 | i386: aki-cd62fff7 13 | eu-west-1: 14 | amd64: aki-52a34525 15 | i386: aki-68a3451f 16 | eu-central-1: 17 | i386: aki-3e4c7a23 18 | amd64: aki-184c7a05 19 | sa-east-1: 20 | amd64: aki-5553f448 21 | i386: aki-5b53f446 22 | us-east-1: 23 | amd64: aki-919dcaf8 24 | i386: aki-8f9dcae6 25 | us-gov-west-1: 26 | amd64: aki-1de98d3e 27 | i386: aki-1fe98d3c 28 | us-west-1: 29 | amd64: aki-880531cd 30 | i386: aki-8e0531cb 31 | us-west-2: 32 | amd64: aki-fc8f11cc 33 | i386: aki-f08f11c0 34 | cn-north-1: 35 | amd64: aki-9e8f1da7 36 | i386: aki-908f1da9 37 | ca-central-1: 38 | amd64: aki-320ebd56 39 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/tasks/filesystem.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | 4 | 5 | class S3FStab(Task): 6 | description = 'Adding the S3 root partition to the fstab' 7 | phase = phases.system_modification 8 | 9 | @classmethod 10 | def run(cls, info): 11 | import os.path 12 | root = info.volume.partition_map.root 13 | 14 | fstab_lines = [] 15 | mount_opts = ['defaults'] 16 | fstab_lines.append('{device_path}{idx} {mountpoint} {filesystem} {mount_opts} {dump} {pass_num}' 17 | .format(device_path='/dev/xvda', 18 | idx=1, 19 | mountpoint='/', 20 | filesystem=root.filesystem, 21 | mount_opts=','.join(mount_opts), 22 | dump='1', 23 | pass_num='1')) 24 | 25 | fstab_path = os.path.join(info.root, 'etc/fstab') 26 | with open(fstab_path, 'w') as fstab: 27 | fstab.write('\n'.join(fstab_lines)) 28 | fstab.write('\n') 29 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/tasks/host.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.common.tasks import host 4 | 5 | 6 | class AddExternalCommands(Task): 7 | description = 'Determining required external commands for EC2 bootstrapping' 8 | phase = phases.validation 9 | successors = [host.CheckExternalCommands] 10 | 11 | @classmethod 12 | def run(cls, info): 13 | if info.manifest.volume['backing'] == 's3': 14 | info.host_dependencies['euca-bundle-image'] = 'euca2ools' 15 | info.host_dependencies['euca-upload-bundle'] = 'euca2ools' 16 | 17 | 18 | class GetInstanceMetadata(Task): 19 | description = 'Retrieving instance metadata' 20 | phase = phases.preparation 21 | 22 | @classmethod 23 | def run(cls, info): 24 | import urllib2 25 | import json 26 | metadata_url = 'http://169.254.169.254/latest/dynamic/instance-identity/document' 27 | response = urllib2.urlopen(url=metadata_url, timeout=5) 28 | info._ec2['host'] = json.load(response) 29 | info._ec2['region'] = info._ec2['host']['region'] 30 | 31 | 32 | class SetRegion(Task): 33 | description = 'Setting the AWS region' 34 | phase = phases.preparation 35 | 36 | @classmethod 37 | def run(cls, info): 38 | info._ec2['region'] = info.manifest.provider['region'] 39 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/tasks/initd.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.common.tasks import initd 4 | from . import assets 5 | import os.path 6 | 7 | 8 | class AddEC2InitScripts(Task): 9 | description = 'Adding EC2 startup scripts' 10 | phase = phases.system_modification 11 | successors = [initd.InstallInitScripts] 12 | 13 | @classmethod 14 | def run(cls, info): 15 | init_scripts = {'ec2-get-credentials': 'ec2-get-credentials', 16 | 'ec2-run-user-data': 'ec2-run-user-data'} 17 | 18 | init_scripts_dir = os.path.join(assets, 'init.d') 19 | for name, path in init_scripts.iteritems(): 20 | info.initd['install'][name] = os.path.join(init_scripts_dir, path) 21 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/tasks/packages-kernels.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is a mapping of Debian release codenames to processor architectures to kernel packages 3 | wheezy: 4 | amd64: linux-image-amd64 5 | i386: linux-image-686 6 | jessie: 7 | amd64: linux-image-amd64 8 | i386: linux-image-686-pae 9 | stretch: 10 | amd64: linux-image-amd64 11 | i386: linux-image-686-pae 12 | buster: 13 | amd64: linux-image-amd64 14 | i386: linux-image-686-pae 15 | sid: 16 | amd64: linux-image-amd64 17 | i386: linux-image-686-pae 18 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/tasks/packages.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | import os.path 4 | 5 | 6 | class DefaultPackages(Task): 7 | description = 'Adding image packages required for EC2' 8 | phase = phases.preparation 9 | 10 | @classmethod 11 | def run(cls, info): 12 | from bootstrapvz.common.tools import rel_path 13 | info.packages.add('file') # Needed for the init scripts 14 | 15 | kernel_packages_path = rel_path(__file__, 'packages-kernels.yml') 16 | from bootstrapvz.common.tools import config_get 17 | kernel_package = config_get(kernel_packages_path, [info.manifest.release.codename, 18 | info.manifest.system['architecture']]) 19 | info.packages.add(kernel_package) 20 | 21 | 22 | class AddWorkaroundGrowpart(Task): 23 | description = 'Adding growpart workaround for jessie' 24 | phase = phases.system_modification 25 | 26 | @classmethod 27 | def run(cls, info): 28 | from shutil import copy 29 | from . import assets 30 | src = os.path.join(assets, 'bin/growpart') 31 | dst = os.path.join(info.root, 'usr/bin/growpart-workaround') 32 | copy(src, dst) 33 | -------------------------------------------------------------------------------- /bootstrapvz/providers/ec2/tasks/tuning.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from . import assets 4 | from shutil import copy 5 | import os 6 | 7 | 8 | class TuneSystem(Task): 9 | description = 'Tuning system for EC2' 10 | phase = phases.system_modification 11 | 12 | @classmethod 13 | def run(cls, info): 14 | sysctl_src = os.path.join(assets, 'sysctl.d/tuning.conf') 15 | sysctl_dst = os.path.join(info.root, 'etc/sysctl.d/01_ec2.conf') 16 | copy(sysctl_src, sysctl_dst) 17 | os.chmod(sysctl_dst, 0o644) 18 | 19 | 20 | class BlackListModules(Task): 21 | description = 'Blacklisting unused kernel modules' 22 | phase = phases.system_modification 23 | 24 | @classmethod 25 | def run(cls, info): 26 | blacklist_path = os.path.join(info.root, 'etc/modprobe.d/blacklist.conf') 27 | with open(blacklist_path, 'a') as blacklist: 28 | blacklist.write(('blacklist i2c_piix4\n' 29 | 'blacklist psmouse\n')) 30 | -------------------------------------------------------------------------------- /bootstrapvz/providers/gce/README.rst: -------------------------------------------------------------------------------- 1 | Google Compute Engine 2 | ===================== 3 | 4 | The `GCE `__ provider 5 | can creates image as expected by GCE - i.e. raw disk image in \*.tar.gz 6 | file. It can upload created images to Google Cloud Storage (to a URI 7 | provided in the manifest by ``gcs_destination``) and can register images to 8 | be used by Google Compute Engine to a project provided in the manifest by 9 | ``gce_project``. Both of those functionalities are not fully tested yet. 10 | 11 | Note that to register an image, it must first be uploaded to GCS, so you must 12 | specify ``gcs_destination`` (upload to GCS) to use ``gce_project`` (register 13 | with GCE) 14 | 15 | Manifest settings 16 | ----------------- 17 | 18 | Provider 19 | ~~~~~~~~ 20 | 21 | - ``description``: Description of the image. 22 | - ``gcs_destination``: Image destination in GCS. 23 | - ``gce_project``: GCE project in which to register the image. 24 | 25 | 26 | Example: 27 | 28 | .. code-block:: yaml 29 | 30 | --- 31 | provider: 32 | name: gce 33 | description: Debian {system.release} {system.architecture} 34 | gcs_destination: gs://my-bucket 35 | gce_project: my-project 36 | -------------------------------------------------------------------------------- /bootstrapvz/providers/gce/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: GCE manifest 4 | type: object 5 | properties: 6 | provider: 7 | type: object 8 | properties: 9 | description: {type: string} 10 | gce_project: {type: string} 11 | gcs_destination: {type: string} 12 | system: 13 | type: object 14 | properties: 15 | bootloader: 16 | type: string 17 | enum: 18 | - grub 19 | - extlinux 20 | volume: 21 | type: object 22 | properties: 23 | partitions: 24 | type: object 25 | properties: 26 | type: 27 | enum: 28 | - msdos 29 | - gpt 30 | required: [partitions] 31 | -------------------------------------------------------------------------------- /bootstrapvz/providers/gce/tasks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/providers/gce/tasks/__init__.py -------------------------------------------------------------------------------- /bootstrapvz/providers/gce/tasks/apt.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.common.tasks import apt 4 | from bootstrapvz.common.tasks import network 5 | from bootstrapvz.common.tools import log_check_call 6 | 7 | 8 | class AddBaselineAptCache(Task): 9 | description = 'Add a baseline apt cache into the image.' 10 | phase = phases.system_cleaning 11 | predecessors = [apt.AptClean] 12 | successors = [network.RemoveDNSInfo] 13 | 14 | @classmethod 15 | def run(cls, info): 16 | log_check_call(['chroot', info.root, 'apt-get', 'update']) 17 | -------------------------------------------------------------------------------- /bootstrapvz/providers/gce/tasks/boot.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.common.tasks import grub 4 | 5 | 6 | class ConfigureGrub(Task): 7 | description = 'Change grub configuration to allow for ttyS0 output' 8 | phase = phases.system_modification 9 | successors = [grub.WriteGrubConfig] 10 | 11 | @classmethod 12 | def run(cls, info): 13 | info.grub_config['GRUB_CMDLINE_LINUX'].append('console=ttyS0,38400n8') 14 | info.grub_config['GRUB_CMDLINE_LINUX'].append('elevator=noop') 15 | # Enable SCSI block multiqueue on Stretch. 16 | from bootstrapvz.common.releases import stretch 17 | if info.manifest.release >= stretch: 18 | info.grub_config['GRUB_CMDLINE_LINUX'].append('scsi_mod.use_blk_mq=Y') 19 | -------------------------------------------------------------------------------- /bootstrapvz/providers/gce/tasks/configuration.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.common.tools import log_check_call 4 | 5 | 6 | class GatherReleaseInformation(Task): 7 | description = 'Gathering release information about created image' 8 | phase = phases.system_modification 9 | 10 | @classmethod 11 | def run(cls, info): 12 | lsb_distribution = log_check_call(['chroot', info.root, 'lsb_release', '-i', '-s']) 13 | lsb_description = log_check_call(['chroot', info.root, 'lsb_release', '-d', '-s']) 14 | lsb_release = log_check_call(['chroot', info.root, 'lsb_release', '-r', '-s']) 15 | info._gce['lsb_distribution'] = lsb_distribution[0] 16 | info._gce['lsb_description'] = lsb_description[0] 17 | info._gce['lsb_release'] = lsb_release[0] 18 | -------------------------------------------------------------------------------- /bootstrapvz/providers/gce/tasks/packages-kernels.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is a mapping of Debian release codenames to processor architectures to kernel packages 3 | wheezy: 4 | amd64: linux-image-amd64 5 | jessie: 6 | amd64: linux-image-amd64 7 | stretch: 8 | amd64: linux-image-amd64 9 | buster: 10 | amd64: linux-image-amd64 11 | sid: 12 | amd64: linux-image-amd64 13 | -------------------------------------------------------------------------------- /bootstrapvz/providers/kvm/assets/noclear.conf: -------------------------------------------------------------------------------- 1 | # https://wiki.debian.org/systemd#Missing_startup_messages_on_console.28tty1.29_after_the_boot 2 | [Service] 3 | TTYVTDisallocate=no 4 | -------------------------------------------------------------------------------- /bootstrapvz/providers/kvm/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: KVM manifest 4 | type: object 5 | properties: 6 | provider: 7 | type: object 8 | properties: 9 | virtio: 10 | type: array 11 | items: 12 | type: string 13 | enum: 14 | - virtio 15 | - virtio_pci 16 | - virtio_balloon 17 | - virtio_blk 18 | - virtio_net 19 | - virtio_ring 20 | minItems: 1 21 | console: 22 | type: string 23 | enum: 24 | - serial 25 | - virtual 26 | system: 27 | type: object 28 | properties: 29 | bootloader: 30 | type: string 31 | enum: 32 | - grub 33 | - extlinux 34 | - none 35 | volume: 36 | type: object 37 | properties: 38 | backing: 39 | type: string 40 | enum: 41 | - qcow2 42 | - raw 43 | - lvm 44 | logicalvolume: {type: string} 45 | volumegroup: {type: string} 46 | partitions: 47 | type: object 48 | properties: 49 | type: 50 | type: string 51 | enum: 52 | - none 53 | - msdos 54 | - gpt 55 | required: [backing] 56 | -------------------------------------------------------------------------------- /bootstrapvz/providers/kvm/tasks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/providers/kvm/tasks/__init__.py -------------------------------------------------------------------------------- /bootstrapvz/providers/kvm/tasks/packages-kernels.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is a mapping of Debian release codenames to processor architectures to kernel packages 3 | wheezy: 4 | amd64: linux-image-amd64 5 | i386: linux-image-686 6 | jessie: 7 | amd64: linux-image-amd64 8 | i386: linux-image-686-pae 9 | arm64: linux-image-arm64 10 | stretch: 11 | amd64: linux-image-amd64 12 | i386: linux-image-686-pae 13 | arm64: linux-image-arm64 14 | buster: 15 | amd64: linux-image-amd64 16 | i386: linux-image-686-pae 17 | arm64: linux-image-arm64 18 | sid: 19 | amd64: linux-image-amd64 20 | i386: linux-image-686-pae 21 | -------------------------------------------------------------------------------- /bootstrapvz/providers/kvm/tasks/packages.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | 4 | 5 | class DefaultPackages(Task): 6 | description = 'Adding image packages required for kvm' 7 | phase = phases.preparation 8 | 9 | @classmethod 10 | def run(cls, info): 11 | from bootstrapvz.common.tools import config_get, rel_path 12 | kernel_packages_path = rel_path(__file__, 'packages-kernels.yml') 13 | kernel_package = config_get(kernel_packages_path, [info.manifest.release.codename, 14 | info.manifest.system['architecture']]) 15 | info.packages.add(kernel_package) 16 | -------------------------------------------------------------------------------- /bootstrapvz/providers/kvm/tasks/virtio.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | import os 4 | 5 | 6 | class VirtIO(Task): 7 | description = 'Install virtio modules' 8 | phase = phases.system_modification 9 | 10 | @classmethod 11 | def run(cls, info): 12 | modules = os.path.join(info.root, '/etc/initramfs-tools/modules') 13 | with open(modules, "a") as modules_file: 14 | modules_file.write("\n") 15 | for module in info.manifest.provider.get('virtio', []): 16 | modules_file.write(module + "\n") 17 | -------------------------------------------------------------------------------- /bootstrapvz/providers/oracle/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: Oracle manifest 4 | type: object 5 | properties: 6 | provider: 7 | type: object 8 | properties: 9 | credentials: 10 | type: object 11 | properties: 12 | username: {type: string} 13 | password: {type: string} 14 | identity-domain: {type: string} 15 | container: {type: string} 16 | verify: {type: boolean} 17 | system: 18 | type: object 19 | properties: 20 | bootloader: 21 | type: string 22 | enum: [grub] 23 | volume: 24 | type: object 25 | properties: 26 | backing: 27 | type: string 28 | enum: [raw] 29 | partitions: 30 | type: object 31 | properties: 32 | type: 33 | type: string 34 | enum: 35 | - msdos 36 | - gpt 37 | required: [backing] 38 | -------------------------------------------------------------------------------- /bootstrapvz/providers/oracle/tasks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/providers/oracle/tasks/__init__.py -------------------------------------------------------------------------------- /bootstrapvz/providers/oracle/tasks/api.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.providers.oracle.apiclient import OracleStorageAPIClient 4 | 5 | 6 | class Connect(Task): 7 | description = 'Connecting to the Oracle Storage Cloud API' 8 | phase = phases.preparation 9 | 10 | @classmethod 11 | def run(cls, info): 12 | info._oracle['client'] = OracleStorageAPIClient( 13 | username=info.manifest.provider['credentials']['username'], 14 | password=info.manifest.provider['credentials']['password'], 15 | identity_domain=info.manifest.provider['credentials']['identity-domain'], 16 | container=info.manifest.provider['container'], 17 | ) 18 | # Try to fetch the token, so it will fail early if the credentials are wrong 19 | info._oracle['client'].auth_token # pylint: disable=pointless-statement 20 | -------------------------------------------------------------------------------- /bootstrapvz/providers/oracle/tasks/network.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | 4 | 5 | class InstallDHCPCD(Task): 6 | description = 'Replacing isc-dhcp with dhcpcd5' 7 | phase = phases.preparation 8 | 9 | @classmethod 10 | def run(cls, info): 11 | info.packages.add('dhcpcd5') 12 | info.exclude_packages.add('isc-dhcp-client') 13 | info.exclude_packages.add('isc-dhcp-common') 14 | -------------------------------------------------------------------------------- /bootstrapvz/providers/oracle/tasks/packages-kernels.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is a mapping of Debian release codenames to processor architectures to kernel packages 3 | jessie: 4 | amd64: linux-image-amd64 5 | i386: linux-image-686-pae 6 | stretch: 7 | amd64: linux-image-amd64 8 | i386: linux-image-686-pae 9 | sid: 10 | amd64: linux-image-amd64 11 | i386: linux-image-686-pae 12 | -------------------------------------------------------------------------------- /bootstrapvz/providers/oracle/tasks/packages.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.common.tools import config_get, rel_path 4 | 5 | 6 | class DefaultPackages(Task): 7 | description = 'Adding image packages required for Oracle Compute Cloud' 8 | phase = phases.preparation 9 | 10 | @classmethod 11 | def run(cls, info): 12 | kernel_packages_path = rel_path(__file__, 'packages-kernels.yml') 13 | kernel_package = config_get(kernel_packages_path, [info.manifest.release.codename, 14 | info.manifest.system['architecture']]) 15 | info.packages.add(kernel_package) 16 | -------------------------------------------------------------------------------- /bootstrapvz/providers/virtualbox/README.rst: -------------------------------------------------------------------------------- 1 | VirtualBox 2 | ========== 3 | 4 | The `VirtualBox `__ provider can bootstrap 5 | to both .vdi and .vmdk images (raw images are also supported but do not 6 | run in VirtualBox). It's advisable to always use vmdk images for 7 | interoperability (e.g. 8 | `OVF `__ files 9 | *should* support vdi files, but since they have no identifier URL not 10 | even VirtualBox itself can import them). 11 | 12 | VirtualBox Guest Additions can be installed automatically if the ISO is 13 | provided in the manifest. 14 | VirtualBox Additions iso can be installed from main Debian repo by running: 15 | `apt install virtualbox-guest-additions-iso` 16 | 17 | 18 | Manifest settings 19 | ----------------- 20 | 21 | Provider 22 | ~~~~~~~~ 23 | 24 | - ``guest_additions``: Specifies the path to the VirtualBox Guest Additions ISO, 25 | which, when specified, will be mounted and used to install the 26 | VirtualBox Guest Additions. 27 | ``optional`` 28 | 29 | Example: 30 | 31 | .. code-block:: yaml 32 | 33 | --- 34 | provider: 35 | name: virtualbox 36 | guest_additions: /usr/share/virtualbox/VBoxGuestAdditions.iso 37 | -------------------------------------------------------------------------------- /bootstrapvz/providers/virtualbox/__init__.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.common import task_groups 2 | from bootstrapvz.common.tasks import image 3 | from bootstrapvz.common.tasks import loopback 4 | from .tasks import packages, boot 5 | 6 | 7 | def validate_manifest(data, validator, error): 8 | from bootstrapvz.common.tools import rel_path 9 | validator(data, rel_path(__file__, 'manifest-schema.yml')) 10 | 11 | 12 | def resolve_tasks(taskset, manifest): 13 | taskset.update(task_groups.get_standard_groups(manifest)) 14 | 15 | taskset.update([packages.DefaultPackages, 16 | boot.AddVirtualConsoleGrubOutputDevice, 17 | loopback.AddRequiredCommands, 18 | loopback.Create, 19 | image.MoveImage, 20 | ]) 21 | 22 | if manifest.provider.get('guest_additions', False): 23 | from .tasks import guest_additions 24 | taskset.update([guest_additions.CheckGuestAdditionsPath, 25 | guest_additions.AddGuestAdditionsPackages, 26 | guest_additions.InstallGuestAdditions, 27 | ]) 28 | 29 | 30 | def resolve_rollback_tasks(taskset, manifest, completed, counter_task): 31 | taskset.update(task_groups.get_standard_rollback_tasks(completed)) 32 | -------------------------------------------------------------------------------- /bootstrapvz/providers/virtualbox/assets/install_guest_additions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This file was created by bootstrap-vz. 3 | # See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for 4 | # legal notices and disclaimers. 5 | 6 | function uname { 7 | if [[ $1 == '-r' ]]; then 8 | echo "KERNEL_VERSION" 9 | return 0 10 | elif [[ $1 == '-m' ]]; then 11 | echo "KERNEL_ARCH" 12 | return 0 13 | else 14 | $(which uname) $@ 15 | fi 16 | } 17 | export -f uname 18 | 19 | INSTALL_SCRIPT --nox11 20 | -------------------------------------------------------------------------------- /bootstrapvz/providers/virtualbox/manifest-schema.yml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | title: VirtualBox manifest 4 | type: object 5 | properties: 6 | provider: 7 | type: object 8 | properties: 9 | guest_additions: 10 | type: string 11 | pattern: ^[^\0]+$ 12 | system: 13 | type: object 14 | properties: 15 | bootloader: 16 | type: string 17 | enum: 18 | - grub 19 | - extlinux 20 | volume: 21 | type: object 22 | properties: 23 | backing: 24 | type: string 25 | enum: 26 | - raw 27 | - vdi 28 | - vmdk 29 | partitions: 30 | type: object 31 | properties: 32 | type: 33 | type: string 34 | enum: 35 | - none 36 | - msdos 37 | - gpt 38 | required: [backing] 39 | -------------------------------------------------------------------------------- /bootstrapvz/providers/virtualbox/tasks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/bootstrapvz/providers/virtualbox/tasks/__init__.py -------------------------------------------------------------------------------- /bootstrapvz/providers/virtualbox/tasks/boot.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | from bootstrapvz.common.tasks import grub 4 | 5 | 6 | class AddVirtualConsoleGrubOutputDevice(Task): 7 | description = 'Adding `tty0\' as output device for grub' 8 | phase = phases.system_modification 9 | predecessors = [grub.SetGrubConsolOutputDeviceToSerial] 10 | successors = [grub.WriteGrubConfig] 11 | 12 | @classmethod 13 | def run(cls, info): 14 | info.grub_config['GRUB_CMDLINE_LINUX_DEFAULT'].append('console=tty0') 15 | -------------------------------------------------------------------------------- /bootstrapvz/providers/virtualbox/tasks/packages-kernels.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is a mapping of Debian release codenames to processor architectures to kernel packages 3 | wheezy: 4 | amd64: linux-image-amd64 5 | i386: linux-image-686 6 | jessie: 7 | amd64: linux-image-amd64 8 | i386: linux-image-686-pae 9 | stretch: 10 | amd64: linux-image-amd64 11 | i386: linux-image-686-pae 12 | sid: 13 | amd64: linux-image-amd64 14 | i386: linux-image-686-pae 15 | -------------------------------------------------------------------------------- /bootstrapvz/providers/virtualbox/tasks/packages.py: -------------------------------------------------------------------------------- 1 | from bootstrapvz.base import Task 2 | from bootstrapvz.common import phases 3 | 4 | 5 | class DefaultPackages(Task): 6 | description = 'Adding image packages required for virtualbox' 7 | phase = phases.preparation 8 | 9 | @classmethod 10 | def run(cls, info): 11 | from bootstrapvz.common.tools import config_get, rel_path 12 | kernel_packages_path = rel_path(__file__, 'packages-kernels.yml') 13 | kernel_package = config_get(kernel_packages_path, [info.manifest.release.codename, 14 | info.manifest.system['architecture']]) 15 | info.packages.add(kernel_package) 16 | -------------------------------------------------------------------------------- /bootstrapvz/remote/build_servers/callback.py: -------------------------------------------------------------------------------- 1 | import Pyro4 2 | import logging 3 | 4 | Pyro4.config.REQUIRE_EXPOSE = True 5 | log = logging.getLogger(__name__) 6 | 7 | 8 | class CallbackServer(object): 9 | 10 | def __init__(self, listen_port, remote_port): 11 | self.daemon = Pyro4.Daemon(host='localhost', port=listen_port, 12 | nathost='localhost', natport=remote_port, 13 | unixsocket=None) 14 | self.daemon.register(self) 15 | 16 | def __enter__(self): 17 | def serve(): 18 | self.daemon.requestLoop() 19 | from threading import Thread 20 | self.thread = Thread(target=serve) 21 | log.debug('Starting callback server') 22 | self.thread.start() 23 | return self 24 | 25 | def __exit__(self, exception_type, exception_value, traceback): 26 | log.debug('Shutting down callback server') 27 | self.daemon.shutdown() 28 | self.thread.join() 29 | 30 | @Pyro4.expose 31 | def handle_log(self, pickled_record): 32 | import pickle 33 | record = pickle.loads(pickled_record) 34 | record.extra = getattr(record, 'extra', {}) 35 | record.extra['source'] = 'remote' 36 | log.handle(record) 37 | -------------------------------------------------------------------------------- /bootstrapvz/remote/build_servers/local.py: -------------------------------------------------------------------------------- 1 | from .build_server import BuildServer 2 | from contextlib import contextmanager 3 | 4 | 5 | class LocalBuildServer(BuildServer): 6 | 7 | @contextmanager 8 | def connect(self): 9 | yield LocalConnection() 10 | 11 | 12 | class LocalConnection(object): 13 | 14 | def run(self, *args, **kwargs): 15 | from bootstrapvz.base.main import run 16 | return run(*args, **kwargs) 17 | -------------------------------------------------------------------------------- /bootstrapvz/remote/log.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | 4 | class LogForwarder(logging.Handler): 5 | 6 | def __init__(self, level=logging.NOTSET): 7 | self.server = None 8 | super(LogForwarder, self).__init__(level) 9 | 10 | def set_server(self, server): 11 | self.server = server 12 | 13 | def emit(self, record): 14 | if self.server is not None: 15 | if record.exc_info is not None: 16 | import traceback 17 | exc_type, exc_value, exc_traceback = record.exc_info 18 | record.extra = getattr(record, 'extra', {}) 19 | record.extra['traceback'] = traceback.format_exception(exc_type, exc_value, exc_traceback) 20 | record.exc_info = None 21 | # TODO: Use serpent instead 22 | import pickle 23 | self.server.handle_log(pickle.dumps(record)) 24 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | -------------------------------------------------------------------------------- /docs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/docs/__init__.py -------------------------------------------------------------------------------- /docs/_static/.gitignore: -------------------------------------------------------------------------------- 1 | graph.json 2 | -------------------------------------------------------------------------------- /docs/_static/taskoverview.less: -------------------------------------------------------------------------------- 1 | #taskoverview-graph { 2 | g.hulls path { 3 | opacity: 0.25; 4 | } 5 | g.hull-labels text { 6 | } 7 | g.nodes circle { 8 | stroke: #000000; 9 | &.highlight { 10 | stroke: #555599; 11 | stroke-width: 2.5px; 12 | fill: #EEAAAA !important; 13 | } 14 | opacity: .9; 15 | stroke-width: 1.5px; 16 | } 17 | g.node-labels text { 18 | pointer-events: none; 19 | font: 10px sans-serif; 20 | text-anchor: middle; 21 | text-shadow: 0 0 2px #FFFFFF; 22 | font-weight: bold; 23 | opacity: 0; 24 | &.hover { 25 | transition: opacity .5s; 26 | opacity: .9; 27 | } 28 | } 29 | g.links line { 30 | stroke: #999; 31 | stroke-opacity: .6; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /docs/api/base/index.rst: -------------------------------------------------------------------------------- 1 | 2 | Base functionality 3 | ================== 4 | 5 | The base module represents concepts of the bootstrapping process that tasks can interact with 6 | and handles the gather, sorting and running of tasks. 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | :glob: 11 | 12 | * 13 | 14 | Bootstrap information 15 | --------------------- 16 | .. automodule:: bootstrapvz.base.bootstrapinfo 17 | :members: 18 | :private-members: 19 | 20 | Manifest 21 | -------- 22 | .. automodule:: bootstrapvz.base.manifest 23 | :members: 24 | :private-members: 25 | 26 | 27 | Tasklist 28 | -------- 29 | .. automodule:: bootstrapvz.base.tasklist 30 | :members: 31 | :private-members: 32 | 33 | 34 | Logging 35 | -------- 36 | .. automodule:: bootstrapvz.base.log 37 | :members: 38 | :private-members: 39 | 40 | 41 | Task 42 | -------- 43 | .. automodule:: bootstrapvz.base.task 44 | :members: 45 | :private-members: 46 | 47 | 48 | Phase 49 | -------- 50 | .. automodule:: bootstrapvz.base.phase 51 | :members: 52 | :private-members: 53 | -------------------------------------------------------------------------------- /docs/api/base/pkg.rst: -------------------------------------------------------------------------------- 1 | 2 | Package handling 3 | ================ 4 | 5 | 6 | Package list 7 | ------------ 8 | .. automodule:: bootstrapvz.base.pkg.packagelist 9 | :members: 10 | :private-members: 11 | 12 | Sources list 13 | ------------ 14 | .. automodule:: bootstrapvz.base.pkg.sourceslist 15 | :members: 16 | :private-members: 17 | 18 | Preferences list 19 | ---------------- 20 | .. automodule:: bootstrapvz.base.pkg.preferenceslist 21 | :members: 22 | :private-members: 23 | 24 | Exceptions 25 | ---------- 26 | .. automodule:: bootstrapvz.base.pkg.exceptions 27 | :members: 28 | :private-members: 29 | -------------------------------------------------------------------------------- /docs/api/common/fs.rst: -------------------------------------------------------------------------------- 1 | 2 | Volume representations 3 | ============================= 4 | -------------------------------------------------------------------------------- /docs/api/common/index.rst: -------------------------------------------------------------------------------- 1 | 2 | Common 3 | ====== 4 | 5 | The common module contains features that are common to multiple providers and plugins. 6 | It holds both a large set of shared tasks and also various tools that are used by both 7 | the base module and tasks. 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | 12 | fs 13 | tasks/index 14 | -------------------------------------------------------------------------------- /docs/api/common/tasks/index.rst: -------------------------------------------------------------------------------- 1 | 2 | Shared tasks 3 | ============ 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | -------------------------------------------------------------------------------- /docs/api/index.rst: -------------------------------------------------------------------------------- 1 | API 2 | === 3 | 4 | 5 | .. toctree:: 6 | :maxdepth: 1 7 | :hidden: 8 | 9 | base/index 10 | common/index 11 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../CHANGELOG.rst 2 | -------------------------------------------------------------------------------- /docs/developers/contributing.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../../CONTRIBUTING.rst 2 | -------------------------------------------------------------------------------- /docs/developers/documentation.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../README.rst 2 | -------------------------------------------------------------------------------- /docs/developers/index.rst: -------------------------------------------------------------------------------- 1 | Developers 2 | ========== 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | :hidden: 7 | 8 | contributing 9 | plugins 10 | documentation 11 | switches 12 | taskoverview 13 | 14 | .. include:: ../../bootstrapvz/README.rst 15 | -------------------------------------------------------------------------------- /docs/developers/switches.rst: -------------------------------------------------------------------------------- 1 | 2 | Commandline switches 3 | ==================== 4 | As a developer, there are commandline switches available which can 5 | make your life a lot easier. 6 | 7 | + ``--debug``: Enables debug output in the console. This includes output 8 | from all commands that are invoked during bootstrapping. 9 | + ``--pause-on-error``: Pauses the execution when an exception occurs 10 | before rolling back. This allows you to debug by inspecting the volume 11 | at the time the error occurred. 12 | + ``--dry-run``: Prevents the ``run()`` function from being called on all 13 | tasks. This is useful if you want to see whether the task order is 14 | correct. 15 | -------------------------------------------------------------------------------- /docs/developers/taskoverview.rst: -------------------------------------------------------------------------------- 1 | 2 | Taskoverview 3 | ============ 4 | 5 | .. raw:: html 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. toctree:: 2 | :maxdepth: 1 3 | :hidden: 4 | 5 | self 6 | manifests/index 7 | providers/index 8 | plugins/index 9 | supported_builds 10 | logging 11 | remote_bootstrapping 12 | changelog 13 | developers/index 14 | api/index 15 | testing/index 16 | 17 | .. include:: ../README.rst 18 | -------------------------------------------------------------------------------- /docs/logging.rst: -------------------------------------------------------------------------------- 1 | 2 | Logfile 3 | ======= 4 | Every run creates a new logfile in the ``logs/`` directory. The filename 5 | for each run consists of a timestamp (``%Y%m%d%H%M%S``) and the basename 6 | of the manifest used. The log also contains debugging statements 7 | regardless of whether the ``--debug`` switch was used. 8 | -------------------------------------------------------------------------------- /docs/manifests/index.rst: -------------------------------------------------------------------------------- 1 | Manifests 2 | ========= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | :hidden: 7 | 8 | official_ec2_manifests 9 | official_gce_manifests 10 | 11 | .. include:: ../../manifests/README.rst 12 | -------------------------------------------------------------------------------- /docs/manifests/official_ec2_manifests.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../../manifests/official/ec2/README.rst 2 | -------------------------------------------------------------------------------- /docs/manifests/official_gce_manifests.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../../manifests/official/gce/README.rst 2 | -------------------------------------------------------------------------------- /docs/plugins/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !index.rst 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /docs/plugins/index.rst: -------------------------------------------------------------------------------- 1 | Plugins 2 | ======= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | :hidden: 7 | :glob: 8 | 9 | * 10 | 11 | .. include:: ../../bootstrapvz/plugins/README.rst 12 | -------------------------------------------------------------------------------- /docs/providers/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !index.rst 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /docs/providers/index.rst: -------------------------------------------------------------------------------- 1 | Providers 2 | ========= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | :hidden: 7 | :glob: 8 | 9 | * 10 | 11 | .. include:: ../../bootstrapvz/providers/README.rst 12 | -------------------------------------------------------------------------------- /docs/remote_bootstrapping.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../bootstrapvz/remote/README.rst 2 | -------------------------------------------------------------------------------- /docs/testing/index.rst: -------------------------------------------------------------------------------- 1 | Testing 2 | ======= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | :hidden: 7 | 8 | unit_tests 9 | system_tests 10 | system_test_providers/index 11 | 12 | .. include:: ../../tests/README.rst 13 | -------------------------------------------------------------------------------- /docs/testing/system_test_providers/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !index.rst 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /docs/testing/system_test_providers/index.rst: -------------------------------------------------------------------------------- 1 | System test providers 2 | ===================== 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | :glob: 7 | 8 | * 9 | 10 | .. include:: ../../../tests/system/providers/README.rst 11 | -------------------------------------------------------------------------------- /docs/testing/system_tests.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../../tests/system/README.rst 2 | -------------------------------------------------------------------------------- /docs/testing/unit_tests.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../../tests/unit/README.rst 2 | -------------------------------------------------------------------------------- /manifests/examples/azure/jessie.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%y}{%m}{%d} 3 | provider: 4 | name: azure 5 | waagent: 6 | version: 2.0.14 7 | bootstrapper: 8 | mirror: http://deb.debian.org/debian/ 9 | workspace: /target 10 | system: 11 | release: jessie 12 | architecture: amd64 13 | bootloader: grub 14 | charmap: UTF-8 15 | locale: en_US 16 | timezone: UTC 17 | volume: 18 | backing: vhd 19 | partitions: 20 | type: msdos 21 | root: 22 | filesystem: ext4 23 | size: 10GiB 24 | packages: 25 | components: 26 | - main 27 | - contrib 28 | - non-free 29 | plugins: 30 | ntp: 31 | servers: 32 | - time.windows.com 33 | -------------------------------------------------------------------------------- /manifests/examples/azure/wheezy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%y}{%m}{%d} 3 | provider: 4 | name: azure 5 | waagent: 6 | version: 2.0.14 7 | bootstrapper: 8 | mirror: http://deb.debian.org/debian/ 9 | workspace: /target 10 | system: 11 | release: wheezy 12 | architecture: amd64 13 | bootloader: grub 14 | charmap: UTF-8 15 | locale: en_US 16 | timezone: UTC 17 | volume: 18 | backing: vhd 19 | partitions: 20 | type: msdos 21 | root: 22 | filesystem: ext4 23 | size: 10GiB 24 | packages: 25 | components: 26 | - main 27 | - contrib 28 | - non-free 29 | preferences: 30 | backport-kernel: 31 | - package: linux-image-* initramfs-tools 32 | pin: release n=wheezy-backports 33 | pin-priority: 500 34 | plugins: 35 | ntp: 36 | servers: 37 | - time.windows.com 38 | -------------------------------------------------------------------------------- /manifests/examples/docker/jessie-minimized.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}:latest 3 | provider: 4 | name: docker 5 | labels: 6 | summary: Debian {system.release} {system.architecture} 7 | description: >- 8 | Minimized version of Debian jessie 9 | without any manpages, additional documentation 10 | or other language files. 11 | Additional package installs: 12 | inetutils-ping (dep: netbase) and iproute2 13 | distribution-scope: public 14 | dockerfile: 15 | - CMD /bin/bash 16 | bootstrapper: 17 | workspace: /target 18 | variant: minbase 19 | system: 20 | release: jessie 21 | architecture: amd64 22 | bootloader: none 23 | charmap: UTF-8 24 | locale: en_US 25 | timezone: UTC 26 | packages: 27 | install: 28 | - inetutils-ping 29 | - iproute2 30 | volume: 31 | backing: folder 32 | partitions: 33 | type: none 34 | root: 35 | filesystem: ext4 36 | size: 1GiB 37 | plugins: 38 | minimize_size: 39 | apt: 40 | autoclean: true 41 | languages: [none] 42 | gzip_indexes: true 43 | autoremove_suggests: true 44 | dpkg: 45 | locales: [] 46 | exclude_docs: true 47 | -------------------------------------------------------------------------------- /manifests/examples/ec2/ebs-testing-amd64-pvm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{provider.virtualization}-{%Y}-{%m}-{%d}-ebs 3 | provider: 4 | name: ec2 5 | virtualization: pvm 6 | # credentials: 7 | # access-key: AFAKEACCESSKEYFORAWS 8 | # secret-key: thes3cr3tkeyf0ryourawsaccount/FS4d8Qdva 9 | description: Debian {system.release} {system.architecture} 10 | bootstrapper: 11 | workspace: /target 12 | 13 | system: 14 | release: testing 15 | architecture: amd64 16 | bootloader: pvgrub 17 | charmap: UTF-8 18 | locale: en_US 19 | timezone: UTC 20 | volume: 21 | backing: ebs 22 | partitions: 23 | type: none 24 | root: 25 | filesystem: ext4 26 | size: 8GiB 27 | packages: 28 | mirror: http://cloudfront.debian.net/debian 29 | plugins: 30 | cloud_init: 31 | metadata_sources: Ec2 32 | username: admin 33 | -------------------------------------------------------------------------------- /manifests/examples/ec2/ebs-unstable-amd64-pvm-contrib.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{provider.virtualization}-{%Y}-{%m}-{%d}-ebs 3 | provider: 4 | name: ec2 5 | virtualization: pvm 6 | # credentials: 7 | # access-key: AFAKEACCESSKEYFORAWS 8 | # secret-key: thes3cr3tkeyf0ryourawsaccount/FS4d8Qdva 9 | description: Debian {system.release} {system.architecture} 10 | bootstrapper: 11 | workspace: /target 12 | system: 13 | release: unstable 14 | architecture: amd64 15 | bootloader: pvgrub 16 | charmap: UTF-8 17 | locale: en_US 18 | timezone: UTC 19 | volume: 20 | backing: ebs 21 | partitions: 22 | type: none 23 | root: 24 | filesystem: ext4 25 | size: 8GiB 26 | packages: 27 | mirror: http://cloudfront.debian.net/debian 28 | components: 29 | - main 30 | - contrib 31 | - non-free 32 | plugins: 33 | cloud_init: 34 | metadata_sources: Ec2 35 | username: admin 36 | -------------------------------------------------------------------------------- /manifests/examples/ec2/ebs-unstable-amd64-pvm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{provider.virtualization}-{%Y}-{%m}-{%d}-ebs 3 | provider: 4 | name: ec2 5 | virtualization: pvm 6 | # credentials: 7 | # access-key: AFAKEACCESSKEYFORAWS 8 | # secret-key: thes3cr3tkeyf0ryourawsaccount/FS4d8Qdva 9 | description: Debian {system.release} {system.architecture} 10 | bootstrapper: 11 | workspace: /target 12 | system: 13 | release: unstable 14 | architecture: amd64 15 | bootloader: pvgrub 16 | charmap: UTF-8 17 | locale: en_US 18 | timezone: UTC 19 | volume: 20 | backing: ebs 21 | partitions: 22 | type: none 23 | root: 24 | filesystem: ext4 25 | size: 8GiB 26 | packages: 27 | mirror: http://cloudfront.debian.net/debian 28 | plugins: 29 | cloud_init: 30 | metadata_sources: Ec2 31 | username: admin 32 | -------------------------------------------------------------------------------- /manifests/examples/ec2/s3-wheezy-amd64-pvm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{provider.virtualization}-{%y}{%m}{%d} 3 | provider: 4 | name: ec2 5 | virtualization: pvm 6 | # credentials: 7 | # access-key: AFAKEACCESSKEYFORAWS 8 | # secret-key: thes3cr3tkeyf0ryourawsaccount/FS4d8Qdva 9 | # certificate: /path/to/your/certificate.pem 10 | # private-key: /path/to/your/private.key 11 | # user-id: arn:aws:iam::123456789012:user/iamuser 12 | description: Debian {system.release} {system.architecture} AMI 13 | bucket: debian-amis 14 | region: us-west-1 15 | bootstrapper: 16 | workspace: /target 17 | system: 18 | release: wheezy 19 | architecture: amd64 20 | bootloader: pvgrub 21 | charmap: UTF-8 22 | locale: en_US 23 | timezone: UTC 24 | volume: 25 | backing: s3 26 | partitions: 27 | type: none 28 | root: 29 | filesystem: ext4 30 | size: 4GiB 31 | packages: 32 | mirror: http://cloudfront.debian.net/debian 33 | -------------------------------------------------------------------------------- /manifests/examples/kvm/buster-cloudimg.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio 7 | - virtio_pci 8 | - virtio_balloon 9 | - virtio_blk 10 | - virtio_net 11 | - virtio_ring 12 | console: virtual 13 | bootstrapper: 14 | workspace: /target 15 | system: 16 | release: stretch 17 | architecture: amd64 18 | bootloader: grub 19 | charmap: UTF-8 20 | locale: en_US 21 | timezone: UTC 22 | packages: 23 | components: 24 | - main 25 | - contrib 26 | - non-free 27 | install_standard: true 28 | install: 29 | - task-ssh-server 30 | - cloud-init 31 | - cloud-utils 32 | volume: 33 | backing: qcow2 34 | partitions: 35 | type: msdos 36 | root: 37 | filesystem: ext4 38 | size: 2GiB 39 | mountopts: 40 | - defaults 41 | - noatime 42 | - errors=remount-ro 43 | plugins: 44 | minimize_size: 45 | zerofree: true 46 | shrink: qemu-img 47 | apt: 48 | autoclean: true 49 | -------------------------------------------------------------------------------- /manifests/examples/kvm/buster-console.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio_blk 7 | - virtio_net 8 | - virtio_ring 9 | console: virtual 10 | bootstrapper: 11 | workspace: /target 12 | system: 13 | release: stretch 14 | architecture: amd64 15 | bootloader: grub 16 | charmap: UTF-8 17 | locale: en_US 18 | timezone: UTC 19 | volume: 20 | backing: raw 21 | partitions: 22 | type: msdos 23 | root: 24 | filesystem: ext4 25 | size: 2GiB 26 | mountopts: 27 | - defaults 28 | - noatime 29 | - errors=remount-ro 30 | -------------------------------------------------------------------------------- /manifests/examples/kvm/buster-virtio-partitions.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio_pci 7 | - virtio_blk 8 | bootstrapper: 9 | workspace: /target 10 | system: 11 | release: stretch 12 | architecture: amd64 13 | bootloader: grub 14 | charmap: UTF-8 15 | locale: en_US 16 | timezone: UTC 17 | volume: 18 | backing: raw 19 | partitions: 20 | type: gpt 21 | boot: 22 | filesystem: ext2 23 | size: 1GiB 24 | swap: 25 | size: 128MiB 26 | root: 27 | filesystem: ext4 28 | size: 8GiB 29 | tmp: 30 | mountopts: 31 | - nodev 32 | - noexec 33 | - nosuid 34 | - journal_ioprio=3 35 | filesystem: ext4 36 | size: 1GiB 37 | mode: '1777' 38 | var: 39 | filesystem: ext4 40 | size: 1GiB 41 | var/tmp: 42 | filesystem: ext4 43 | size: 1GiB 44 | 45 | plugins: 46 | root_password: 47 | password: test 48 | -------------------------------------------------------------------------------- /manifests/examples/kvm/jessie-arm64-virtio.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio_pci 7 | - virtio_blk 8 | bootstrapper: 9 | workspace: /target 10 | system: 11 | release: jessie 12 | architecture: arm64 13 | bootloader: none 14 | charmap: UTF-8 15 | locale: en_US 16 | timezone: UTC 17 | volume: 18 | backing: raw 19 | partitions: 20 | type: msdos 21 | boot: 22 | filesystem: ext2 23 | size: 32MiB 24 | root: 25 | filesystem: ext4 26 | size: 864MiB 27 | swap: 28 | size: 128MiB 29 | packages: {} 30 | plugins: 31 | root_password: 32 | password: test 33 | -------------------------------------------------------------------------------- /manifests/examples/kvm/jessie-lvm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-lvm-example 3 | provider: 4 | name: kvm 5 | bootstrapper: 6 | workspace: /target 7 | system: 8 | release: jessie 9 | architecture: amd64 10 | bootloader: grub 11 | charmap: UTF-8 12 | locale: en_US 13 | timezone: UTC 14 | volume: 15 | backing: lvm 16 | logicalvolume: lvtest 17 | volumegroup: vgtest 18 | partitions: 19 | type: gpt 20 | root: 21 | filesystem: ext4 22 | size: 1GB 23 | packages: 24 | security: http://security.debian.org/ 25 | plugins: 26 | root_password: 27 | password: test 28 | -------------------------------------------------------------------------------- /manifests/examples/kvm/jessie-puppet.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio_pci 7 | - virtio_blk 8 | bootstrapper: 9 | workspace: /target 10 | system: 11 | release: jessie 12 | architecture: amd64 13 | bootloader: grub 14 | charmap: UTF-8 15 | locale: en_US 16 | timezone: UTC 17 | volume: 18 | backing: raw 19 | partitions: 20 | type: msdos 21 | root: 22 | filesystem: ext4 23 | size: 10GiB 24 | packages: 25 | install_standard: true 26 | mirror: http://httpredir.debian.org/debian 27 | install: 28 | # required to be pre-installed for proper puppet functioning of 29 | # puppetlabs-apt, it is also the primary puppet module 30 | - lsb-release 31 | plugins: 32 | # It is advisable to avoid running things as root, use a sudo account instead 33 | admin_user: 34 | username: administrator 35 | password: something 36 | # puppet plugin 37 | puppet: 38 | # The assets path MUST be ABSOLUTE on your project. 39 | assets: /your/absolute/path/to/etc/puppetlabs 40 | install_modules: 41 | - [puppetlabs-accounts] 42 | - [puppetlabs-apt] 43 | - [puppetlabs-concat, 3.0.0] 44 | - [puppetlabs-stdlib] 45 | - [puppetlabs-apache, 1.11.0] 46 | -------------------------------------------------------------------------------- /manifests/examples/kvm/jessie-qcow2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-qcow2-example 3 | provider: 4 | name: kvm 5 | bootstrapper: 6 | workspace: /target 7 | system: 8 | release: jessie 9 | architecture: amd64 10 | bootloader: grub 11 | charmap: UTF-8 12 | locale: en_US 13 | timezone: UTC 14 | volume: 15 | backing: qcow2 16 | partitions: 17 | type: gpt 18 | root: 19 | filesystem: ext4 20 | size: 1GB 21 | packages: {} 22 | plugins: 23 | root_password: 24 | password: test 25 | -------------------------------------------------------------------------------- /manifests/examples/kvm/jessie-virtio.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio_pci 7 | - virtio_blk 8 | bootstrapper: 9 | workspace: /target 10 | system: 11 | release: jessie 12 | architecture: amd64 13 | bootloader: grub 14 | charmap: UTF-8 15 | locale: en_US 16 | timezone: UTC 17 | volume: 18 | backing: raw 19 | partitions: 20 | type: msdos 21 | root: 22 | filesystem: ext4 23 | size: 8GiB 24 | plugins: 25 | root_password: 26 | password: test 27 | -------------------------------------------------------------------------------- /manifests/examples/kvm/stretch-cloudimg.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio 7 | - virtio_pci 8 | - virtio_balloon 9 | - virtio_blk 10 | - virtio_net 11 | - virtio_ring 12 | console: virtual 13 | bootstrapper: 14 | workspace: /target 15 | system: 16 | release: stretch 17 | architecture: amd64 18 | bootloader: grub 19 | charmap: UTF-8 20 | locale: en_US 21 | timezone: UTC 22 | packages: 23 | components: 24 | - main 25 | - contrib 26 | - non-free 27 | install_standard: true 28 | install: 29 | - task-ssh-server 30 | - cloud-init 31 | - cloud-utils 32 | volume: 33 | backing: qcow2 34 | partitions: 35 | type: msdos 36 | root: 37 | filesystem: ext4 38 | size: 2GiB 39 | mountopts: 40 | - defaults 41 | - noatime 42 | - errors=remount-ro 43 | plugins: 44 | minimize_size: 45 | zerofree: true 46 | shrink: qemu-img 47 | apt: 48 | autoclean: true 49 | -------------------------------------------------------------------------------- /manifests/examples/kvm/stretch-console.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio_blk 7 | - virtio_net 8 | - virtio_ring 9 | console: virtual 10 | bootstrapper: 11 | workspace: /target 12 | system: 13 | release: stretch 14 | architecture: amd64 15 | bootloader: grub 16 | charmap: UTF-8 17 | locale: en_US 18 | timezone: UTC 19 | volume: 20 | backing: raw 21 | partitions: 22 | type: msdos 23 | root: 24 | filesystem: ext4 25 | size: 2GiB 26 | mountopts: 27 | - defaults 28 | - noatime 29 | - errors=remount-ro 30 | -------------------------------------------------------------------------------- /manifests/examples/kvm/stretch-puppet.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio_pci 7 | - virtio_blk 8 | bootstrapper: 9 | workspace: /target 10 | system: 11 | release: stretch 12 | architecture: amd64 13 | bootloader: grub 14 | charmap: UTF-8 15 | locale: en_US 16 | timezone: UTC 17 | volume: 18 | backing: raw 19 | partitions: 20 | type: msdos 21 | root: 22 | filesystem: ext4 23 | size: 10GiB 24 | packages: 25 | install_standard: true 26 | mirror: http://httpredir.debian.org/debian 27 | install: 28 | # required to be pre-installed for proper puppet functioning of 29 | # puppetlabs-apt, it is also the primary puppet module 30 | - lsb-release 31 | plugins: 32 | # It is advisable to avoid running things as root, use a sudo account instead 33 | admin_user: 34 | username: administrator 35 | password: something 36 | # puppet plugin 37 | puppet: 38 | # The assets path MUST be ABSOLUTE on your project. 39 | assets: /your/absolute/path/to/etc/puppetlabs 40 | install_modules: 41 | - [puppetlabs-accounts] 42 | - [puppetlabs-apt] 43 | - [puppetlabs-concat, 3.0.0] 44 | - [puppetlabs-stdlib] 45 | - [puppetlabs-apache, 1.11.0] 46 | -------------------------------------------------------------------------------- /manifests/examples/kvm/stretch-virtio-partitions.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio_pci 7 | - virtio_blk 8 | bootstrapper: 9 | workspace: /target 10 | system: 11 | release: stretch 12 | architecture: amd64 13 | bootloader: grub 14 | charmap: UTF-8 15 | locale: en_US 16 | timezone: UTC 17 | volume: 18 | backing: raw 19 | partitions: 20 | type: gpt 21 | boot: 22 | filesystem: ext2 23 | size: 1GiB 24 | swap: 25 | size: 128MiB 26 | root: 27 | filesystem: ext4 28 | size: 8GiB 29 | tmp: 30 | mountopts: 31 | - nodev 32 | - noexec 33 | - nosuid 34 | - journal_ioprio=3 35 | filesystem: ext4 36 | size: 1GiB 37 | mode: '1777' 38 | var: 39 | filesystem: ext4 40 | size: 1GiB 41 | var/tmp: 42 | filesystem: ext4 43 | size: 1GiB 44 | 45 | plugins: 46 | root_password: 47 | password: test 48 | -------------------------------------------------------------------------------- /manifests/examples/kvm/wheezy-virtio.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | virtio: 6 | - virtio_pci 7 | - virtio_blk 8 | bootstrapper: 9 | workspace: /target 10 | system: 11 | release: wheezy 12 | architecture: amd64 13 | bootloader: grub 14 | charmap: UTF-8 15 | locale: en_US 16 | timezone: UTC 17 | volume: 18 | backing: raw 19 | partitions: 20 | type: msdos 21 | boot: 22 | filesystem: ext2 23 | size: 32MiB 24 | root: 25 | filesystem: ext4 26 | size: 864MiB 27 | swap: 28 | size: 128MiB 29 | packages: {} 30 | plugins: 31 | root_password: 32 | password: test 33 | -------------------------------------------------------------------------------- /manifests/examples/kvm/wheezy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%y}{%m}{%d} 3 | provider: 4 | name: kvm 5 | bootstrapper: 6 | workspace: /target 7 | system: 8 | release: wheezy 9 | architecture: amd64 10 | bootloader: grub 11 | charmap: UTF-8 12 | locale: en_US 13 | timezone: UTC 14 | volume: 15 | backing: raw 16 | partitions: 17 | type: msdos 18 | boot: 19 | filesystem: ext2 20 | size: 32MiB 21 | root: 22 | filesystem: ext4 23 | size: 864MiB 24 | swap: 25 | size: 128MiB 26 | packages: {} 27 | plugins: 28 | root_password: 29 | password: test 30 | -------------------------------------------------------------------------------- /manifests/examples/virtualbox/jessie-vagrant.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%y}{%m}{%d} 3 | provider: 4 | name: virtualbox 5 | guest_additions: /usr/share/virtualbox/VBoxGuestAdditions.iso 6 | bootstrapper: 7 | workspace: /target 8 | system: 9 | release: jessie 10 | architecture: amd64 11 | bootloader: grub 12 | charmap: UTF-8 13 | hostname: localhost 14 | locale: en_US 15 | timezone: UTC 16 | volume: 17 | backing: vmdk 18 | partitions: 19 | type: msdos 20 | boot: 21 | filesystem: ext2 22 | size: 64MiB 23 | root: 24 | filesystem: ext4 25 | size: 1856MiB 26 | swap: 27 | size: 128MiB 28 | packages: {} 29 | plugins: 30 | vagrant: {} 31 | -------------------------------------------------------------------------------- /manifests/examples/virtualbox/stretch-vagrant.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%y}{%m}{%d} 3 | provider: 4 | name: virtualbox 5 | guest_additions: /usr/share/virtualbox/VBoxGuestAdditions.iso 6 | bootstrapper: 7 | workspace: /target 8 | system: 9 | release: stretch 10 | architecture: amd64 11 | bootloader: grub 12 | charmap: UTF-8 13 | hostname: localhost 14 | locale: en_US 15 | timezone: UTC 16 | volume: 17 | backing: vmdk 18 | partitions: 19 | type: msdos 20 | boot: 21 | filesystem: ext2 22 | size: 64MiB 23 | root: 24 | filesystem: ext4 25 | size: 1856MiB 26 | swap: 27 | size: 128MiB 28 | packages: {} 29 | plugins: 30 | vagrant: {} 31 | root_password: 32 | password-crypted: $6$MU3jLtZHS$UHdibqwOJrZw5yI7cqzG.AnzWqOVD9krryd3Y/SgXDSHUEMsaT7iAiQHhuCpjN4Q0tEssbJYoy4H1QFxOY3Tc/ 33 | -------------------------------------------------------------------------------- /manifests/examples/virtualbox/wheezy-vagrant.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%y}{%m}{%d} 3 | provider: 4 | name: virtualbox 5 | guest_additions: /usr/share/virtualbox/VBoxGuestAdditions.iso 6 | bootstrapper: 7 | workspace: /target 8 | system: 9 | release: wheezy 10 | architecture: amd64 11 | bootloader: grub 12 | charmap: UTF-8 13 | hostname: localhost 14 | locale: en_US 15 | timezone: UTC 16 | volume: 17 | backing: vmdk 18 | partitions: 19 | type: msdos 20 | boot: 21 | filesystem: ext2 22 | size: 64MiB 23 | root: 24 | filesystem: ext4 25 | size: 1856MiB 26 | swap: 27 | size: 128MiB 28 | packages: {} 29 | plugins: 30 | vagrant: {} 31 | -------------------------------------------------------------------------------- /manifests/examples/virtualbox/wheezy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%y}{%m}{%d} 3 | provider: 4 | name: virtualbox 5 | guest_additions: /usr/share/virtualbox/VBoxGuestAdditions.iso 6 | bootstrapper: 7 | workspace: /target 8 | system: 9 | release: wheezy 10 | architecture: amd64 11 | bootloader: grub 12 | charmap: UTF-8 13 | locale: en_US 14 | timezone: UTC 15 | volume: 16 | backing: vdi 17 | partitions: 18 | type: msdos 19 | boot: 20 | filesystem: ext2 21 | size: 32MiB 22 | root: 23 | filesystem: ext4 24 | size: 864MiB 25 | swap: 26 | size: 128MiB 27 | packages: {} 28 | -------------------------------------------------------------------------------- /manifests/official/ec2/README.rst: -------------------------------------------------------------------------------- 1 | Official EC2 manifests 2 | ====================== 3 | 4 | The official Debian images for EC2 are built with bootstrap-vz. 5 | In the folder ``manifests/official/ec2`` you will find the various manifests 6 | that are used to create the different flavors of Debian AMIs for EC2. 7 | 8 | You can read more about those official images in the `Debian wiki`__. 9 | 10 | .. __: https://wiki.debian.org/Cloud/AmazonEC2Image/ 11 | 12 | The official images can be found on the `AWS marketplace`__. 13 | 14 | .. __: https://aws.amazon.com/marketplace/seller-profile?id=890be55d-32d8-4bc8-9042-2b4fd83064d5 15 | -------------------------------------------------------------------------------- /manifests/official/ec2/ebs-wheezy-amd64-hvm-cn-north-1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{provider.virtualization}-{%Y}-{%m}-{%d}-ebs 3 | provider: 4 | name: ec2 5 | virtualization: hvm 6 | enhanced_networking: simple 7 | # credentials: 8 | # access-key: AFAKEACCESSKEYFORAWS 9 | # secret-key: thes3cr3tkeyf0ryourawsaccount/FS4d8Qdva 10 | description: Debian {system.release} {system.architecture} 11 | bootstrapper: 12 | workspace: /target 13 | system: 14 | release: wheezy 15 | architecture: amd64 16 | bootloader: extlinux 17 | charmap: UTF-8 18 | locale: en_US 19 | timezone: UTC 20 | volume: 21 | backing: ebs 22 | partitions: 23 | type: none 24 | root: 25 | filesystem: ext4 26 | size: 8GiB 27 | packages: 28 | mirror: http://ftp.cn.debian.org/debian 29 | plugins: 30 | cloud_init: 31 | metadata_sources: Ec2 32 | username: admin 33 | -------------------------------------------------------------------------------- /manifests/official/ec2/ebs-wheezy-amd64-hvm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{provider.virtualization}-{%Y}-{%m}-{%d}-ebs 3 | provider: 4 | name: ec2 5 | virtualization: hvm 6 | enhanced_networking: simple 7 | # credentials: 8 | # access-key: AFAKEACCESSKEYFORAWS 9 | # secret-key: thes3cr3tkeyf0ryourawsaccount/FS4d8Qdva 10 | description: Debian {system.release} {system.architecture} 11 | bootstrapper: 12 | workspace: /target 13 | system: 14 | release: wheezy 15 | architecture: amd64 16 | bootloader: extlinux 17 | charmap: UTF-8 18 | locale: en_US 19 | timezone: UTC 20 | volume: 21 | backing: ebs 22 | partitions: 23 | type: none 24 | root: 25 | filesystem: ext4 26 | size: 8GiB 27 | packages: 28 | mirror: http://cloudfront.debian.net/debian 29 | plugins: 30 | cloud_init: 31 | metadata_sources: Ec2 32 | username: admin 33 | -------------------------------------------------------------------------------- /manifests/official/ec2/ebs-wheezy-amd64-pvm-cn-north-1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{provider.virtualization}-{%Y}-{%m}-{%d}-ebs 3 | provider: 4 | name: ec2 5 | virtualization: pvm 6 | # credentials: 7 | # access-key: AFAKEACCESSKEYFORAWS 8 | # secret-key: thes3cr3tkeyf0ryourawsaccount/FS4d8Qdva 9 | description: Debian {system.release} {system.architecture} 10 | bootstrapper: 11 | workspace: /target 12 | system: 13 | release: wheezy 14 | architecture: amd64 15 | bootloader: pvgrub 16 | charmap: UTF-8 17 | locale: en_US 18 | timezone: UTC 19 | volume: 20 | backing: ebs 21 | partitions: 22 | type: none 23 | root: 24 | filesystem: ext4 25 | size: 8GiB 26 | packages: 27 | mirror: http://ftp.cn.debian.org/debian 28 | plugins: 29 | cloud_init: 30 | metadata_sources: Ec2 31 | username: admin 32 | -------------------------------------------------------------------------------- /manifests/official/ec2/ebs-wheezy-amd64-pvm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{provider.virtualization}-{%Y}-{%m}-{%d}-ebs 3 | provider: 4 | name: ec2 5 | virtualization: pvm 6 | # credentials: 7 | # access-key: AFAKEACCESSKEYFORAWS 8 | # secret-key: thes3cr3tkeyf0ryourawsaccount/FS4d8Qdva 9 | description: Debian {system.release} {system.architecture} 10 | bootstrapper: 11 | workspace: /target 12 | system: 13 | release: wheezy 14 | architecture: amd64 15 | bootloader: pvgrub 16 | charmap: UTF-8 17 | locale: en_US 18 | timezone: UTC 19 | volume: 20 | backing: ebs 21 | partitions: 22 | type: none 23 | root: 24 | filesystem: ext4 25 | size: 8GiB 26 | packages: 27 | mirror: http://cloudfront.debian.net/debian 28 | plugins: 29 | cloud_init: 30 | metadata_sources: Ec2 31 | username: admin 32 | -------------------------------------------------------------------------------- /manifests/official/ec2/ebs-wheezy-i386-pvm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{provider.virtualization}-{%Y}-{%m}-{%d}-ebs 3 | provider: 4 | name: ec2 5 | virtualization: pvm 6 | # credentials: 7 | # access-key: AFAKEACCESSKEYFORAWS 8 | # secret-key: thes3cr3tkeyf0ryourawsaccount/FS4d8Qdva 9 | description: Debian {system.release} {system.architecture} 10 | bootstrapper: 11 | workspace: /target 12 | system: 13 | release: wheezy 14 | architecture: i386 15 | bootloader: pvgrub 16 | charmap: UTF-8 17 | locale: en_US 18 | timezone: UTC 19 | volume: 20 | backing: ebs 21 | partitions: 22 | type: none 23 | root: 24 | filesystem: ext4 25 | size: 8GiB 26 | packages: 27 | mirror: http://cloudfront.debian.net/debian 28 | plugins: 29 | cloud_init: 30 | metadata_sources: Ec2 31 | username: admin 32 | -------------------------------------------------------------------------------- /manifests/official/ec2/s3-wheezy-amd64-pvm-cn-north-1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{provider.virtualization}-{%Y}-{%m}-{%d} 3 | provider: 4 | name: ec2 5 | virtualization: pvm 6 | # credentials: 7 | # access-key: AFAKEACCESSKEYFORAWS 8 | # secret-key: thes3cr3tkeyf0ryourawsaccount/FS4d8Qdva 9 | # certificate: /path/to/your/certificate.pem 10 | # private-key: /path/to/your/private.key 11 | # user-id: arn:aws:iam::123456789012:user/iamuser 12 | description: Debian {system.release} {system.architecture} AMI 13 | bucket: debian-amis-cn-north-1 14 | region: cn-north-1 15 | bootstrapper: 16 | workspace: /target 17 | system: 18 | release: wheezy 19 | architecture: amd64 20 | bootloader: pvgrub 21 | charmap: UTF-8 22 | locale: en_US 23 | timezone: UTC 24 | volume: 25 | backing: s3 26 | partitions: 27 | type: none 28 | root: 29 | filesystem: ext4 30 | size: 4GiB 31 | packages: 32 | mirror: http://ftp.cn.debian.org/debian 33 | plugins: 34 | cloud_init: 35 | disable_modules: 36 | - landscape 37 | - byobu 38 | - ssh-import-id 39 | username: admin 40 | -------------------------------------------------------------------------------- /manifests/official/gce/buster-minimal.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: disk 3 | provider: 4 | name: gce 5 | description: Debian {system.release} {system.architecture} 6 | bootstrapper: 7 | workspace: /target 8 | system: 9 | release: buster 10 | architecture: amd64 11 | bootloader: grub 12 | charmap: UTF-8 13 | locale: en_US 14 | timezone: UTC 15 | volume: 16 | backing: raw 17 | partitions: 18 | type: msdos 19 | root: 20 | filesystem: ext4 21 | size: 10GiB 22 | packages: 23 | include-source-type: true 24 | sources: 25 | google-cloud: 26 | - deb http://packages.cloud.google.com/apt google-compute-engine-{system.release}-stable main 27 | install: 28 | - google-compute-engine 29 | - python-google-compute-engine 30 | - python3-google-compute-engine 31 | plugins: 32 | google_cloud_repo: 33 | cleanup_bootstrap_key: true 34 | enable_keyring_repo: true 35 | ntp: 36 | servers: 37 | - metadata.google.internal 38 | -------------------------------------------------------------------------------- /manifests/official/gce/buster.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: disk 3 | provider: 4 | name: gce 5 | description: Debian {system.release} {system.architecture} 6 | bootstrapper: 7 | workspace: /target 8 | system: 9 | release: buster 10 | architecture: amd64 11 | bootloader: grub 12 | charmap: UTF-8 13 | locale: en_US 14 | timezone: UTC 15 | volume: 16 | backing: raw 17 | partitions: 18 | type: msdos 19 | root: 20 | filesystem: ext4 21 | size: 10GiB 22 | packages: 23 | include-source-type: true 24 | sources: 25 | google-cloud: 26 | - deb http://packages.cloud.google.com/apt cloud-sdk-{system.release} main 27 | - deb http://packages.cloud.google.com/apt google-compute-engine-{system.release}-stable main 28 | install: 29 | - file 30 | - google-cloud-sdk 31 | - google-compute-engine 32 | - python-google-compute-engine 33 | - python3-google-compute-engine 34 | - man 35 | - net-tools 36 | - python-crcmod 37 | - screen 38 | - vim 39 | plugins: 40 | expand_root: 41 | filesystem_type: ext4 42 | root_device: /dev/sda 43 | root_partition: 1 44 | google_cloud_repo: 45 | cleanup_bootstrap_key: true 46 | enable_keyring_repo: true 47 | ntp: 48 | servers: 49 | - metadata.google.internal 50 | unattended_upgrades: 51 | download_interval: 1 52 | update_interval: 1 53 | upgrade_interval: 1 54 | -------------------------------------------------------------------------------- /manifests/official/gce/deprecated/wheezy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: disk 3 | provider: 4 | name: gce 5 | description: Debian {system.release} {system.architecture} 6 | bootstrapper: 7 | workspace: /target 8 | system: 9 | release: wheezy 10 | architecture: amd64 11 | bootloader: grub 12 | charmap: UTF-8 13 | locale: en_US 14 | timezone: UTC 15 | volume: 16 | backing: raw 17 | partitions: 18 | type: msdos 19 | root: 20 | filesystem: ext4 21 | size: 10GiB 22 | packages: 23 | sources: 24 | google-cloud: 25 | - deb http://packages.cloud.google.com/apt cloud-sdk-{system.release} main 26 | - deb http://packages.cloud.google.com/apt google-cloud-compute-legacy-{system.release} main 27 | install: 28 | - google-cloud-sdk 29 | - google-compute-daemon 30 | - google-startup-scripts 31 | - python-gcimagebundle 32 | - rsync 33 | - screen 34 | - vim 35 | plugins: 36 | google_cloud_repo: 37 | cleanup_bootstrap_key: true 38 | enable_keyring_repo: true 39 | ntp: 40 | servers: 41 | - metadata.google.internal 42 | -------------------------------------------------------------------------------- /manifests/official/gce/jessie-minimal.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: disk 3 | provider: 4 | name: gce 5 | description: Debian {system.release} {system.architecture} 6 | bootstrapper: 7 | workspace: /target 8 | system: 9 | release: jessie 10 | architecture: amd64 11 | bootloader: grub 12 | charmap: UTF-8 13 | locale: en_US 14 | timezone: UTC 15 | volume: 16 | backing: raw 17 | partitions: 18 | type: msdos 19 | root: 20 | filesystem: ext4 21 | size: 10GiB 22 | packages: 23 | include-source-type: true 24 | sources: 25 | google-cloud: 26 | - deb http://packages.cloud.google.com/apt google-compute-engine-{system.release}-stable main 27 | install: 28 | - google-compute-engine 29 | - python-google-compute-engine 30 | - python3-google-compute-engine 31 | plugins: 32 | google_cloud_repo: 33 | cleanup_bootstrap_key: true 34 | enable_keyring_repo: true 35 | ntp: 36 | servers: 37 | - metadata.google.internal 38 | -------------------------------------------------------------------------------- /manifests/official/gce/stretch-minimal.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: disk 3 | provider: 4 | name: gce 5 | description: Debian {system.release} {system.architecture} 6 | bootstrapper: 7 | workspace: /target 8 | system: 9 | release: stretch 10 | architecture: amd64 11 | bootloader: grub 12 | charmap: UTF-8 13 | locale: en_US 14 | timezone: UTC 15 | volume: 16 | backing: raw 17 | partitions: 18 | type: msdos 19 | root: 20 | filesystem: ext4 21 | size: 10GiB 22 | packages: 23 | include-source-type: true 24 | sources: 25 | google-cloud: 26 | - deb http://packages.cloud.google.com/apt google-compute-engine-{system.release}-stable main 27 | install: 28 | - google-compute-engine 29 | - python-google-compute-engine 30 | - python3-google-compute-engine 31 | plugins: 32 | google_cloud_repo: 33 | cleanup_bootstrap_key: true 34 | enable_keyring_repo: true 35 | ntp: 36 | servers: 37 | - metadata.google.internal 38 | -------------------------------------------------------------------------------- /manifests/official/gce/stretch.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: disk 3 | provider: 4 | name: gce 5 | description: Debian {system.release} {system.architecture} 6 | bootstrapper: 7 | workspace: /target 8 | system: 9 | release: stretch 10 | architecture: amd64 11 | bootloader: grub 12 | charmap: UTF-8 13 | locale: en_US 14 | timezone: UTC 15 | volume: 16 | backing: raw 17 | partitions: 18 | type: msdos 19 | root: 20 | filesystem: ext4 21 | size: 10GiB 22 | packages: 23 | include-source-type: true 24 | sources: 25 | google-cloud: 26 | - deb http://packages.cloud.google.com/apt cloud-sdk-{system.release} main 27 | - deb http://packages.cloud.google.com/apt google-compute-engine-{system.release}-stable main 28 | install: 29 | - file 30 | - google-cloud-sdk 31 | - google-compute-engine 32 | - python-google-compute-engine 33 | - python3-google-compute-engine 34 | - man 35 | - net-tools 36 | - python-crcmod 37 | - screen 38 | - vim 39 | plugins: 40 | expand_root: 41 | filesystem_type: ext4 42 | root_device: /dev/sda 43 | root_partition: 1 44 | google_cloud_repo: 45 | cleanup_bootstrap_key: true 46 | enable_keyring_repo: true 47 | ntp: 48 | servers: 49 | - metadata.google.internal 50 | unattended_upgrades: 51 | download_interval: 1 52 | update_interval: 1 53 | upgrade_interval: 1 54 | -------------------------------------------------------------------------------- /manifests/official/oracle/jessie.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: debian-{system.release}-{system.architecture}-{%Y}{%m}{%d} 3 | provider: 4 | name: oracle 5 | bootstrapper: 6 | workspace: /target 7 | system: 8 | release: jessie 9 | architecture: amd64 10 | bootloader: grub 11 | charmap: UTF-8 12 | locale: en_US 13 | timezone: UTC 14 | volume: 15 | backing: raw 16 | partitions: 17 | type: msdos 18 | root: 19 | filesystem: ext4 20 | size: 8GiB 21 | plugins: 22 | cloud_init: 23 | username: opc 24 | metadata_sources: Ec2 25 | -------------------------------------------------------------------------------- /tests/README.rst: -------------------------------------------------------------------------------- 1 | The testing framework consists of two parts: 2 | The unit tests and the integration tests. 3 | 4 | The `unit tests `__ are responsible for testing individual 5 | parts of bootstrap-vz, while the `integration tests `__ test 6 | entire manifests by bootstrapping and booting them. 7 | 8 | Selecting tests 9 | --------------- 10 | To run one specific test suite simply append the module path to tox: 11 | 12 | .. code-block:: sh 13 | 14 | $ tox -e unit tests.unit.releases_tests 15 | 16 | Specific tests can be selected by appending the function name with a colon 17 | to the modulepath -- to run more than one tests, simply attach more arguments. 18 | 19 | 20 | .. code-block:: sh 21 | 22 | $ tox -e unit tests.unit.releases_tests:test_lt tests.unit.releases_tests:test_eq 23 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Snatched from: http://stackoverflow.com/a/2186565/339505 4 | def recursive_glob(path, pattern): 5 | import fnmatch 6 | import os 7 | for root, dirnames, filenames in os.walk(path): 8 | for filename in fnmatch.filter(filenames, pattern): 9 | yield os.path.join(root, filename) 10 | -------------------------------------------------------------------------------- /tests/integration/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/tests/integration/__init__.py -------------------------------------------------------------------------------- /tests/integration/dry_run_tests.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def test_manifest_generator(): 4 | """ 5 | manifests_tests - test_manifest_generator. 6 | 7 | Loops through the manifests directory and tests that 8 | each file can successfully be loaded and validated. 9 | """ 10 | 11 | from bootstrapvz.base.manifest import Manifest 12 | from bootstrapvz.base.main import run 13 | 14 | def dry_run(path): 15 | manifest = Manifest(path=path) 16 | run(manifest, dry_run=True) 17 | 18 | import os.path 19 | from .. import recursive_glob 20 | from itertools import chain 21 | manifests = os.path.join(os.path.dirname(os.path.realpath(__file__)), 22 | '../../manifests') 23 | manifest_paths = chain(recursive_glob(manifests, '*.yml'), recursive_glob(manifests, '*.json')) 24 | for manifest_path in manifest_paths: 25 | dry_run.description = "Dry-running %s" % os.path.relpath(manifest_path, manifests) 26 | yield dry_run, manifest_path 27 | -------------------------------------------------------------------------------- /tests/system/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/tests/system/__init__.py -------------------------------------------------------------------------------- /tests/system/docker_tests.py: -------------------------------------------------------------------------------- 1 | from .manifests import merge_manifest_data 2 | from .tools import boot_manifest 3 | 4 | partials = {'docker': ''' 5 | provider: 6 | name: docker 7 | virtualization: hvm 8 | dockerfile: CMD /bin/bash 9 | bootstrapper: 10 | variant: minbase 11 | system: 12 | bootloader: none 13 | volume: 14 | backing: folder 15 | partitions: 16 | type: none 17 | root: 18 | filesystem: ext4 19 | size: 1GiB 20 | ''', 21 | } 22 | 23 | 24 | def test_stable(): 25 | std_partials = ['base', 'stable64'] 26 | custom_partials = [partials['docker']] 27 | manifest_data = merge_manifest_data(std_partials, custom_partials) 28 | with boot_manifest(manifest_data) as instance: 29 | print('\n'.join(instance.run(['echo', 'test']))) # pylint: disable=print-statement 30 | -------------------------------------------------------------------------------- /tests/system/manifests/base.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: deb-{system.release}-{system.architecture}-{system.bootloader}-{volume.partitions.type}-{%y}{%m}{%d} 3 | provider: {} 4 | bootstrapper: 5 | workspace: /target 6 | tarball: true 7 | system: 8 | charmap: UTF-8 9 | locale: en_US 10 | timezone: UTC 11 | volume: 12 | partitions: {} 13 | packages: {} 14 | -------------------------------------------------------------------------------- /tests/system/manifests/extlinux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | system: 3 | bootloader: extlinux 4 | -------------------------------------------------------------------------------- /tests/system/manifests/gpt.yml: -------------------------------------------------------------------------------- 1 | --- 2 | volume: 3 | partitions: 4 | type: gpt 5 | -------------------------------------------------------------------------------- /tests/system/manifests/grub.yml: -------------------------------------------------------------------------------- 1 | --- 2 | system: 3 | bootloader: grub 4 | -------------------------------------------------------------------------------- /tests/system/manifests/msdos.yml: -------------------------------------------------------------------------------- 1 | --- 2 | volume: 3 | partitions: 4 | type: msdos 5 | -------------------------------------------------------------------------------- /tests/system/manifests/oldstable64.yml: -------------------------------------------------------------------------------- 1 | --- 2 | system: 3 | release: oldstable 4 | architecture: amd64 5 | -------------------------------------------------------------------------------- /tests/system/manifests/partitioned.yml: -------------------------------------------------------------------------------- 1 | --- 2 | volume: 3 | partitions: 4 | boot: 5 | filesystem: ext2 6 | size: 64MiB 7 | root: 8 | filesystem: ext4 9 | size: 832MiB 10 | swap: 11 | size: 128MiB 12 | -------------------------------------------------------------------------------- /tests/system/manifests/root_password.yml: -------------------------------------------------------------------------------- 1 | --- 2 | plugins: 3 | root_password: 4 | password: random password set by the partial manifest loader 5 | -------------------------------------------------------------------------------- /tests/system/manifests/single_partition.yml: -------------------------------------------------------------------------------- 1 | --- 2 | volume: 3 | partitions: 4 | root: 5 | filesystem: ext4 6 | size: 1GiB 7 | -------------------------------------------------------------------------------- /tests/system/manifests/stable64.yml: -------------------------------------------------------------------------------- 1 | --- 2 | system: 3 | release: stable 4 | architecture: amd64 5 | -------------------------------------------------------------------------------- /tests/system/manifests/stable86.yml: -------------------------------------------------------------------------------- 1 | --- 2 | system: 3 | release: stable 4 | architecture: x86 5 | -------------------------------------------------------------------------------- /tests/system/manifests/unpartitioned.yml: -------------------------------------------------------------------------------- 1 | --- 2 | volume: 3 | partitions: 4 | type: none 5 | root: 6 | filesystem: ext4 7 | size: 1GiB 8 | -------------------------------------------------------------------------------- /tests/system/manifests/unstable64.yml: -------------------------------------------------------------------------------- 1 | --- 2 | system: 3 | release: unstable 4 | architecture: amd64 5 | -------------------------------------------------------------------------------- /tests/system/providers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/tests/system/providers/__init__.py -------------------------------------------------------------------------------- /tests/system/providers/docker/README.rst: -------------------------------------------------------------------------------- 1 | Docker 2 | ------ 3 | 4 | 5 | Dependencies 6 | ~~~~~~~~~~~~ 7 | The host machine running the system tests must have docker installed. 8 | -------------------------------------------------------------------------------- /tests/system/providers/ec2/README.rst: -------------------------------------------------------------------------------- 1 | EC2 2 | --- 3 | 4 | Dependencies 5 | ~~~~~~~~~~~~ 6 | The host machine running the system tests must have the python package 7 | ``boto`` installed (``>= 2.14.0``). 8 | -------------------------------------------------------------------------------- /tests/system/providers/ec2/images.py: -------------------------------------------------------------------------------- 1 | import logging 2 | log = logging.getLogger(__name__) 3 | 4 | 5 | class AmazonMachineImage(object): 6 | 7 | def __init__(self, image_id, ec2_connection): 8 | self.ec2_connection = ec2_connection 9 | self.ami = self.ec2_connection.get_image(image_id) 10 | 11 | 12 | class EBSImage(AmazonMachineImage): 13 | 14 | def destroy(self): 15 | log.debug('Deleting AMI') 16 | self.ami.deregister() 17 | for device, block_device_type in self.ami.block_device_mapping.items(): 18 | self.ec2_connection.delete_snapshot(block_device_type.snapshot_id) 19 | del self.ami 20 | 21 | 22 | class S3Image(AmazonMachineImage): 23 | 24 | def destroy(self): 25 | log.debug('Deleting AMI') 26 | self.ami.deregister() 27 | del self.ami 28 | -------------------------------------------------------------------------------- /tests/system/providers/virtualbox/README.rst: -------------------------------------------------------------------------------- 1 | Virtualbox 2 | ---------- 3 | 4 | 5 | Dependencies 6 | ~~~~~~~~~~~~ 7 | VirtualBox itself is required on the machine that is 8 | running the system tests. The same machine also needs to 9 | have python package ``vboxapi`` (``>=1.0``) installed. 10 | -------------------------------------------------------------------------------- /tests/system/providers/virtualbox/image.py: -------------------------------------------------------------------------------- 1 | import virtualbox 2 | import logging 3 | log = logging.getLogger(__name__) 4 | 5 | 6 | class VirtualBoxImage(object): 7 | 8 | def __init__(self, image_path): 9 | self.image_path = image_path 10 | self.vbox = virtualbox.VirtualBox() 11 | 12 | def open(self): 13 | log.debug('Opening vbox medium `{path}\''.format(path=self.image_path)) 14 | self.medium = self.vbox.open_medium(self.image_path, # location 15 | virtualbox.library.DeviceType.hard_disk, # device_type 16 | virtualbox.library.AccessMode.read_only, # access_mode 17 | False) # force_new_uuid 18 | 19 | def close(self): 20 | log.debug('Closing vbox medium `{path}\''.format(path=self.image_path)) 21 | self.medium.close() 22 | 23 | def destroy(self): 24 | log.debug('Deleting vbox image `{path}\''.format(path=self.image_path)) 25 | import os 26 | os.remove(self.image_path) 27 | del self.image_path 28 | -------------------------------------------------------------------------------- /tests/system/tools/exceptions.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class SocketReadTimeout(Exception): 4 | pass 5 | -------------------------------------------------------------------------------- /tests/unit/README.rst: -------------------------------------------------------------------------------- 1 | Unit tests 2 | ========== 3 | -------------------------------------------------------------------------------- /tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andsens/bootstrap-vz/fcdc6993f59e521567fb101302b02312e741b88c/tests/unit/__init__.py -------------------------------------------------------------------------------- /tests/unit/manifests_tests.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def test_manifest_generator(): 4 | """ 5 | manifests_tests - test_manifest_generator. 6 | 7 | Loops through the manifests directory and tests that 8 | each file can successfully be loaded and validated. 9 | """ 10 | 11 | from nose.tools import assert_true 12 | from bootstrapvz.base.manifest import Manifest 13 | 14 | def validate_manifest(path): 15 | manifest = Manifest(path=path) 16 | assert_true(manifest.data) 17 | assert_true(manifest.data['name']) 18 | assert_true(manifest.data['provider']) 19 | assert_true(manifest.data['bootstrapper']) 20 | assert_true(manifest.data['volume']) 21 | assert_true(manifest.data['system']) 22 | 23 | import os.path 24 | from .. import recursive_glob 25 | from itertools import chain 26 | manifests = os.path.join(os.path.dirname(os.path.realpath(__file__)), 27 | '../../manifests') 28 | manifest_paths = chain(recursive_glob(manifests, '*.yml'), recursive_glob(manifests, '*.json')) 29 | for manifest_path in manifest_paths: 30 | validate_manifest.description = "Validating %s" % os.path.relpath(manifest_path, manifests) 31 | yield validate_manifest, manifest_path 32 | -------------------------------------------------------------------------------- /tests/unit/releases_tests.py: -------------------------------------------------------------------------------- 1 | from nose.tools import raises 2 | from bootstrapvz.common import releases 3 | 4 | 5 | def test_gt(): 6 | assert releases.wheezy > releases.squeeze 7 | 8 | 9 | def test_lt(): 10 | assert releases.wheezy < releases.stretch 11 | 12 | 13 | def test_eq(): 14 | assert releases.wheezy == releases.wheezy 15 | 16 | 17 | def test_neq(): 18 | assert releases.wheezy != releases.jessie 19 | 20 | 21 | def test_identity(): 22 | assert releases.wheezy is releases.wheezy 23 | 24 | 25 | def test_not_identity(): 26 | # "==" tests equality "is" tests identity 27 | assert releases.stretch == releases.stable 28 | assert releases.stretch is not releases.stable 29 | 30 | assert releases.stable is releases.stable 31 | assert releases.stretch is releases.stretch 32 | 33 | assert releases.jessie != releases.stable 34 | assert releases.jessie is not releases.stable 35 | 36 | 37 | def test_alias(): 38 | assert releases.oldstable == releases.jessie 39 | assert releases.stable == releases.stretch 40 | assert releases.testing == releases.buster 41 | assert releases.unstable == releases.sid 42 | 43 | 44 | @raises(releases.UnknownReleaseException) 45 | def test_bogus_releasename(): 46 | releases.get_release('nemo') 47 | -------------------------------------------------------------------------------- /tests/unit/subprocess.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Expected input from stdin: 4 | # streamNo delay message 5 | # Running the following 6 | # 7 | # (cat <&$stream 29 | done 30 | wait 31 | -------------------------------------------------------------------------------- /tests/unit/tools_tests.py: -------------------------------------------------------------------------------- 1 | import os 2 | from nose.tools import eq_ 3 | from bootstrapvz.common.tools import log_call 4 | 5 | subprocess_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'subprocess.sh') 6 | 7 | 8 | def setup_logger(): 9 | import logging 10 | root = logging.getLogger() 11 | root.setLevel(logging.NOTSET) 12 | 13 | import StringIO 14 | output = StringIO.StringIO() 15 | string_handler = logging.StreamHandler(output) 16 | string_handler.setLevel(logging.DEBUG) 17 | root.addHandler(string_handler) 18 | return output 19 | 20 | 21 | def test_log_call_output_order(): 22 | logged = setup_logger() 23 | fixture = """ 24 | 2 0.0 one\\\\n 25 | 1 0.4 two\\\\n 26 | 1 0.4 four\\\\n 27 | 2 0.4 No, three..\\\\n 28 | 1 0.4 three\\\\n 29 | """ 30 | status, stdout, stderr = log_call([subprocess_path], stdin=fixture) 31 | eq_(status, 0) 32 | eq_(stderr, ['one', 'No, three..']) 33 | eq_(stdout, ['two', 'four', 'three']) 34 | expected_order = ['one', 35 | 'two', 36 | 'four', 37 | 'No, three..', 38 | 'three', 39 | ] 40 | eq_(expected_order, logged.getvalue().split("\n")[8:-1]) 41 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = flake8, pylint, yamllint, unit, integration, docs 3 | 4 | [flake8] 5 | ignore = E221,E241,E501,W504 6 | max-line-length = 110 7 | 8 | [testenv] 9 | basepython = python2.7 10 | 11 | [testenv:flake8] 12 | deps = flake8 13 | commands = flake8 bootstrapvz/ tests/ {posargs} 14 | 15 | [testenv:pylint] 16 | deps = 17 | pylint 18 | nose 19 | pyvbox 20 | commands = pylint bootstrapvz/ tests/ setup.py 21 | 22 | [testenv:unit] 23 | deps = 24 | nose 25 | nose-cov 26 | commands = nosetests --verbose {posargs:tests/unit} 27 | 28 | [testenv:integration] 29 | deps = 30 | nose 31 | nose-cov 32 | commands = nosetests --verbose {posargs:tests/integration} 33 | 34 | [testenv:system] 35 | deps = 36 | nose 37 | nose-cov 38 | nose-htmloutput 39 | pyvbox >= 0.2.0 40 | commands = nosetests --with-html --html-file=system.html --verbose {posargs:tests/system} 41 | 42 | [testenv:docs] 43 | changedir = docs 44 | deps = 45 | sphinx != 1.5 46 | sphinx_rtd_theme 47 | commands = sphinx-build -W -b html -d _build/html/doctrees . _build/html 48 | 49 | [testenv:yamllint] 50 | deps = yamllint 51 | commands = yamllint manifests 52 | --------------------------------------------------------------------------------