summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jenkinsfile194
-rw-r--r--cloudinit/config/cc_vyos.py333
-rw-r--r--cloudinit/sources/DataSourceOVF.py3
-rw-r--r--config/cloud.cfg.tmpl202
-rw-r--r--systemd/cloud-config.service.tmpl1
5 files changed, 542 insertions, 191 deletions
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 00000000..1b9d23e4
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,194 @@
+// Copyright (C) 2019 VyOS maintainers and contributors
+//
+// This program is free software; you can redistribute it and/or modify
+// in order to easy exprort images built to "external" world
+// it under the terms of the GNU General Public License version 2 or later as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+@NonCPS
+
+def getGitBranchName() {
+ def branch = scm.branches[0].name
+ return branch.split('/')[-1]
+}
+
+def getGitRepoURL() {
+ return scm.userRemoteConfigs[0].url
+}
+
+def getGitRepoName() {
+ return getGitRepoURL().split('/').last()
+}
+
+// Returns true if this is a custom build launched on any project fork.
+// Returns false if this is build from git@github.com:vyos/<reponame>.
+// <reponame> can be e.g. vyos-1x.git or vyatta-op.git
+def isCustomBuild() {
+ // GitHub organisation base URL
+ def gitURI = 'git@github.com:vyos/' + getGitRepoName()
+ def httpURI = 'https://github.com/vyos/' + getGitRepoName()
+
+ return ! ((getGitRepoURL() == gitURI) || (getGitRepoURL() == httpURI))
+}
+
+def setDescription() {
+ def item = Jenkins.instance.getItemByFullName(env.JOB_NAME)
+
+ // build up the main description text
+ def description = ""
+ description += "<h2>VyOS individual package build: " + getGitRepoName().replace('.git', '') + "</h2>"
+
+ if (isCustomBuild()) {
+ description += "<p style='border: 3px dashed red; width: 50%;'>"
+ description += "<b>Build not started from official Git repository!</b><br>"
+ description += "<br>"
+ description += "Repository: <font face = 'courier'>" + getGitRepoURL() + "</font><br>"
+ description += "Branch: <font face = 'courier'>" + getGitBranchName() + "</font><br>"
+ description += "</p>"
+ } else {
+ description += "Sources taken from Git branch: <font face = 'courier'>" + getGitBranchName() + "</font><br>"
+ }
+
+ item.setDescription(description)
+ item.save()
+}
+
+/* Only keep the 10 most recent builds. */
+def projectProperties = [
+ [$class: 'BuildDiscarderProperty',strategy: [$class: 'LogRotator', numToKeepStr: '10']],
+]
+
+properties(projectProperties)
+setDescription()
+
+node('Docker') {
+ stage('Define Agent') {
+ script {
+ // create container name on demand
+ def branchName = getGitBranchName()
+ if (branchName == "master") {
+ branchName = "current"
+ }
+ env.DOCKER_IMAGE = "vyos/vyos-build:" + branchName
+ }
+ }
+}
+
+pipeline {
+ agent {
+ docker {
+ args "--sysctl net.ipv6.conf.lo.disable_ipv6=0 -e GOSU_UID=1006 -e GOSU_GID=1006"
+ image "${env.DOCKER_IMAGE}"
+ alwaysPull true
+ }
+ }
+ options {
+ disableConcurrentBuilds()
+ skipDefaultCheckout()
+ timeout(time: 30, unit: 'MINUTES')
+ timestamps()
+ }
+ stages {
+ stage('Fetch') {
+ steps {
+ script {
+ dir('build') {
+ git branch: getGitBranchName(),
+ url: getGitRepoURL()
+ }
+ }
+ }
+ }
+ stage('Install missed dependencies') {
+ steps {
+ script {
+ dir('build') {
+ sh 'sudo apt update'
+ sh 'sudo apt install -y python3-jsonschema python3-contextlib2 cloud-utils'
+ }
+ }
+ }
+ }
+ stage('Build') {
+ steps {
+ script {
+ dir('build') {
+ def commitId = sh(returnStdout: true, script: 'git rev-parse --short=11 HEAD').trim()
+ currentBuild.description = sprintf('Git SHA1: %s', commitId[-11..-1])
+
+ sh './packages/bddeb'
+ }
+ }
+ }
+ }
+ }
+ post {
+ cleanup {
+ deleteDir()
+ }
+ success {
+ script {
+ // archive *.deb artifact on custom builds, deploy to repo otherwise
+ if ( isCustomBuild()) {
+ archiveArtifacts artifacts: 'cloud-init_*_all.deb', fingerprint: true
+ } else {
+ // publish build result, using SSH-dev.packages.vyos.net Jenkins Credentials
+ sshagent(['SSH-dev.packages.vyos.net']) {
+ // build up some fancy groovy variables so we do not need to write/copy
+ // every option over and over again!
+ def RELEASE = getGitBranchName()
+ if (getGitBranchName() == "master") {
+ RELEASE = 'current'
+ }
+
+ def VYOS_REPO_PATH = '/home/sentrium/web/dev.packages.vyos.net/public_html/repositories/' + RELEASE + '/'
+ if (getGitBranchName() == "crux")
+ VYOS_REPO_PATH += 'vyos/'
+
+ def SSH_OPTS = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR'
+ def SSH_REMOTE = 'khagen@10.217.48.113'
+
+ echo "Uploading package(s) and updating package(s) in the repository ..."
+
+ files = findFiles(glob: 'cloud-init_*_all.deb')
+ files.each { PACKAGE ->
+ def ARCH = sh(returnStdout: true, script: "dpkg-deb -f ${PACKAGE} Architecture").trim()
+ def SUBSTRING = sh(returnStdout: true, script: "dpkg-deb -f ${PACKAGE} Package").trim()
+ def SSH_DIR = '~/VyOS/' + RELEASE + '/' + ARCH
+ def ARCH_OPT = ''
+ if (ARCH != 'all')
+ ARCH_OPT = '-A ' + ARCH
+
+ // No need to explicitly check the return code. The pipeline
+ // will fail if sh returns a non 0 exit code
+ sh """
+ ssh ${SSH_OPTS} ${SSH_REMOTE} -t "bash --login -c 'mkdir -p ${SSH_DIR}'"
+ """
+ sh """
+ scp ${SSH_OPTS} ${PACKAGE} ${SSH_REMOTE}:${SSH_DIR}/
+ """
+ sh """
+ ssh ${SSH_OPTS} ${SSH_REMOTE} -t "uncron-add 'reprepro -v -b ${VYOS_REPO_PATH} ${ARCH_OPT} remove ${RELEASE} ${SUBSTRING}'"
+ """
+ sh """
+ ssh ${SSH_OPTS} ${SSH_REMOTE} -t "uncron-add 'reprepro -v -b ${VYOS_REPO_PATH} deleteunreferenced'"
+ """
+ sh """
+ ssh ${SSH_OPTS} ${SSH_REMOTE} -t "uncron-add 'reprepro -v -b ${VYOS_REPO_PATH} ${ARCH_OPT} includedeb ${RELEASE} ${SSH_DIR}/${PACKAGE}'"
+ """
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/cloudinit/config/cc_vyos.py b/cloudinit/config/cc_vyos.py
new file mode 100644
index 00000000..e51ed7f2
--- /dev/null
+++ b/cloudinit/config/cc_vyos.py
@@ -0,0 +1,333 @@
+# vi: ts=4 expandtab
+#
+# Copyright (C) 2009-2010 Canonical Ltd.
+# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+# Copyright (C) 2019 Sentrium S.L.
+#
+# Author: Scott Moser <scott.moser@canonical.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.com>
+# Author: Kim Hagen <kim@sentrium.io>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import re
+import sys
+import ast
+
+import ipaddress
+from cloudinit import stages
+from cloudinit import util
+
+from cloudinit.distros import ug_util
+from cloudinit.settings import PER_INSTANCE
+from cloudinit import handlers
+from cloudinit import log as logging
+
+from vyos.configtree import ConfigTree
+
+# configure logging
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+frequency = PER_INSTANCE
+
+class VyosError(Exception):
+ """Raised when the distro runs into an exception when setting vyos config.
+ This may happen when the ssh pub key format is wrong.
+ """
+ pass
+
+# configure user account with password
+def set_pass_login(config, user, password, encrypted_pass):
+ if encrypted_pass:
+ config.set(['system', 'login', 'user', user, 'authentication', 'encrypted-password'], value=password, replace=True)
+ else:
+ config.set(['system', 'login', 'user', user, 'authentication', 'plaintext-password'], value=password, replace=True)
+
+ config.set_tag(['system', 'login', 'user'])
+
+# configure user account with ssh key
+def set_ssh_login(config, user, key_string, key_x):
+ key_type = None
+ key_data = None
+ key_name = None
+
+ if key_string == '':
+ logger.error("No keys found.")
+ return
+
+ key_parts = key_string.split(None)
+
+ for key in key_parts:
+ if 'ssh-dss' in key or 'ssh-rsa' in key:
+ key_type = key
+
+ if key.startswith('AAAAB3NzaC1yc2E') or key.startswith('AAAAB3NzaC1kc3M'):
+ key_data = key
+
+ if not key_type:
+ logger.error("Key type not defined, wrong ssh key format.")
+ return
+
+ if not key_data:
+ logger.error("Key base64 not defined, wrong ssh key format.")
+ return
+
+ if len(key_parts) > 2:
+ if key_parts[2] != key_type or key_parts[2] != key_data:
+ key_name = key_parts[2]
+ else:
+ key_name = "cloud-init-%s" % key_x
+ else:
+ key_name = "cloud-init-%s" % key_x
+
+ config.set(['system', 'login', 'user', user, 'authentication', 'public-keys', key_name , 'key'], value=key_data, replace=True)
+ config.set(['system', 'login', 'user', user, 'authentication', 'public-keys', key_name , 'type'], value=key_type, replace=True)
+ config.set_tag(['system', 'login', 'user'])
+ config.set_tag(['system', 'login', 'user', user, 'authentication', 'public-keys'])
+
+
+# configure system parameters from OVF template
+def set_config_ovf(config, hostname, metadata):
+ ip_0 = metadata['ip0']
+ mask_0 = metadata['netmask0']
+ gateway = metadata['gateway']
+ DNS = list(metadata['DNS'].replace(' ', '').split(','))
+ NTP = list(metadata['NTP'].replace(' ', '').split(','))
+ APIKEY = metadata['APIKEY']
+ APIPORT = metadata['APIPORT']
+ APIDEBUG = metadata['APIDEBUG']
+
+ if ip_0 and ip_0 != 'null' and mask_0 and mask_0 != 'null' and gateway and gateway != 'null':
+ cidr = str(ipaddress.IPv4Network('0.0.0.0/' + mask_0).prefixlen)
+ ipcidr = ip_0 + '/' + cidr
+
+ config.set(['interfaces', 'ethernet', 'eth0', 'address'], value=ipcidr, replace=True)
+ config.set_tag(['interfaces', 'ethernet'])
+ config.set(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop'], value=gateway, replace=True)
+ config.set_tag(['protocols', 'static', 'route'])
+ config.set_tag(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop'])
+ else:
+ config.set(['interfaces', 'ethernet', 'eth0', 'address'], value='dhcp', replace=True)
+ config.set_tag(['interfaces', 'ethernet'])
+
+ DNS = [server for server in DNS if server and server != 'null']
+ if DNS:
+ for server in DNS:
+ config.set(['system', 'name-server'], value=server, replace=False)
+
+ NTP = [server for server in NTP if server and server != 'null']
+ if NTP:
+ for server in NTP:
+ config.set(['system', 'ntp', 'server'], value=server, replace=False)
+ config.set_tag(['system', 'ntp', 'server'])
+
+ if APIKEY and APIKEY != 'null':
+ config.set(['service', 'https', 'api', 'keys', 'id', 'cloud-init', 'key'], value=APIKEY, replace=True)
+ config.set_tag(['service', 'https', 'api', 'keys', 'id'])
+
+ if APIDEBUG != 'False' and APIKEY and APIKEY != 'null':
+ config.set(['service', 'https', 'api', 'debug'], replace=True)
+
+ if APIPORT and APIPORT != 'null' and APIKEY and APIKEY != 'null':
+ config.set(['service', 'https', 'listen-address', '0.0.0.0', 'listen-port'], value=APIPORT, replace=True)
+ config.set_tag(['service', 'https', 'listen-address'])
+
+ config.set(['service', 'ssh'], replace=True)
+ config.set(['service', 'ssh', 'port'], value='22', replace=True)
+
+ if hostname and hostname != 'null':
+ config.set(['system', 'host-name'], value=hostname, replace=True)
+ else:
+ config.set(['system', 'host-name'], value='vyos', replace=True)
+
+
+# configure interface
+def set_config_interfaces(config, iface_name, iface_config):
+ # configure DHCP client
+ if 'dhcp4' in iface_config:
+ if iface_config['dhcp4'] == True:
+ config.set(['interfaces', 'ethernet', iface_name, 'address'], value='dhcp', replace=True)
+ config.set_tag(['interfaces', 'ethernet'])
+ if 'dhcp6' in iface_config:
+ if iface_config['dhcp6'] == True:
+ config.set(['interfaces', 'ethernet', iface_name, 'address'], value='dhcp6', replace=True)
+ config.set_tag(['interfaces', 'ethernet'])
+
+ # configure static addresses
+ if 'addresses' in iface_config:
+ for item in iface_config['addresses']:
+ config.set(['interfaces', 'ethernet', iface_name, 'address'], value=item, replace=True)
+ config.set_tag(['interfaces', 'ethernet'])
+
+ # configure gateways
+ if 'gateway4' in iface_config:
+ config.set(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop'], value=item, replace=True)
+ config.set_tag(['protocols', 'static', 'route'])
+ config.set_tag(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop'])
+ if 'gateway6' in iface_config:
+ config.set(['protocols', 'static', 'route6', '::/0', 'next-hop'], value=item, replace=True)
+ config.set_tag(['protocols', 'static', 'route6'])
+ config.set_tag(['protocols', 'static', 'route6', '::/0', 'next-hop'])
+
+ # configre MTU
+ if 'mtu' in iface_config:
+ config.set(['interfaces', 'ethernet', iface_name, 'mtu'], value=iface_config['mtu'], replace=True)
+ config.set_tag(['interfaces', 'ethernet'])
+
+ # configure routes
+ if 'routes' in iface_config:
+ for item in iface_config['routes']:
+ try:
+ if ipaddress.ip_network(item['to']).version == 4:
+ config.set(['protocols', 'static', 'route', item['to'], 'next-hop'], value=item['via'], replace=True)
+ config.set_tag(['protocols', 'static', 'route'])
+ config.set_tag(['protocols', 'static', 'route', item['to'], 'next-hop'])
+ if ipaddress.ip_network(item['to']).version == 6:
+ config.set(['protocols', 'static', 'route6', item['to'], 'next-hop'], value=item['via'], replace=True)
+ config.set_tag(['protocols', 'static', 'route6'])
+ config.set_tag(['protocols', 'static', 'route6', item['to'], 'next-hop'])
+ except Exception as err:
+ logger.error("Impossible to detect IP protocol version: {}".format(err))
+
+ # configure nameservers
+ if 'nameservers' in iface_config:
+ if 'search' in iface_config['nameservers']:
+ for item in iface_config['nameservers']['search']:
+ config.set(['system', 'domain-search'], value=item, replace=False)
+ if 'addresses' in iface_config['nameservers']:
+ for item in iface_config['nameservers']['addresses']:
+ config.set(['system', 'name-server'], value=item, replace=False)
+
+
+# configure DHCP client for interface
+def set_config_dhcp(config):
+ config.set(['interfaces', 'ethernet', 'eth0', 'address'], value='dhcp', replace=True)
+ config.set_tag(['interfaces', 'ethernet'])
+
+
+# configure SSH server service
+def set_config_ssh(config):
+ config.set(['service', 'ssh'], replace=True)
+ config.set(['service', 'ssh', 'port'], value='22', replace=True)
+ config.set(['service', 'ssh', 'client-keepalive-interval'], value='180', replace=True)
+
+
+# configure hostname
+def set_config_hostname(config, hostname):
+ config.set(['system', 'host-name'], value=hostname, replace=True)
+
+
+# configure SSH, eth0 interface and hostname
+def set_config_cloud(config, hostname):
+ config.set(['service', 'ssh'], replace=True)
+ config.set(['service', 'ssh', 'port'], value='22', replace=True)
+ config.set(['service', 'ssh', 'client-keepalive-interval'], value='180', replace=True)
+ config.set(['interfaces', 'ethernet', 'eth0', 'address'], value='dhcp', replace=True)
+ config.set_tag(['interfaces', 'ethernet'])
+ config.set(['system', 'host-name'], value=hostname, replace=True)
+
+
+# main config handler
+def handle(name, cfg, cloud, log, _args):
+ init = stages.Init()
+ dc = init.fetch()
+ cfg_file_name = '/opt/vyatta/etc/config/config.boot'
+ bak_file_name = '/opt/vyatta/etc/config.boot.default'
+ metadata = cloud.datasource.metadata
+ (netcfg, _) = init._find_networking_config()
+ (users, _) = ug_util.normalize_users_groups(cfg, cloud.distro)
+ (hostname, _) = util.get_hostname_fqdn(cfg, cloud)
+ key_x = 1
+ key_y = 0
+
+ # look at data that can be used for configuration
+ #print(dir(dc))
+
+ if not os.path.exists(cfg_file_name):
+ file_name = bak_file_name
+ else:
+ file_name = cfg_file_name
+
+ with open(file_name, 'r') as f:
+ config_file = f.read()
+ config = ConfigTree(config_file)
+
+ if 'Azure' in dc.dsname:
+ encrypted_pass = True
+ for key, val in users.items():
+ user = key
+
+ if 'passwd' in val:
+ password = val.get('passwd')
+ set_pass_login(config, user, password, encrypted_pass)
+
+ vyos_keys = metadata['public-keys']
+
+ for ssh_key in vyos_keys:
+ set_ssh_login(config, user, ssh_key, key_x)
+ key_x = key_x + 1
+ else:
+ encrypted_pass = False
+ for user in users:
+ password = util.get_cfg_option_str(cfg, 'passwd', None)
+
+ if not password:
+ password = util.get_cfg_option_str(cfg, 'password', None)
+
+ if password and password != '':
+ hash = re.match("(^\$.\$)", password)
+ hash_count = password.count('$')
+ if hash and hash_count >= 3:
+ base64 = password.split('$')[3]
+ base_64_len = len(base64)
+ if ((hash.group(1) == '$1$' and base_64_len == 22) or
+ (hash.group(1) == '$5$' and base_64_len == 43) or
+ (hash.group(1) == '$6$' and base_64_len == 86)):
+ encrypted_pass = True
+ set_pass_login(config, user, password, encrypted_pass)
+
+ vyos_keys = cloud.get_public_ssh_keys() or []
+ if 'ssh_authorized_keys' in cfg:
+ cfgkeys = cfg['ssh_authorized_keys']
+ vyos_keys.extend(cfgkeys)
+
+ for ssh_key in vyos_keys:
+ set_ssh_login(config, user, ssh_key, key_x)
+ key_x = key_x + 1
+
+ if 'OVF' in dc.dsname:
+ set_config_ovf(config, hostname, metadata)
+ key_y = 1
+ elif netcfg:
+ if 'ethernets' in netcfg:
+ key_y = 1
+ for interface_name, interface_config in netcfg['ethernets'].items():
+ set_config_interfaces(config, interface_name, interface_config)
+
+ set_config_ssh(config)
+ set_config_hostname(config, hostname)
+ else:
+ set_config_dhcp(config)
+ set_config_ssh(config)
+ set_config_hostname(config, hostname)
+
+ if key_y == 0:
+ set_config_dhcp(config)
+
+ try:
+ with open(cfg_file_name, 'w') as f:
+ f.write(config.to_string())
+ except Exception as e:
+ logger.error("Failed to write configs into file %s error %s", file_name, e)
diff --git a/cloudinit/sources/DataSourceOVF.py b/cloudinit/sources/DataSourceOVF.py
index 9f6e6b6c..7f55b5f8 100644
--- a/cloudinit/sources/DataSourceOVF.py
+++ b/cloudinit/sources/DataSourceOVF.py
@@ -414,7 +414,8 @@ def read_ovf_environment(contents):
cfg = {}
ud = None
cfg_props = ['password']
- md_props = ['seedfrom', 'local-hostname', 'public-keys', 'instance-id']
+ md_props = ['seedfrom', 'local-hostname', 'public-keys', 'instance-id',
+ 'ip0', 'netmask0', 'gateway', 'DNS', 'NTP', 'APIKEY' ,'APIPORT', 'APIDEBUG']
for (prop, val) in props.items():
if prop == 'hostname':
prop = "local-hostname"
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index 99f96ea1..8f98cb96 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -2,228 +2,50 @@
# The top level settings are used as module
# and system configuration.
-{% if variant in ["freebsd"] %}
-syslog_fix_perms: root:wheel
-{% elif variant in ["suse"] %}
-syslog_fix_perms: root:root
-{% endif %}
# A set of users which may be applied and/or used by various modules
# when a 'default' entry is found it will reference the 'default_user'
# from the distro configuration specified below
users:
- default
-# If this is set, 'root' will not be able to ssh in and they
-# will get a message to login instead as the default $user
-{% if variant in ["freebsd"] %}
-disable_root: false
-{% else %}
-disable_root: true
-{% endif %}
-
-{% if variant in ["amazon", "centos", "fedora", "rhel"] %}
-mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2']
-{% if variant == "amazon" %}
-resize_rootfs: noblock
-{% endif %}
-resize_rootfs_tmp: /dev
-ssh_pwauth: 0
-
-{% endif %}
# This will cause the set+update hostname module to not operate (if true)
-preserve_hostname: false
+preserve_hostname: true
-{% if variant in ["freebsd"] %}
-# This should not be required, but leave it in place until the real cause of
-# not finding -any- datasources is resolved.
-datasource_list: ['NoCloud', 'ConfigDrive', 'Azure', 'OpenStack', 'Ec2']
-{% endif %}
# Example datasource config
# datasource:
# Ec2:
# metadata_urls: [ 'blah.com' ]
# timeout: 5 # (defaults to 50 seconds)
# max_wait: 10 # (defaults to 120 seconds)
+datasource:
+ Azure:
+ agent_command: [/usr/bin/python3, -u, /usr/sbin/waagent, -start]
-
-{% if variant == "amazon" %}
-# Amazon Linux relies on ec2-net-utils for network configuration
-network:
- config: disabled
-{% endif %}
+# disable customization for VMware
+disable_vmware_customization: true
# The modules that run in the 'init' stage
cloud_init_modules:
- - migrator
- - seed_random
- - bootcmd
- - write-files
- - growpart
- - resizefs
-{% if variant not in ["freebsd"] %}
- - disk_setup
- - mounts
-{% endif %}
- - set_hostname
- - update_hostname
-{% if variant not in ["freebsd"] %}
- - update_etc_hosts
- - ca-certs
- - rsyslog
-{% endif %}
- - users-groups
- - ssh
# The modules that run in the 'config' stage
cloud_config_modules:
-{% if variant in ["ubuntu", "unknown", "debian"] %}
-# Emit the cloud config ready event
-# this can be used by upstart jobs for 'start on cloud-config'.
- - emit_upstart
- - snap
-{% endif %}
- - ssh-import-id
- - locale
- - set-passwords
-{% if variant in ["rhel", "fedora"] %}
- - spacewalk
- - yum-add-repo
-{% endif %}
-{% if variant in ["ubuntu", "unknown", "debian"] %}
- - grub-dpkg
- - apt-pipelining
- - apt-configure
-{% endif %}
-{% if variant in ["ubuntu"] %}
- - ubuntu-advantage
-{% endif %}
-{% if variant in ["suse"] %}
- - zypper-add-repo
-{% endif %}
-{% if variant not in ["freebsd"] %}
- - ntp
-{% endif %}
- - timezone
- - disable-ec2-metadata
- - runcmd
-{% if variant in ["ubuntu", "unknown", "debian"] %}
- - byobu
-{% endif %}
+ - vyos
# The modules that run in the 'final' stage
cloud_final_modules:
- - package-update-upgrade-install
-{% if variant in ["ubuntu", "unknown", "debian"] %}
- - fan
- - landscape
- - lxd
-{% endif %}
-{% if variant in ["ubuntu", "unknown"] %}
- - ubuntu-drivers
-{% endif %}
-{% if variant not in ["freebsd"] %}
- - puppet
- - chef
- - mcollective
-{% endif %}
- - salt-minion
- - rightscale_userdata
- - scripts-vendor
- - scripts-per-once
- - scripts-per-boot
- - scripts-per-instance
- - scripts-user
- - ssh-authkey-fingerprints
- - keys-to-console
- - phone-home
- - final-message
- - power-state-change
+ - runcmd
+
# System and/or distro specific settings
# (not accessible to handlers/transforms)
system_info:
# This will affect which distro class gets used
-{% if variant in ["amazon", "arch", "centos", "debian", "fedora", "freebsd", "rhel", "suse", "ubuntu"] %}
- distro: {{ variant }}
-{% else %}
- # Unknown/fallback distro.
- distro: ubuntu
-{% endif %}
-{% if variant in ["ubuntu", "unknown", "debian"] %}
+ distro: debian
# Default user name + that default users groups (if added/used)
default_user:
- name: ubuntu
- lock_passwd: True
- gecos: Ubuntu
- groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video]
- sudo: ["ALL=(ALL) NOPASSWD:ALL"]
- shell: /bin/bash
- # Automatically discover the best ntp_client
- ntp_client: auto
+ name: vyos
# Other config here will be given to the distro class and/or path classes
paths:
- cloud_dir: /var/lib/cloud/
+ cloud_dir: /opt/vyatta/etc/config/cloud/
templates_dir: /etc/cloud/templates/
upstart_dir: /etc/init/
- package_mirrors:
- - arches: [i386, amd64]
- failsafe:
- primary: http://archive.ubuntu.com/ubuntu
- security: http://security.ubuntu.com/ubuntu
- search:
- primary:
- - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/
- - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/
- - http://%(region)s.clouds.archive.ubuntu.com/ubuntu/
- security: []
- - arches: [arm64, armel, armhf]
- failsafe:
- primary: http://ports.ubuntu.com/ubuntu-ports
- security: http://ports.ubuntu.com/ubuntu-ports
- search:
- primary:
- - http://%(ec2_region)s.ec2.ports.ubuntu.com/ubuntu-ports/
- - http://%(availability_zone)s.clouds.ports.ubuntu.com/ubuntu-ports/
- - http://%(region)s.clouds.ports.ubuntu.com/ubuntu-ports/
- security: []
- - arches: [default]
- failsafe:
- primary: http://ports.ubuntu.com/ubuntu-ports
- security: http://ports.ubuntu.com/ubuntu-ports
- ssh_svcname: ssh
-{% elif variant in ["amazon", "arch", "centos", "fedora", "rhel", "suse"] %}
- # Default user name + that default users groups (if added/used)
- default_user:
-{% if variant == "amazon" %}
- name: ec2-user
- lock_passwd: True
- gecos: EC2 Default User
-{% else %}
- name: {{ variant }}
- lock_passwd: True
- gecos: {{ variant }} Cloud User
-{% endif %}
-{% if variant == "suse" %}
- groups: [cdrom, users]
-{% elif variant == "arch" %}
- groups: [wheel, users]
-{% else %}
- groups: [wheel, adm, systemd-journal]
-{% endif %}
- sudo: ["ALL=(ALL) NOPASSWD:ALL"]
- shell: /bin/bash
- # Other config here will be given to the distro class and/or path classes
- paths:
- cloud_dir: /var/lib/cloud/
- templates_dir: /etc/cloud/templates/
- ssh_svcname: sshd
-{% elif variant in ["freebsd"] %}
- # Default user name + that default users groups (if added/used)
- default_user:
- name: freebsd
- lock_passwd: True
- gecos: FreeBSD
- groups: [wheel]
- sudo: ["ALL=(ALL) NOPASSWD:ALL"]
- shell: /bin/tcsh
-{% endif %}
diff --git a/systemd/cloud-config.service.tmpl b/systemd/cloud-config.service.tmpl
index 9d928ca2..508d777e 100644
--- a/systemd/cloud-config.service.tmpl
+++ b/systemd/cloud-config.service.tmpl
@@ -1,6 +1,7 @@
## template:jinja
[Unit]
Description=Apply the settings specified in cloud-config
+Before=vyos-router.service
After=network-online.target cloud-config.target
After=snapd.seeded.service
Wants=network-online.target cloud-config.target