From 68b796e24f80726213a3af278b782e5b04863f9d Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sat, 27 Aug 2016 16:06:11 +0200 Subject: [PATCH 001/111] Updated documentation --- docs/cosmos-puppet-ops.mkd | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/docs/cosmos-puppet-ops.mkd b/docs/cosmos-puppet-ops.mkd index 46ceb508..5bd119c1 100644 --- a/docs/cosmos-puppet-ops.mkd +++ b/docs/cosmos-puppet-ops.mkd @@ -1,5 +1,5 @@ % System Operations using Cosmos & Puppet -% Leif Johansson / SUNET / 2013 / v0.0.3 +% Leif Johansson / SUNET / 2013 / v0.0.4 Introduction @@ -152,7 +152,7 @@ system state using a set of idempotent operations. In theory, anything that can using puppet can be done using cosmos post-processors but puppet allows for greater abstraction which greatly increases readability. -The combination of puppet and cosmos is maintained on github in the 'leifj/multiverse' +The combination of puppet and cosmos is maintained on github in the 'SUNET/multiverse' project. The Cosmos Puppet Module @@ -160,7 +160,7 @@ The Cosmos Puppet Module Although not necessary, a few nice-to-have utilities in the form of puppet modules have been collected as the cosmos puppet module (for want of a better name). The source for -this module is at http://github.com/leifj/puppet-cosmos and it is included (but commented +this module is at https://github.com/SUNET/puppet-cosmos and it is included (but commented out) in the cosmos-modules.conf file (cf below) for easy inclusion. @@ -186,11 +186,11 @@ multiverse. Fabric provides the 'fab' command which will be introduced later on. These two tools (git & fabric) are only needed on mashines where system operators work. -Next clone git://github.com/leifj/multiverse.git - this will form the basis of your cosmos+puppet +Next clone git@github.com:SUNET/multiverse.git - this will form the basis of your cosmos+puppet repository: ``` -# git clone git://github.com/leifj/multiverse.git myproj-cosmos +# git clone git@github.com:SUNET/multiverse.git myproj-cosmos # cd myproj-cosmos ``` @@ -207,12 +207,19 @@ as 'ro'. The read-only remote is used by multiverse scripts during host bootstra ``` # git remote add origin git@yourhost:myproj-cosmos.git -# git remote add ro git://yourhost/myproj-cosmos.git +# git remote add ro https://yourhost/myproj-cosmos.git ``` Now edit .git/config and rename the 'master' branch to use the new 'origin' remote or -you'll try to push to the multiverse remote! Finally create a branch for the 'multiverse' -upstream so you can merge changes to multiverse: +you'll try to push to the multiverse remote! + +``` +[branch "master"] + remote = origin + merge = refs/heads/master +``` + +Finally create a branch for the 'multiverse' upstream so you can merge changes to multiverse: ``` # git checkout -b multiverse --track multiverse/master @@ -238,6 +245,10 @@ At this point you should create and sign your first tag: # ./bump-tag ``` +If Git complains during the first run of bump-tag that "Your configuration specifies to +merge with the ref 'master' from the remote, but no such ref was fetched." then you +have run 'git push' to initialize the connection with the remote repository. + Make sure that you are using the key whose public key you just added to the repository! You can now start adding hosts. @@ -330,14 +341,14 @@ with 3 columns: # concat puppetlabs/concat no stdlib puppetlabs/stdlib no -cosmos git://github.com/leifj/puppet-cosmos.git yes -ufw git://github.com/fredrikt/puppet-module-ufw.git yes +cosmos git@github.com:SUNET/puppet-cosmos.git yes +ufw git://github.com/SUNET/puppet-module-ufw.git yes apt puppetlabs/apt no vcsrepo puppetlabs/vcsrepo no xinetd puppetlabs/xinetd no #golang elithrar/golang yes -python git://github.com/fredrikt/puppet-python.git yes -hiera-gpg git://github.com/fredrikt/hiera-gpg.git no +python git://github.com/SUNET/puppet-python.git yes +hiera-gpg git://github.com/SUNET/hiera-gpg.git no ``` This is an example file - the first field is the name of the module, the second is @@ -448,3 +459,4 @@ On all hosts: ``` # fab -- reboot # danger Will Robinsson! ``` + From b10c250c8eb161d5446f65f5169548d1802750ff Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sat, 27 Aug 2016 16:22:16 +0200 Subject: [PATCH 002/111] Removed obsolete references to git:// and changed remotes to https:// MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "The downside of the Git protocol is the lack of authentication. It’s generally undesirable for the Git protocol to be the only access to your project." Source: https://git-scm.com/book/tr/v2/Git-on-the-Server-The-Protocols --- docs/cosmos-puppet-ops.mkd | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/cosmos-puppet-ops.mkd b/docs/cosmos-puppet-ops.mkd index 5bd119c1..3c7bfcd9 100644 --- a/docs/cosmos-puppet-ops.mkd +++ b/docs/cosmos-puppet-ops.mkd @@ -226,9 +226,9 @@ Finally create a branch for the 'multiverse' upstream so you can merge changes t ``` Note that you can maintain your repo on just about any git hosting platform, including -github, gitorius or your own local setup as long as it supports read-only "git://" access -to your repository. It is important that the remotes called 'origin' and 'ro' refer to -your repository and not to anything else (like a private version of multiverse). +github, gitorius or your own local setup as long as it supports read-only access to your +repository. It is important that the remotes called 'origin' and 'ro' refer to your +repository and not to anything else (like a private version of multiverse). Now add at least one key to 'global/overlay/etc/cosmos/keys/' in a file with a .pub extension (eg 'operator.pub') - the name of the file doesn't matter other than the extension. @@ -341,14 +341,14 @@ with 3 columns: # concat puppetlabs/concat no stdlib puppetlabs/stdlib no -cosmos git@github.com:SUNET/puppet-cosmos.git yes -ufw git://github.com/SUNET/puppet-module-ufw.git yes +cosmos https://github.com/SUNET/puppet-cosmos.git yes +ufw https://github.com/SUNET/puppet-module-ufw.git yes apt puppetlabs/apt no vcsrepo puppetlabs/vcsrepo no xinetd puppetlabs/xinetd no #golang elithrar/golang yes -python git://github.com/SUNET/puppet-python.git yes -hiera-gpg git://github.com/SUNET/hiera-gpg.git no +python https://github.com/SUNET/puppet-python.git yes +hiera-gpg https://github.com/SUNET/hiera-gpg.git no ``` This is an example file - the first field is the name of the module, the second is From f939c526e656c21e60727658c1c7e3cea5bcd1cb Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sat, 27 Aug 2016 17:05:11 +0200 Subject: [PATCH 003/111] Changed tag from eduid-cosmos to the more generic cosmos-ops --- cosmos.conf | 2 +- global/overlay/usr/local/sbin/cosmos_vm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cosmos.conf b/cosmos.conf index 32f286ac..46ef4486 100644 --- a/cosmos.conf +++ b/cosmos.conf @@ -1,2 +1,2 @@ -tag="eduid-cosmos" +tag="cosmos-ops" #repo=git://override-repo-URL diff --git a/global/overlay/usr/local/sbin/cosmos_vm b/global/overlay/usr/local/sbin/cosmos_vm index bf275766..498ef431 100755 --- a/global/overlay/usr/local/sbin/cosmos_vm +++ b/global/overlay/usr/local/sbin/cosmos_vm @@ -9,8 +9,8 @@ hostname="default" bridge="br0" cpus="1" mem="1024" -repo="git://code.mnt.se/mnt-cosmos.git" -tag="eduid-cosmos" +repo="https://yourhost/myproj-cosmos.git" +tag="cosmos-ops" ip="" gateway="" netmask="" From b2afd3482ed899e8483226b136c9b28c7d486c36 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sat, 27 Aug 2016 17:05:55 +0200 Subject: [PATCH 004/111] Changed cosmos-modules.conf to reflect the changes in doc --- global/overlay/etc/puppet/cosmos-modules.conf | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/global/overlay/etc/puppet/cosmos-modules.conf b/global/overlay/etc/puppet/cosmos-modules.conf index e1ef0e55..991a570a 100644 --- a/global/overlay/etc/puppet/cosmos-modules.conf +++ b/global/overlay/etc/puppet/cosmos-modules.conf @@ -5,14 +5,14 @@ # in the Cosmos trust list. That is why all the URLs point to forked # versions in the SUNET github organization. # -concat git://github.com/SUNET/puppetlabs-concat.git yes sunet-* -stdlib git://github.com/SUNET/puppetlabs-stdlib.git yes sunet-* -cosmos git://github.com/SUNET/puppet-cosmos.git yes sunet-* -ufw git://github.com/SUNET/puppet-module-ufw.git yes sunet_dev-* -apt git://github.com/SUNET/puppetlabs-apt.git yes sunet_dev-* -vcsrepo git://github.com/SUNET/puppetlabs-vcsrepo.git yes sunet-* -xinetd git://github.com/SUNET/puppetlabs-xinetd.git yes sunet-* -hiera-gpg git://github.com/SUNET/hiera-gpg.git yes sunet-* +concat https://github.com/SUNET/puppetlabs-concat.git yes sunet-* +stdlib https://github.com/SUNET/puppetlabs-stdlib.git yes sunet-* +cosmos https://github.com/SUNET/puppet-cosmos.git yes sunet-* +ufw https://github.com/SUNET/puppet-module-ufw.git yes sunet_dev-* +apt https://github.com/SUNET/puppetlabs-apt.git yes sunet_dev-* +vcsrepo https://github.com/SUNET/puppetlabs-vcsrepo.git yes sunet-* +xinetd https://github.com/SUNET/puppetlabs-xinetd.git yes sunet-* +hiera-gpg https://github.com/SUNET/hiera-gpg.git yes sunet-* # # Alternate sources you might or might not want to use: #concat puppetlabs/concat no @@ -21,16 +21,16 @@ hiera-gpg git://github.com/SUNET/hiera-gpg.git yes sunet-* #apt puppetlabs/apt no #vcsrepo puppetlabs/vcsrepo no #xinetd puppetlabs/xinetd no -#cosmos git://github.com/leifj/puppet-cosmos.git yes -#python git://github.com/SUNET/puppet-python.git yes sunet-* -#erlang git://github.com/SUNET/garethr-erlang.git yes sunet-* -#rabbitmq git://github.com/SUNET/puppetlabs-rabbitmq.git yes sunet_dev-* -#pound git://github.com/SUNET/puppet-pound.git yes sunet_dev-* -#augeas git://github.com/SUNET/puppet-augeas.git yes sunet-* -#bastion git://github.com/SUNET/puppet-bastion.git yes sunet-* -#postgresql git://github.com/SUNET/puppetlabs-postgresql.git yes sunet_dev-* -#munin git://github.com/SUNET/ssm-munin.git yes sunet-* -#nagios git://github.com/SUNET/puppet-nagios.git yes sunet-* -#staging git://github.com/SUNET/puppet-staging.git yes sunet-* -#apparmor git://github.com/SUNET/puppet-apparmor.git yes sunet-* -#docker git://github.com/SUNET/garethr-docker.git yes sunet_dev-* +#cosmos https://github.com/SUNET/puppet-cosmos.git yes +#python https://github.com/SUNET/puppet-python.git yes sunet-* +#erlang https://github.com/SUNET/garethr-erlang.git yes sunet-* +#rabbitmq https://github.com/SUNET/puppetlabs-rabbitmq.git yes sunet_dev-* +#pound https://github.com/SUNET/puppet-pound.git yes sunet_dev-* +#augeas https://github.com/SUNET/puppet-augeas.git yes sunet-* +#bastion https://github.com/SUNET/puppet-bastion.git yes sunet-* +#postgresql https://github.com/SUNET/puppetlabs-postgresql.git yes sunet_dev-* +#munin https://github.com/SUNET/ssm-munin.git yes sunet-* +#nagios https://github.com/SUNET/puppet-nagios.git yes sunet-* +#staging https://github.com/SUNET/puppet-staging.git yes sunet-* +#apparmor https://github.com/SUNET/puppet-apparmor.git yes sunet-* +#docker https://github.com/SUNET/garethr-docker.git yes sunet_dev-* From b9ec2c8f69f6d263053ae15f0111e329970996e9 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sat, 27 Aug 2016 17:53:18 +0200 Subject: [PATCH 005/111] Various improvements made to bump-tag at SUNET --- bump-tag | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/bump-tag b/bump-tag index b163569b..0bfe7be4 100755 --- a/bump-tag +++ b/bump-tag @@ -4,16 +4,23 @@ set -e test -f cosmos.conf && . ./cosmos.conf +echo "Fetching any updates from server:" git pull +echo "" deftag=`basename $PWD` tagpfx=${tag:="$deftag"} last_tag=`git tag -l "${tagpfx}-*"|sort|tail -1` -git tag -v $last_tag +echo "Verifying last tag $last_tag:" +(git tag -v $last_tag | grep ^gpg:) || true +# again to not mask exit status of git with grep +git tag -v $last_tag > /dev/null 2>&1 +echo "" -PAGER=cat git diff $last_tag..master +echo "Differences between tag $last_tag and what you are about to sign:" +PAGER=cat git diff --color $last_tag..master iter=1 ok= @@ -29,8 +36,13 @@ while test -z "$ok"; do esac done -echo using new tag $this_tag -echo ONLY SIGN IF YOU APPROVE OF VERIFICATION AND DIFF ABOVE +if [ "$deftag" != "$tagpfx" ]; then + echo -e "Using new tag \e[94m$this_tag\e[0m according to pattern in cosmos.conf" +else + echo "Using new tag \e[94m$this_tag\e[0m" +fi + +echo -e "\e[1mONLY SIGN IF YOU APPROVE OF VERIFICATION AND DIFF ABOVE\e[0m" # GITTAGEXTRA is for putting things like "-u 2117364A" From 2e2cc75029b70e3e8042dbc656a773b610c3b345 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sat, 27 Aug 2016 23:51:58 +0200 Subject: [PATCH 006/111] Do not fetch puppet deb over http, instead do as seen in eduID --- global/pre-tasks.d/030puppet | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/global/pre-tasks.d/030puppet b/global/pre-tasks.d/030puppet index cdc99892..ef080161 100755 --- a/global/pre-tasks.d/030puppet +++ b/global/pre-tasks.d/030puppet @@ -9,9 +9,13 @@ stamp="$COSMOS_BASE/stamps/puppet-tools-v01.stamp" if ! test -f $stamp -a -f /usr/bin/puppet; then codename=`lsb_release -c| awk '{print $2}'` - wget -c http://apt.puppetlabs.com/puppetlabs-release-${codename}.deb - dpkg -i puppetlabs-release-${codename}.deb - rm -f puppetlabs-release-${codename}.deb* + puppetdeb="$COSMOS_REPO/apt/puppetlabs-release-${codename}.deb" + if [ ! -f $puppetdeb ]; then + echo "$0: Puppet deb for release $codename not found in $COSMOS_REPO/apt/" + echo " Get it from https://apt.puppetlabs.com/ and put it in the Cosmos repo." + exit 1 + fi + dpkg -i $puppetdeb apt-get update apt-get -y install puppet-common From b56799bcc65d8b7022781d40f338eaa89e64588c Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sat, 27 Aug 2016 23:52:14 +0200 Subject: [PATCH 007/111] Added automatic re-import of expired keys as in eduID --- global/post-tasks.d/015cosmos-trust | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/global/post-tasks.d/015cosmos-trust b/global/post-tasks.d/015cosmos-trust index 447d8755..74835e06 100755 --- a/global/post-tasks.d/015cosmos-trust +++ b/global/post-tasks.d/015cosmos-trust @@ -4,11 +4,19 @@ if [ -z "$COSMOS_KEYS" ]; then COSMOS_KEYS=/etc/cosmos/keys fi +# Install new keys discovered in the $COSMOS_KEYS directory for k in $COSMOS_KEYS/*.pub; do - fp=`cosmos gpg --with-colons --with-fingerprint < $k| awk -F: '$1 == "pub" {print $5}'` - cosmos gpg --with-colons --fingerprint | grep -q ":$fp:" || cosmos gpg --import < $k + fp=`cosmos gpg --with-colons --with-fingerprint < $k | awk -F: '$1 == "pub" {print $5}'` + fp_in_db=`cosmos gpg --with-colons --fingerprint | grep ":$fp:"` + if [ "x`echo $fp_in_db | grep '^pub:e:'`" != "x" ]; then + echo "$0: Key expired, will re-import it from $k" + cosmos gpg --fingerprint $fp + fi + # The removal of any ^pub:e: entrys means to ignore expired keys - thereby importing them again. + echo $fp_in_db | grep -v "^pub:e:" | grep -q ":$fp:" || cosmos gpg --import < $k done +# Delete keys no longer present in $COSMOS_KEYS directory for fp in `cosmos gpg --with-colons --fingerprint | awk -F: '$1 == "pub" {print $5}'`; do seen="no" for k in $COSMOS_KEYS/*.pub; do From a94f87c41c94425fef5cd1f3d713f526e089ad1d Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sun, 28 Aug 2016 00:08:37 +0200 Subject: [PATCH 008/111] Support fetching of git over https:// as seen in eduID --- global/post-tasks.d/018packages | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/global/post-tasks.d/018packages b/global/post-tasks.d/018packages index 3e2e26e2..9370e102 100755 --- a/global/post-tasks.d/018packages +++ b/global/post-tasks.d/018packages @@ -24,8 +24,8 @@ if [ -f $CONFIG ]; then # First pass to clone any new modules, and update those marked for updating. grep -E -v "^#" $CONFIG | ( while read module src update pattern; do - # We only support git:// urls atm - if [ "${src:0:6}" = "git://" ]; then + # We only support git:// urls and https:// urls atm + if [ "${src:0:6}" = "git://" -o "${src:0:8}" = "https://" ]; then if [ ! -d $CACHE_DIR/scm/$module ]; then git clone -q $src $CACHE_DIR/scm/$module elif [ -d $CACHE_DIR/scm/$module/.git ]; then @@ -63,7 +63,7 @@ if [ -f $CONFIG ]; then grep -E -v "^#" $CONFIG | ( while read module src update pattern; do # We only support git:// urls atm - if [ "${src:0:6}" = "git://" ]; then + if [ "${src:0:6}" = "git://" -o "${src:0:8}" = "https://" ]; then # Verify git tag cd $CACHE_DIR/scm/$module TAG=$(git tag -l "${pattern:-*}" | sort | tail -1) From b81de45e773ae9cce84b1b0c11d6bc169ce63cfd Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sun, 28 Aug 2016 00:11:33 +0200 Subject: [PATCH 009/111] Show diff of puppet changes as seen in eduID --- global/post-tasks.d/030puppet | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global/post-tasks.d/030puppet b/global/post-tasks.d/030puppet index 67429497..b94b9ffe 100755 --- a/global/post-tasks.d/030puppet +++ b/global/post-tasks.d/030puppet @@ -1,13 +1,13 @@ #!/bin/sh if [ "x$COSMOS_VERBOSE" = "xy" ]; then - args="--verbose" + args="--verbose --show_diff" else args="--logdest=syslog" fi if [ -f /usr/bin/puppet -a -d /etc/puppet/manifests ]; then for m in `find /etc/puppet/manifests -name \*.pp`; do - puppet apply $args < $m + puppet apply $args $m done fi From 5fbd6f5b94ef67c70fc4bb5c13ab96b3df3b9591 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sun, 28 Aug 2016 00:13:10 +0200 Subject: [PATCH 010/111] Do not run update and autoremove on all machines at the same time as seen in eduID --- global/post-tasks.d/099autoremove | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/global/post-tasks.d/099autoremove b/global/post-tasks.d/099autoremove index 2cc69968..74b0aa43 100755 --- a/global/post-tasks.d/099autoremove +++ b/global/post-tasks.d/099autoremove @@ -1,4 +1,6 @@ #!/bin/sh -apt-get -qq update -apt-get -qq -y autoremove +if (( $RANDOM % 20 == 0)); then + apt-get -qq update + apt-get -qq -y autoremove +fi From 55da5cd7eaa5bd20ba98411bacbf6d89ba9d1feb Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sun, 28 Aug 2016 17:12:10 +0200 Subject: [PATCH 011/111] Included ft improvement to able to specify tag for bump-tag Also changed from #!/bin/sh -> #!/bin/bash since echo -e is not supported in sh --- bump-tag | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bump-tag b/bump-tag index 0bfe7be4..440809ba 100755 --- a/bump-tag +++ b/bump-tag @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -e @@ -8,7 +8,11 @@ echo "Fetching any updates from server:" git pull echo "" -deftag=`basename $PWD` +if [ "x$1" = "x" ]; then + deftag=`basename $PWD` +else + deftag="$1" +fi tagpfx=${tag:="$deftag"} last_tag=`git tag -l "${tagpfx}-*"|sort|tail -1` @@ -39,7 +43,7 @@ done if [ "$deftag" != "$tagpfx" ]; then echo -e "Using new tag \e[94m$this_tag\e[0m according to pattern in cosmos.conf" else - echo "Using new tag \e[94m$this_tag\e[0m" + echo -e "Using new tag \e[94m$this_tag\e[0m" fi echo -e "\e[1mONLY SIGN IF YOU APPROVE OF VERIFICATION AND DIFF ABOVE\e[0m" From f6fe9285908764791613bd78b3a2aa683f910814 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Sun, 28 Aug 2016 21:22:48 +0200 Subject: [PATCH 012/111] new upstream release of cosmos that includes ln5 fixes for https remotes along with a verified version of puppetlabs-release-trusty.deb --- addhost | 2 +- .../overlay/etc/cosmos/apt/bootstrap-cosmos.sh | 2 +- .../overlay/etc/cosmos/apt/cosmos_1.2-2_all.deb | Bin 11724 -> 0 bytes .../overlay/etc/cosmos/apt/cosmos_1.5-1_all.deb | Bin 0 -> 11514 bytes .../cosmos/apt/puppetlabs-release-trusty.deb | Bin 0 -> 9554 bytes global/overlay/usr/local/sbin/cosmos_vm | 4 ++-- 6 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 global/overlay/etc/cosmos/apt/cosmos_1.2-2_all.deb create mode 100644 global/overlay/etc/cosmos/apt/cosmos_1.5-1_all.deb create mode 100644 global/overlay/etc/cosmos/apt/puppetlabs-release-trusty.deb diff --git a/addhost b/addhost index 033c16b0..1c34ce3d 100755 --- a/addhost +++ b/addhost @@ -45,7 +45,7 @@ if [ ! -d $cmd_hostname ]; then fi if [ "$cmd_do_bootstrap" = "yes" ]; then - scp apt/cosmos_1.2-2_all.deb apt/bootstrap-cosmos.sh root@$cmd_hostname: + scp apt/cosmos_1.5-1_all.deb apt/bootstrap-cosmos.sh root@$cmd_hostname: ssh root@$cmd_hostname ./bootstrap-cosmos.sh $cmd_fqdn $rrepo $rtag ssh root@$cmd_hostname cosmos update ssh root@$cmd_hostname cosmos apply diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index 28cbde09..613b74e7 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -23,7 +23,7 @@ fi set -x apt-get -y install rsync git-core wget -dpkg -i cosmos_1.2-2_all.deb +dpkg -i cosmos_1.5-1_all.deb if ! test -d /var/cache/cosmos/repo; then cosmos clone "$cmd_repo" diff --git a/global/overlay/etc/cosmos/apt/cosmos_1.2-2_all.deb b/global/overlay/etc/cosmos/apt/cosmos_1.2-2_all.deb deleted file mode 100644 index 9fe44341db2cea253a51baf6cada57e99a7e9a16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11724 zcmaiabxa-5vnK9N@uJ1u?c(n4?(XgvC{ogi*3^l~%+|@&&6kXfjE#evlbwx&mz$G}jP>9C|7bQ= zR&LIJXaB~3iwP1tGb@t0vy+FLvjek-sT;Gk-~Zp9kDcd#>`7w~ApRpz(3k1P&Kukq z1NXJcq7S}pGODGF=J>dbkX?{l(H6jbx;t9;B#DsHjn0!uQYxy; z!1nF0#k%_zYj|n;(Ie}>d+sDDp~t0nXt)m`n~yt$po6@5H%0UVkW>nYARnuKv!# zB${3q$DVXu#IcJ15O&e`aP$Kd7SzID27V1ZuZX$^_vGm4uLfm&^8WgE#jjFhe^0Jg z627Hpxe?GCp=JcMDcvk-*FwDdsR78eh*Y;7NBxTub;P52-dEi@9+Fy@pM0#&B6R%Py%&NPt{|^s1{hMA}k5 zz~c7lNa^`<`y)t$V)}U2?5h+h3Gs(DVh@V4{E|1;JtAoaUs}JH!|`I=+|n@>R+I!q zk__elHQnOe^E`%K7(viNKpYa<|CbxsSh-pMD?gYZ{a@HNgg3yRcphWE zMcbI0tg@HDq$(AGu$9BBQj@@#N@kR$oETMvQhN}%Aoh2z{4?vueX)Of8nva)cw9wO zX)U>+-UPC?O2L3a@*~;a0v_M1ns^`04F(ymXVMa2UrI^v0`TX#F(pk}SYGD)$fL9K+%(u&1q?;<7WXa5wptVn6(YDJ z0Tv6H-$prLdjoH%M?P)(WF^<6H|r3yI;*9LO;D<#uB>gqVc)z!F^ZLwrRlJ!DNHsH9nToju)Z4HyCDJ`jDoprP6RTs70rgO*1%+4@ zHS5Y*gL<*(6BOL6lggi z(+2nGc!*fc%~#4yb5O#?JfWaJqeR8J!uoQlVf9cYBV;El6eUkVn9frpY1^qmoCk|E zI(K+0s|+nNkkOK{!`&pj!b(KENJ*Fk742ox;2sf>5bP4;{3VDFmkf^#mwH(@)q#P` zq7ZpSALoX&g-1|PuyM&UP;BRet5iqjO^IQn%a?%o8I7QewTnC^QP{6h&mjU0zZeDc z6XP!v4!H><8KinLp}qntzDJ53Cp{iB47Xgi5Fvf_PohgsE3=GStI;uM)*JOn(?Cw;;v;R}sW^ra;x*~8lQC-KHMjB?++>FAsgjQZrTnB| zq#6y2Ol(2IBHtsz zN1N6d#n4)xU6;?#ibo(a7ZNksG~0}by4D}<%ra(D$;`9ZPGk0j3*dhah3GY)eYC@m z_922ckbO`<94~Xb!r#G~!$9c9@@x}C)Z!!jny<0gUnJF-rFK!55D6oLpanu!=&&uY zm`+Cdd0C{%vHrq9z^}1aV?DtLB5xOw2YHQ-6p0Q*zGzK0y|lPEC_s%9>G17;(aF;* z2_k*p3ky{c6UV-Rl6GW2v1%0M=^Kd@_85mZrVLZP&hJ;=|J8kx5kuI5>Y^5(0zFPQ~Ara$^UlY zKfV}yemH}xeCWmE#1j)R%BS7(!9o_%P*?|)q7dq;CV9vJIRSj?LQ)7mdX?vQJP4Jn zS5ob&zjR;}aKB)|Ef~o5dGBkIO#QcD3R0yL+`sv@GdK}42!sO@d|2OrS!%)J;@{%( zPH^hW1{+5;cug)+GCm5^6AbT&*a*I!9S~`B#)VSqNRHwU29RBV6d@})0m%8C_W2BV|=S088p*l;8Fn=vqxI`z1Il8x-Dud*g z#P-^JwrgfN&6|#66KQKZ-NCz2DzNbj!vZCm{-8gx0-Kd4A0h>6@YViEqznYipN9eG z<$ewSpAaJL1o1%e5Mx33+*}dNkF~RF2a`;lcA|4a*DDucA;1=e5h{^$f;*Kbac2MJ z*fLEw4U_%V-7|^Don8<&lHxNEaCe!P`C5<#&iaoMw)(`wy^?3K-kf5FKvmDm>&Vq# zEd5(?*~P7KQvE!H)ZRUNJaUmDT~lb(!G=!KZH8k}dO?aE14 z7)b?D`aQ1wYV5${d}oAk+>)03x802oU&zSM)!w*s_OJ5r;wisTnoXMugUHdxKVvdo zM}ARK=!Gwry&A87k3So(^=s5U>Z-kgG$?tTpO7^wdpxCa4{248NI=qo$a_?$f5A{K z^kJ)_)B#g}co*LmXxIzIK&tS80NMNfy@_k!k^f)}1qA#GijAwrQz<46n&ZW+p zTm27TpTSe_@AFFgA)^WFo2hz?H=ek3pQb8Ll__%=m)~e%)L_A2>WsS z&vhj*-`d&>5nBcPy(*}N`FI%+%10B~3j7{u*qCp@zPZIf&4$Jw`fKTC6+I19tvU@#oy?`&Y6kz%sgCt8iDnJB^mND|%qxDm zFY7Xv#A7XRl7}#Q^4Ua$c_z*9kyCA{5oD zqHRp2im*a-?;@yuw;jb5$;1_q864^6)D5*R?QE{F^MRPFlAQVqppb;3C)_vmhlTlbHGN`c109*qGmJhabDwx^Jay%hJ zew{z8UaM(YD{KZNWJy225Jdt^2#6`T$Rk2=7aZY6cZqD zfZT<78R@7HkqY55+w^(@WYeifk@~ z>aJVl@xt2qOXLEE2dEJAT2-e3A~V_e8caZ0G|RV)5D?@%-K8+=Gza@{9)VwmtHgXN zD~$#6T^glkT&-UQ2?rYU z1bgVVLn!hY)G+3~6jp^tlsQSkAgvZ?ht9wr<^52xJu%<8amK7tfe0C*N6`~EOI)zd zwb?KRV#JUD?!M@kLIlDe($+1cBFEByQ?eCrN|pSy(0&tyR*#|0k}HuSENhomCo56? z2Ex)Nzut=mjfTF2nyW%mn}=$l1)>X;PFdK}G$7UaOE4RM{qZPp z053q?uR%iu47~#3rKOKPz!{7EB0p|u5AP))>LtMOPx0mN;PCkPSa8BCXxImgf4yTI z4;~J0+O59Wj^S`ntdy%YK42B6E{O2C7Q8hc?W!j<4`xue#&1mz{*-26Iaym@8E_n# zhQJAbeMUijVltc=Tm(Z0LJf6_Y||s=NTNti(TdNyg>v;&J-BD@{ROVIfJE%dIIA%p z8m1>v+i>u{Q>&Y-!zo5G^d|iHc{Av#Xo(s+3134w{2Q$e!DGBS(&)wHQWIqY0^gkVOZNb1^Xh?{8X$N`1 zkHeiNwpk31-6!Xl*qbJ4A5@||69^>~579-Ry+)$q@og1DjEUMwE(BSH0`$ivO1&Ra z#$2`XJG$br%VU}`@EnLq!S;uQy$#XKT$~# zw&(_}$l5^Hya@3D*4H=0!~{G-Mwf`Qc+-426b1PXTFk8c4!FemPU2;LJYo+-BKWE@ zXqev?C%#J77e#!Cw2C1#VsWRrU3TkR@O~(CkxxvQy%NmaOHA@L%2HuT8)&$&<)npB zp9L!&=vilN!&8Kxj7Y# zO+;Te{Nab1Cw&|d4hbx329Rl}n5#A77nVu1<8?L2QklwU6y}8FmXv-)z}L7Im(n@6 zD;ueXi4Kn7*(JuJwHGaNrBWVMUvhb_)q^91l1o(A}~61cuK+vHoNQ+$YWrTxghm$q&AuxNTk(+eIFW@n?ZO8zVZL47u3-^X$#1D z1w8!*7H$SL1ZZO5;(W1ad`tPGsmGK`#}W1kw!|rdctXL??#iXN!O=^@gx7EHt%?m2 znss2V8!lCWU2X!|zw9U`fNk7|cH+Qjhx=f_U3e_`zeyb!`B<1fs<{H)>Us5G-_?WW zD+BZzy&1jYI^fS(UYwUlYMngkdwdBXZLIvBNC)aLcFQ(NDu})Dcf^#X7}JpEO%N%< z*nC;Aed#!d==HG5)E9QXdiNjUzEV$Nc0&?+(G;nKd=JMAbzCy0E~zIrYA|<@^Ji($ zNQ9gad!I4E2%CP>m`O+~DJZ@Sr7)X0VQuvgy~!@(O*k(Jut3+M$7woqqtmCNA`~rF zaHIk{Vbcy!4I2@u<;>I~fb8yOR-AvnkQrHEz?Sg!rT!hv+3$iBPQTxZ4u?L40#^J^RDxj(?z z&$0g~ZLarg=Z%d@8JKjOQB@Nq0i!GdQg;Su$KipxSXK%RoDze;kM`;`HRnc0?l7!g7=2EhlX^h&A%Y` zhdJ-R0JgUVr_UH!%;$n4;1{gu1u))xzZ2EV;RDOxqQ`%M11^3;zm1D;OeqZ#`UH}J zkmrn42*GhQB0E4Ifg{kEo$Mv`inOr(ikgDpd<}PhlCtUqOh%M+!uyg_z-b1ge*||> z8?T59o#>tXyJUXDVr>h%Q?2e3dv%tV*b?u%Qt>uy9Ud{eJL)M17oVr{!&aB{-C3)! zu8xBjUD1qPzdhhd*QnrU)9uYM&+4jkUlC~LRKU%CtEZ#}S&Iu)Wns2^mCbD!p1{p= z*uV`Oq~jO%^EhLQPunRVJbWua_F=flPP_#)qdP>!tnnP0y7V3%U&){e336GX@_hj| z9cC($c)y&Re}1_%*k&@|sM`VA2Mtd@=}0(U7<_L!6&`+hj*Y$`AS6*0JRpVhrw4$D zb1$;4`0Gnm47!$fy6Wxaow=G5FJW0d<#wbWT%>lA?`H#A$65tDi=HPtexLI-{KM79 zyUlJtd@_Br<`mVIju%$!l^^oEnzq{c1SK7vxj@VI?hvn6x5IIg&c*`zVtw!Tro;P1Q;a$L)+B;PSQK6b zmweX4gtwCep2*YnoihTzAJ+y;oXh;t@*i}LU;bJ==`1LvwJiA$r)ed1>#kK4zl~l8 zzO^zPI~=dXuhH!52vt#G_g<_s=DPK*j@EM&8wVA1I#1;czdKgYkh=DAAO4>ClT0kS zjV>8=+>aj3O6s;&VRIQV1j>{0dUiwZm_;VZ@YZd+JMoo!?UhW45hSfol?uNW7LUyn zZyndOc9b10$T0wxrR+0=OqC68r94}X)fy6Qn)2Bj>deVY8l`uHSFDN3I;h2YDS3W& z!EKIi{_*t1GkX@;E)(2!2aNgNhDjT9-PL&)i*DFXpqCS`V+i%V($k2spO0smGgzWc zbpSm;j&tosum1a2p!{}Q$M4+a?>U|iU2O7y47<#qCc@{;;lSDLAS2UF%rja(n@@o| zHTeu7#Rfb;p7}`ePeM>T2!0Mu$5rv5LC+tSutH&32PP{t@bPPN|#vKhL~O7f!nu z4+BZEDjKHkgpOY$WbydZbvh^WpGjNpwjVWC{?-zEt)@RDf7So<-g+pOzodyJ=-Avb zGUHzp5I&R6gb>tud7ik%Ru?%t+33K2nyqZ)ozbP3!;+nfow#)5Wo zbbqI$=-7YHc>9Q6d%y44^7+ol893*>!5_qtcHK==qg1oG0MMB_H);o!2fh_{mhd;? z;>?h?Y`JN*6TQOYCdWK?^bk2L+c@PHKlY0H1E>FR-xjV=&y*o}Pdg7I${jOho23o3 ztpUo<8(yg%7qv?D9eR&B2QSxt;Cau{Tjp)MMRNcdt2i8FXOM?0{1ccaZFt`mDuT}a z@@O%iHUk}&&7Pi&vp03K+72#ihNuFA&UpEDTYK$lr>{gVYw`(#MsO{xbk;ZCm6D0# z`kZ@OMz#sKFUyxb4&o6=a$Jfx4n|#n^5n_^Tf51~T=atiti<~)&pQutF4pjI{oH=- zGv#~+iV?T1Z@rMS?&ZA2d1nhMUtfGKK3?-&JGXOpQfXp*w4sU;Q7ttxCAw-`5G6@=cqLI`1+jQ zx3=uE{-G6eJUY#A;adWRwuf)f=8}*{PttE+?ziFgS8Na#G|(lwv*aP1dD!9PV}6OO zd`K7mh0=$+)$}J$ZmXBg$4V7ksCr&OYMaVw1z|r5^RyZSsUI{`h_oVPyLzPf_D%C_ zr=+RE)R$E|$o_6ms-!V9KSxvBL zfDb4qW7ia5&^%S*-t;rSPGOqPEB?*6`*M(uAcv^$p;Jw`Wg}+7>9OU+iKILnb9 zxYOAOI&Cp8>e%=}r~i(jy*2rLr;~|3+vz}fl-@_b5>fB$BKe}9B`rz|!IxP1$JtpLnO(&`KESY-Uk8vd$C)se$ zG%Vg^9GZKSx!5f9k(96to1Ug`^mGW_y_MZbZCF|%`6#9)zK-=te<;c{Ew-rtqR6sVH2aj>g50$uB4^mh)Paiy)aFKd2tdt#8^5x^za@jbA2 zVPWIU{glspc8t=Ih^J8Glk@(ic)lQC$=Uu?z}|!?#+<_#`#8m~H*dA4_mbYTmxQG} zAHn2bRdW-!D|@qW37JiBk8AyO0=Uy<0DoV_KKokF#}{Ae+g~?z&+*u1Y@7bmaw@lK z%{j>6Hl|X&MN8>XP{1faU6`R>>-t65{1$AO4Y*X40Naj<&qk2s@g~``1wD7xhdTnC zatOD2tO}~2v9ozdJYDC~5*sKhuVS^QD!zX)Q*Dvv46M62>demZlyA#iW=#-hMqJz6UeKdI>pXs6 z-4>6IZ0%UDTrMg%d_na>N>E6CZ$Vcmu2%_ex*RHc{Q08~w749tjOp`U0 z*dUFM=jUnMISEUKmfShg5At*{xO&P)j~?+-Z!vy|>CV{N8|WqCxR(-|?sxGY917&y zx^2iOMo_?0>K5p(n5n&YNbq$B7=74rrV*bI2~}B{G`+47WQe2b8fS0sx{mjysQ8=K3R^=mGX6boMg4$7aD;3IBg6; zfZMGoZLXE}n)YFhy$yZ#>1*df35ewB!udK&*E4Rbxy87A zBYe$^#O7eUjlf@B!rX%GcIh7coHyCcy0gP2ur*G`fH%r)qUOECdx`hhP-gGu%O3tO zTMp^JA0pqZ4bSrUIchaa8Vu_gZr&5Ln1pZOW@B2&4EYr+i8x|fw-}Y9qBl76( zYTbP_M$d)`p3z8|AM|&M(=~r}2*Ez~wC6kYGj!S?*#A@$yE!LeF@DMmkVzKTebCvk zuu`*=D}Nsu>N-;1dF}Om+PFF)jTGLwdzyCc?smVT(boZlStrEyoAWj0Xj*MQxlB$b z+;3WL8Wz1*@vJT~TPWml@6YyCZ4#L8A4g5}e0@T9G(5VJIk@Z$unl$Wo@qEp(0RCD zV|jhcsF?zBiUlu{b6jRq(siM&37bn~>;&OsX>vMOSe!M64#*UgR{$jIlcI@bv%0=?Yphr;o<`I5w88h1h|E` zh2QRTGW!Av(ejeKbp5m!yS?`}TuWw+<&{|YULqEckA(!YS^jX|>$!PtQqA6bQ_1cy z?<~x$f4(E%6Sd|oG%236xf;nEItOt8_m(V~t_vX1=`Cb;?tjXEWh>eO~HZ-wqKd+i#XQ#m!zn)s#Bg4EM?-k4FIP z!z7H20G+2>kvT*&3J2~#w!>GauedqREj|mkbLYS7K2KZe&Jvl{KW+C>T9RtHuN-;S z;o$^&U%jPyZKX09*<&4D`*N=hT`%7lRej@`-r6XW_)X?5|5Vyr((JCO>&=3U9+(zX zdWp7oxKke?Ew~sFzY(5*z&*OtSonM&SWx3%1FwW0TUW>k4_HQG!KY-R~ECE}cOQ&+w|DeCS&+cK#+ z80y%#S8w3mabC^gasm3i9pv<1dj)s}iD$qQ!Bw>F9lCztu5I}*&k0#L?D-J;#i!d~ zkb(N%cEhueuSa))0V}wXEIv>hH`*l`0)4{nM-k!hQ(+_7BC2`^;XN8^3?jm9q<@8t zbm~vNcELaClKy#f(bhPm@s_4jr3O(kyqzrC_P z6)%b}0^JZTbgM0^M#85q%tAh=(R(ychd+H~vv_pW!JgR9bwS@_-0*a0owDORlFO9a z6b-vQo|gOAS$xs8!D%^pO(s1lhj%;Zykq?BWcsuvUMMV0IHa=)+%Y;vEE(B3n#TiZ zEh9|(?{{Y;Sr)<@XI8Vdc&{z%^#s1_;hgQ8t;In(JdS7)3NpZj2NO5b?8A>EM8}^S zI=QBKS5bIEr+#;MAqgW~%Ojb#>O{E#haXO=F5NJZ-NKG`?sPU~B?mW(N*a1o;!FTO zlvV)&zs+jooK22JUjM*0REO&r(aB8XW%P^|F{u@5&^tKj$qEu2~8ikkA~249q4OL1+mc4U5IA35(G1yV!GnovpbYAm91qLvic4Cfgeq zmEq06^MqSCj2E8s1l{GiKj1vWC-dr!m#_-t--a75%3I#uK|AKE6_)SVMwhn^ba}Y0 zR0gB>E&-{_j6IgSszf7&C-oNtfAj(c#Jf=Y_^%90mW3i0S4Nsi^Dw-w`4_xwMPbrFKmpGnh6BFe=`XAK;dT@DWtc1V5xh$+Y0}X?Enx;ClT)QVupK|;V7teNd z8ju>tm-D>?bA$r#9;|AVNo=yt=<>2#uYGD6nYPyVhPJFek0^JLQIxKQ_qQgK_F9yg z3A|_RqCe$BzZwVd+CRa`?PGhsHaAF@zRI22&QX1HDmQ$#<2^fbS{2IUxWD5VLN|UH z<#L&b*y+s{=xdh$uv1_G&vKx15#O|)?&q`z5uUYpNil=u`xgRmdj(>Ji#fIBswJPavCPt??Xn8{X4PzF>2v zo2{e1`>)T2F{a!AZ6bDuf4tB>-oS&`2)`yP5InZ8sU08xaN9iAc}hak@RG5J*Vf(p zt@HUjyeNj}oq4mBt?l|(OUn1|U-i9ny$nf;cB|qhYqzib$0fpYOv&N}HfUU(KuJbm z7SCfWa4^5U!5Q47c5f}0H1+pH9dZ_WME}#!2u4^+wxOQ;7`-*4BNUJsn$e3{9);@O~c*J7Z)_OIv2?%O^%Lt}SODtjdHELcy&pDy8U(gm5k`G876B_k z(ezb)vV38EF=mS515f0FKUi|XOVzH3A)alfWdy_>vF4J4W6Wzr7l8az=yD_`0WPQ!-CPnmx@^~Ea04ZLxM#FPy}x{R{+uyr8UouFRP=D zuu;wR#}S2`{qhj6$Qdo8hBgU*&{{mT2^IXorQ^xLB2S_SReC-|}yMLTMUh(M7UL-JQ@o79+6TuLTquTcVi zb@G9U3e|8^>3OgTZ4n>o3)QN04eUkDLoP`Sj~|BhN!%WFw7e zovG9_r1{A#v_WmRK~h=wJx0p#z{AaxIxM6gB$MS$1)=2kgeC0cQ{nT%1|eQza9mjo zID){i%XZh$I~=OZQynNzXZ58<3@+S_~Heng@d6g?Ee-COSR_hSwu6`NM=4>M0o6IpAvIMD`oS}oQHqXnB?JA*dx8Ga&m}_!44yemj$y>SNr{ItN@vf;5SbOCt+*1E^d0mUr0^J^;4GDk zoSJvT!j##N`lKY8o{lOjvu(;aCD*eoPFB!5s}i|A_js=g481~+kUQm(y_z`bc zJv{ll2wobRt+ZA69Hu-byPn7h2gUAB2)$43IrO#f_b-NnfIOi+R$RJYS1!EGHm=PO zU$s~dbV3}w%)B}a$;qDmhx1R%>fz<>Wqx%TIJ6|-^vSAlvtHXQU1{ZEHi@2`5sc&D z9YDxyqA1YO&0|Z4pf7`!BBc*))CT0JAWzKx(>am|J17eG(^HtFLLbb$qGRB{mD0gH z?8y_3%HB(cvJ5gpJaOa?7BXx0e~%`D*g%>nd~y6il1*#MoGp}tMl0q`WhiXg=ENE$ dt6+welKG30n(hC!Jp2uY94H9{LEJz<{4X-u7fJvC diff --git a/global/overlay/etc/cosmos/apt/cosmos_1.5-1_all.deb b/global/overlay/etc/cosmos/apt/cosmos_1.5-1_all.deb new file mode 100644 index 0000000000000000000000000000000000000000..28cdaadecb4cc29e60287a551ce98d7ada04e972 GIT binary patch literal 11514 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/dev/null mcopy -i ${seed} ${meta_data} ::meta-data 2>/dev/null -mcopy -i ${seed} /etc/cosmos/apt/bootstrap-cosmos.sh /etc/cosmos/apt/cosmos_1.2-2_all.deb :: +mcopy -i ${seed} /etc/cosmos/apt/bootstrap-cosmos.sh /etc/cosmos/apt/cosmos_1.5-1_all.deb :: mv ${seed} /var/lib/libvirt/images/ virsh pool-refresh default From 5cd4e5b0cfb5abada19fb06793745f2fce800316 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Fri, 30 Sep 2016 17:58:56 +0200 Subject: [PATCH 013/111] Verified puppetlabs-release-xenial.deb for Ubuntu 16.04 --- .../cosmos/apt/puppetlabs-release-xenial.deb | Bin 0 -> 13662 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 global/overlay/etc/cosmos/apt/puppetlabs-release-xenial.deb diff --git a/global/overlay/etc/cosmos/apt/puppetlabs-release-xenial.deb b/global/overlay/etc/cosmos/apt/puppetlabs-release-xenial.deb new file mode 100644 index 0000000000000000000000000000000000000000..ca14b2531e29025a9a85692893a5531fa6d7a1f7 GIT binary patch literal 13662 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 literal 0 HcmV?d00001 From 4972eefdcc35d504cced13884372610c9605087d Mon Sep 17 00:00:00 2001 From: Leif Johansson Date: Thu, 2 Feb 2017 15:37:32 +0100 Subject: [PATCH 014/111] ny run-cosmos --- global/overlay/usr/local/bin/run-cosmos | 54 ++++++++++++++++++------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/global/overlay/usr/local/bin/run-cosmos b/global/overlay/usr/local/bin/run-cosmos index a37d49f1..5f2cbc1e 100755 --- a/global/overlay/usr/local/bin/run-cosmos +++ b/global/overlay/usr/local/bin/run-cosmos @@ -1,22 +1,46 @@ -#!/bin/sh +#!/bin/bash # # Simplify running cosmos, with serialization if flock is available. # -set -e +readonly PROGNAME=$(basename "$0") +readonly LOCKFILE_DIR=/tmp +readonly LOCK_FD=200 -FLOCK=`which flock` +lock() { + local prefix=$1 + local fd=${2:-$LOCK_FD} + local lock_file=$LOCKFILE_DIR/$prefix.lock -if [ -x "$FLOCK" ]; then - ($FLOCK --exclusive --wait 60 9 || exit 1 - cosmos $* update - cosmos $* apply - )9>/var/lock/run-cosmos -else - cosmos $* update - cosmos $* apply + # create lock file + eval "exec $fd>$lock_file" + + # acquier the lock + flock -n $fd \ + && return 0 \ + || return 1 +} + +eexit() { + local error_str="$@" + + echo $error_str + exit 1 +} + +main () { + lock $PROGNAME || eexit "Only one instance of $PROGNAME can run at one time." + cosmos $* update + cosmos $* apply + + touch /var/run/last-cosmos-ok.stamp + + find /var/lib/puppet/reports/ -type f -mtime +10 | xargs rm -f +} + +main $* + +if [ -f /cosmos-reboot ]; then + rm -f /cosmos-reboot + reboot fi - -touch /var/run/last-cosmos-ok.stamp - -find /var/lib/puppet/reports/ -type f -mtime +10 | xargs rm -f From e0505b4100d87519b469d3512f825f8c3fe81c6a Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Wed, 26 Apr 2017 16:03:02 +0200 Subject: [PATCH 015/111] Uppdated puppetlabs-release-xenial.deb to version 1.1.0-4 called puppetlabs-release-pc1_1.1.0-4xenial_all.deb at https://apt.puppetlabs.com. --- .../cosmos/apt/puppetlabs-release-xenial.deb | Bin 13662 -> 13646 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/global/overlay/etc/cosmos/apt/puppetlabs-release-xenial.deb b/global/overlay/etc/cosmos/apt/puppetlabs-release-xenial.deb index ca14b2531e29025a9a85692893a5531fa6d7a1f7..fdb4cd490515c499d453d516652b3013f3ad05a5 100644 GIT binary patch literal 13646 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 literal 13662 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 From 29bf83125a686a76ccf79a09d02f2c1242451cc7 Mon Sep 17 00:00:00 2001 From: Gijutsu Date: Wed, 23 Aug 2017 16:26:11 +0200 Subject: [PATCH 016/111] Added info on how to bootstrap a machine that is not yet in DNS --- docs/cosmos-puppet-ops.mkd | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/cosmos-puppet-ops.mkd b/docs/cosmos-puppet-ops.mkd index 3c7bfcd9..48ce4921 100644 --- a/docs/cosmos-puppet-ops.mkd +++ b/docs/cosmos-puppet-ops.mkd @@ -258,7 +258,7 @@ Adding a host Bootstrapping a host is done using the 'addhost' command: ``` -# ./addhost [-b] $fqdn +# ./addhost -b $fqdn ``` The -b flag causes addhost to attempt to bootstrap cosmos on the remote host using @@ -275,6 +275,12 @@ The boostrap process will create a cron-job on $fqdn that runs every 15 minutes. This should be a good starting point for your domain. Now you may want to add some 'naming rules'. +To bootstrap a machine that is not yet configured in DNS, use the following options: + +``` +# ./addhost -b -n $fqdn-to-add-later-in-dns -- IP-address +``` + Defining naming rules --------------------- From ffdb1aa4d1a0fd67ecf1f357a7887fdc44afb96a Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Thu, 9 Nov 2017 14:31:27 +0100 Subject: [PATCH 017/111] Updated year and version in cosmos-puppet-ops.mkd --- docs/cosmos-puppet-ops.mkd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cosmos-puppet-ops.mkd b/docs/cosmos-puppet-ops.mkd index 48ce4921..0d8515bf 100644 --- a/docs/cosmos-puppet-ops.mkd +++ b/docs/cosmos-puppet-ops.mkd @@ -1,5 +1,5 @@ % System Operations using Cosmos & Puppet -% Leif Johansson / SUNET / 2013 / v0.0.4 +% Leif Johansson / SUNET / 2017 / v0.0.5 Introduction From f096b2274dc2e9f19c9c61b7e87bc05fff85f031 Mon Sep 17 00:00:00 2001 From: Fredrik Pettai Date: Thu, 15 Feb 2018 23:48:16 +0100 Subject: [PATCH 018/111] Add more puppet debs Add (puppet)support for more deb-based releases. Add sha1sum + realname for all debs downloaded from apt.puppet.com --- global/overlay/etc/cosmos/apt/SHA1SUM | 6 ++++++ .../cosmos/apt/puppetlabs-release-jessie.deb | Bin 0 -> 16950 bytes .../cosmos/apt/puppetlabs-release-stretch.deb | Bin 0 -> 13706 bytes .../cosmos/apt/puppetlabs-release-yakkety.deb | Bin 0 -> 13932 bytes 4 files changed, 6 insertions(+) create mode 100644 global/overlay/etc/cosmos/apt/SHA1SUM create mode 100644 global/overlay/etc/cosmos/apt/puppetlabs-release-jessie.deb create mode 100644 global/overlay/etc/cosmos/apt/puppetlabs-release-stretch.deb create mode 100644 global/overlay/etc/cosmos/apt/puppetlabs-release-yakkety.deb diff --git a/global/overlay/etc/cosmos/apt/SHA1SUM b/global/overlay/etc/cosmos/apt/SHA1SUM new file mode 100644 index 00000000..663473cc --- /dev/null +++ b/global/overlay/etc/cosmos/apt/SHA1SUM @@ -0,0 +1,6 @@ +c8c591fc7bcc54c4a7cf35759ee35ef11936b9a8 puppetlabs-release_1.0-12_all.deb +d69b9a005a604a6739dbcf2524de53fdd93f135f puppetlabs-release_1.1-1_all.deb +761a213324fd1bfa7bc76dc46d6a58b29f17b1a3 puppetlabs-release-pc1_1.1.0-4xenial_all.deb +cfead6a6242a5407ea45ca9dd148c0e694df9ff8 puppetlabs-release-pc1_1.1.0-5yakkety_all.deb +f0c104d210956b4a934076b49fb124107237a4ca puppetlabs-release-pc1_1.1.0-5stretch_all.deb + diff --git a/global/overlay/etc/cosmos/apt/puppetlabs-release-jessie.deb b/global/overlay/etc/cosmos/apt/puppetlabs-release-jessie.deb new file mode 100644 index 0000000000000000000000000000000000000000..2ca91fac5c491dd91104c22c163d4e6cddcc5965 GIT binary patch literal 16950 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 BEKC3Z literal 0 HcmV?d00001 diff --git a/global/overlay/etc/cosmos/apt/puppetlabs-release-stretch.deb b/global/overlay/etc/cosmos/apt/puppetlabs-release-stretch.deb new file mode 100644 index 0000000000000000000000000000000000000000..b5ce6d690232ff71d29f217fd148722d7526bc42 GIT binary patch literal 13706 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

6hSPk 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 r@C$W6YybV0fOPI&NR*2$1pyuW?+*pYNf)SKmU literal 0 HcmV?d00001 diff --git a/global/overlay/etc/cosmos/apt/puppetlabs-release-yakkety.deb b/global/overlay/etc/cosmos/apt/puppetlabs-release-yakkety.deb new file mode 100644 index 0000000000000000000000000000000000000000..197e5b992cab624e49a91ccc2928e456b38245bf GIT binary patch literal 13932 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 z Date: Wed, 25 Apr 2018 12:03:50 +0200 Subject: [PATCH 019/111] Merge of edit-secrets from nunoc-ops --- edit-secrets | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/edit-secrets b/edit-secrets index 742321fa..149715e0 100755 --- a/edit-secrets +++ b/edit-secrets @@ -1,17 +1,36 @@ #!/bin/bash +# +# Script to edit secrets for a host. +# +# This script is used by an administrator on his/hers local machine. The +# general principle is for this script to ssh to the target host, decrypt +# the secrets and allow changes to be made, and then fetch the encrypted +# secrets from the host and add it to the Cosmos repository on the +# administrators machine. +# +# Funnily enough, this script will execute itself (with the argument +# '--on-host') on the target host in order to do the decryption etc. Don't +# allow this to confuse you and everything will be fine. +# set -e umask 077 LAST_OUTPUT_FILENAME="/root/.last_edit-secrets_output" +if [[ "x${EDITOR}" != "x" ]]; then + declare -r REMOTE_EDITOR="${EDITOR}" +else + declare -r REMOTE_EDITOR='/usr/bin/vim.tiny' +fi + if [ "x$1" = "x" ]; then echo "Syntax: $0 -l OR fqdn" exit 1 fi if [ "x$1" != "x-l" ]; then - host=$1 + host=$(echo $1 | sed -e 's!/*$!!') # remove trailing slashes if [ ! -d $host ]; then echo "$0: No host-directory for '$host' found - execute in top-level cosmos dir" @@ -19,12 +38,12 @@ if [ "x$1" != "x-l" ]; then fi # Execute this very script, on a remote host - TMPFILE=$(mktemp) + TMPFILE=$(mktemp edit-secrets.$$.XXXXXXX) if [ ! -f $TMPFILE ]; then echo "$0: Failed creating temporary file" exit 1 fi - TMPFILE2=$(mktemp) + TMPFILE2=$(mktemp edit-secrets.$$.XXXXXXX) if [ ! -f $TMPFILE2 ]; then echo "$0: Failed creating temporary file" exit 1 @@ -32,7 +51,7 @@ if [ "x$1" != "x-l" ]; then trap "rm -f $TMPFILE $TMPFILE2" EXIT - ssh -t root@$host /var/cache/cosmos/repo/edit-secrets -l + ssh -t root@$host EDITOR="${REMOTE_EDITOR}" /var/cache/cosmos/repo/edit-secrets -l scp -q root@$host:$LAST_OUTPUT_FILENAME $TMPFILE if grep ^"STATUS=UPDATED" $TMPFILE > /dev/null; then @@ -98,8 +117,11 @@ fi trap "rm -f $TMPFILE $TMPFILE2" EXIT -if [ ! -f "$GNUPGHOME/secring.gpg" ]; then - echo "$0: Secret keyring $GNUPGHOME/secring.gpg does not exist." +if ! $GPG --list-secret-keys | grep -q ^"sec\s"; then + echo "$0: Secret key does not exist (in $GNUPGHOME)." + echo "" + echo "Generate it with /var/cache/cosmos/model/pre-tasks.d/040hiera-gpg" + echo "" exit 1 fi @@ -126,10 +148,16 @@ else # figure out this hosts gpg key id recipient=$($GPG --list-secret-key | grep ^sec | head -1 | awk '{print $2}' | cut -d / -f 2) + save_to="`hostname --fqdn`/overlay${SECRETFILE}" echo "" ( echo "STATUS=UPDATED" echo "" ) > $LAST_OUTPUT_FILENAME $GPG --output - --armor --recipient $recipient --sign --encrypt $TMPFILE >> $LAST_OUTPUT_FILENAME + echo "" + echo "GPG output saved in $LAST_OUTPUT_FILENAME - save it in Cosmos as" + echo "" + echo " $save_to" + echo "" fi From 761963ba2f0892096c708c6f880398a11ebc1956 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 15 Jan 2019 13:06:48 +0100 Subject: [PATCH 020/111] add colors, sanity checking and support for Ubuntu 18.04 --- global/post-tasks.d/015cosmos-trust | 90 ++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 20 deletions(-) diff --git a/global/post-tasks.d/015cosmos-trust b/global/post-tasks.d/015cosmos-trust index 74835e06..f9f46676 100755 --- a/global/post-tasks.d/015cosmos-trust +++ b/global/post-tasks.d/015cosmos-trust @@ -1,28 +1,78 @@ -#!/bin/sh +#!/bin/bash + +gnupg_show_options='--import --import-options show-only,import-minimal' +if [[ $(lsb_release -sr | awk -F . '{ print $1 }') -le 16 ]]; then + # gpg on Ubuntu 16 and less is gnupg < 2, which doesn't have --import-options show-only + # but on the other hand defaults to this mode (https://dev.gnupg.org/T2943) + gnupg_show_options='--dry-run' +fi if [ -z "$COSMOS_KEYS" ]; then COSMOS_KEYS=/etc/cosmos/keys fi -# Install new keys discovered in the $COSMOS_KEYS directory -for k in $COSMOS_KEYS/*.pub; do - fp=`cosmos gpg --with-colons --with-fingerprint < $k | awk -F: '$1 == "pub" {print $5}'` - fp_in_db=`cosmos gpg --with-colons --fingerprint | grep ":$fp:"` - if [ "x`echo $fp_in_db | grep '^pub:e:'`" != "x" ]; then - echo "$0: Key expired, will re-import it from $k" - cosmos gpg --fingerprint $fp - fi - # The removal of any ^pub:e: entrys means to ignore expired keys - thereby importing them again. - echo $fp_in_db | grep -v "^pub:e:" | grep -q ":$fp:" || cosmos gpg --import < $k +bold='\e[1m' +reset='\e[0m' +red='\033[01;31m' + +# Associative array of fingerprints in the GPG keyring +declare -A KEYRING + +# Associative array with expired keys in the GPG keyring +declare -A EXPIRED + +# associative array with non-expired keys found in $COSMOS_KEYS directory +declare -A SEEN + +# Load information about all keys present in the GPG keyring +for line in $(cosmos gpg --with-colons --fingerprint | awk -F: '$1 == "pub" { print $2 ":" $5 }'); do + IFS=':' read -r expired fp <<< $line + KEYRING[$fp]='1' + if [[ $expired == 'e' ]]; then + EXPIRED[$fp]=1 + fi done -# Delete keys no longer present in $COSMOS_KEYS directory -for fp in `cosmos gpg --with-colons --fingerprint | awk -F: '$1 == "pub" {print $5}'`; do - seen="no" - for k in $COSMOS_KEYS/*.pub; do - cosmos gpg --with-colons --with-fingerprint < $k | grep -q ":$fp:" && seen="yes" - done - if [ "x$seen" = "xno" ]; then - cosmos gpg --yes --batch --delete-key $fp || true - fi +# Install new keys discovered in the $COSMOS_KEYS directory +for k in $COSMOS_KEYS/*.pub; do + if [[ ! -s $k ]]; then + # Silently ignore empty files + continue + fi + pubkeys_in_file=$(cosmos gpg ${gnupg_show_options} \ + --with-colons --with-fingerprint --quiet < $k \ + | grep "^pub:") + non_expired_pubkeys_in_file=$(echo ${pubkeys_in_file} | awk -F: '$2 != "e" { print $0 }') + if [[ ! $non_expired_pubkeys_in_file ]]; then + echo -e "$0: ${red}Ignoring file with expired pubkey: ${k}${reset}" + continue + fi + + fp=$(echo ${pubkeys_in_file} | awk -F: '{print $5}') + + # Remember that we saw fingerprint $fp in file $k + SEEN[$fp]=$k + + if [[ ! ${KEYRING[$fp]} ]]; then + echo -e "$0: ${bold}Importing new key ${fp}${reset} from ${k}" + cosmos gpg --import < $k + elif [[ ${EXPIRED[$fp]} ]]; then + echo -e "$0: ${bold}Re-importing expired key ${fp}${reset} from ${k}" + cosmos gpg --import < $k + fi +done + +if [[ ! ${#SEEN[@]} ]]; then + echo "$0: ${red}NO trusted keys found in directory ${COSMOS_KEYS} - aborting${reset}" + echo "(this is probably a syntax problem with the gpg commands in this script)" + exit 1 +fi + +# Delete keys no longer present (or expired) in $COSMOS_KEYS directory +for fp in ${!KEYRING[@]}; do + if [[ ! ${SEEN[$fp]} ]]; then + echo -e "$0: ${bold}Deleting key${reset} ${fp} not present (or expired) in ${COSMOS_KEYS}" + cosmos gpg --fingerprint $fp + cosmos gpg --yes --batch --delete-key $fp || true + fi done From a2e4c5372f791ba963af18c790c282cfe8b93b7f Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 15 Jan 2019 13:07:47 +0100 Subject: [PATCH 021/111] add support for a second, local puppet module config file --- global/post-tasks.d/018packages | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/global/post-tasks.d/018packages b/global/post-tasks.d/018packages index 9370e102..4e109d05 100755 --- a/global/post-tasks.d/018packages +++ b/global/post-tasks.d/018packages @@ -1,6 +1,7 @@ #!/bin/bash CONFIG=${CONFIG:=/etc/puppet/cosmos-modules.conf} +LOCALCONFIG=${LOCALCONFIG:=/etc/puppet/cosmos-modules_local.conf} CACHE_DIR=/var/cache/puppet-modules MODULES_DIR=${MODULES_DIR:=/etc/puppet/cosmos-modules} export GNUPGHOME=/etc/cosmos/gnupg @@ -13,7 +14,7 @@ stage_module() { git archive --format=tar --prefix=$1/ $2 | (cd $CACHE_DIR/staging/ && tar xf -) } -if [ -f $CONFIG ]; then +if [ -f $CONFIG -o $LOCALCONFIG ]; then if [ ! -d $MODULES_DIR ]; then mkdir -p $MODULES_DIR fi @@ -21,8 +22,11 @@ if [ -f $CONFIG ]; then mkdir -p $CACHE_DIR/{scm,staging} fi + test -f $CONFIG || CONFIG='' + test -f $LOCALCONFIG || LOCALCONFIG='' + # First pass to clone any new modules, and update those marked for updating. - grep -E -v "^#" $CONFIG | ( + grep -h -E -v "^#" $CONFIG $LOCALCONFIG | sort | ( while read module src update pattern; do # We only support git:// urls and https:// urls atm if [ "${src:0:6}" = "git://" -o "${src:0:8}" = "https://" ]; then @@ -60,7 +64,7 @@ if [ -f $CONFIG ]; then # Second pass to verify the signatures on all modules and stage those that # have good signatures. - grep -E -v "^#" $CONFIG | ( + grep -h -E -v "^#" $CONFIG $LOCALCONFIG | sort | ( while read module src update pattern; do # We only support git:// urls atm if [ "${src:0:6}" = "git://" -o "${src:0:8}" = "https://" ]; then @@ -95,9 +99,9 @@ if [ -f $CONFIG ]; then # Cleanup removed puppet modules from CACHE_DIR for MODULE in $(ls -1 $CACHE_DIR/staging/); do - if ! grep -E -q "^$MODULE\s+" $CONFIG; then - rm -rf $CACHE_DIR/{scm,staging}/$MODULE - fi + if ! grep -h -E -q "^$MODULE\s+" $CONFIG $LOCALCONFIG; then + rm -rf $CACHE_DIR/{scm,staging}/$MODULE + fi done # Installing verified puppet modules From bf1b476d9a5579c674ad2095f2d9c5481f4cb7d0 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 15 Jan 2019 13:08:39 +0100 Subject: [PATCH 022/111] colors --- global/post-tasks.d/018packages | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/global/post-tasks.d/018packages b/global/post-tasks.d/018packages index 4e109d05..bd97488c 100755 --- a/global/post-tasks.d/018packages +++ b/global/post-tasks.d/018packages @@ -8,6 +8,9 @@ export GNUPGHOME=/etc/cosmos/gnupg python -c "import yaml" 2>/dev/null || apt-get -y install python-yaml +bold='\e[1m' +reset='\e[0m' +red='\033[01;31m' stage_module() { rm -rf $CACHE_DIR/staging/$1 @@ -43,16 +46,14 @@ if [ -f $CONFIG -o $LOCALCONFIG ]; then continue fi else - echo "ERROR: Ignoring non-git repository" + echo -e "${red}ERROR: Ignoring non-git repository${reset}" continue fi elif [[ "$src" =~ .*:// ]]; then - echo "ERROR: Don't know how to install '$src'" + echo -e "${red}ERROR: Don't know how to install '${src}'${reset}" continue else - echo "WARNING" - echo "WARNING - attempting UNSAFE installation/upgrade of puppet-module $module from $src" - echo "WARNING" + echo -e "${bold}WARNING - attempting UNSAFE installation/upgrade of puppet-module ${module} from ${src}${reset}" if [ ! -d /etc/puppet/modules/$module ]; then puppet module install $src elif [ "$update" = "yes" ]; then @@ -72,26 +73,24 @@ if [ -f $CONFIG -o $LOCALCONFIG ]; then cd $CACHE_DIR/scm/$module TAG=$(git tag -l "${pattern:-*}" | sort | tail -1) if [ "$COSMOS_VERBOSE" = "y" ]; then - echo "" - echo "Checking signature on tag ${TAG} for puppet-module $module" + echo -e "Checking signature on puppet-module:tag ${bold}${module}:${TAG}${reset}" fi if [ -z "$TAG" ]; then - echo "ERROR: No git tag found for pattern '${pattern:-*}' on puppet-module $module" + echo -e "${red}ERROR: No git tag found for pattern '${pattern:-*}' on puppet-module ${module}${reset}" continue fi git tag -v $TAG &> /dev/null if [ $? == 0 ]; then - if [ "$COSMOS_VERBOSE" = "y" ]; then - # short output on good signature - git tag -v $TAG 2>&1 | grep "gpg: Good signature" - fi + #if [ "$COSMOS_VERBOSE" = "y" ]; then + # # short output on good signature + # git tag -v $TAG 2>&1 | grep "gpg: Good signature" + #fi # Put archive in staging since tag verified OK stage_module $module $TAG else - echo "################################################################" - echo "FAILED signature check on puppet-module $module" - echo "################################################################" + echo -e "${red}FAILED signature check on puppet-module ${module}${reset}" git tag -v $TAG + echo '' fi fi done From 08979437b5d6cfdf769e76b60563f2231577aa05 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 15 Jan 2019 13:09:24 +0100 Subject: [PATCH 023/111] add support for file:// urls --- global/post-tasks.d/018packages | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/global/post-tasks.d/018packages b/global/post-tasks.d/018packages index bd97488c..79c33483 100755 --- a/global/post-tasks.d/018packages +++ b/global/post-tasks.d/018packages @@ -31,8 +31,8 @@ if [ -f $CONFIG -o $LOCALCONFIG ]; then # First pass to clone any new modules, and update those marked for updating. grep -h -E -v "^#" $CONFIG $LOCALCONFIG | sort | ( while read module src update pattern; do - # We only support git:// urls and https:// urls atm - if [ "${src:0:6}" = "git://" -o "${src:0:8}" = "https://" ]; then + # We only support git://, file:/// and https:// urls at the moment + if [ "${src:0:6}" = "git://" -o "${src:0:8}" = "file:///" -o "${src:0:8}" = "https://" ]; then if [ ! -d $CACHE_DIR/scm/$module ]; then git clone -q $src $CACHE_DIR/scm/$module elif [ -d $CACHE_DIR/scm/$module/.git ]; then @@ -67,8 +67,8 @@ if [ -f $CONFIG -o $LOCALCONFIG ]; then # have good signatures. grep -h -E -v "^#" $CONFIG $LOCALCONFIG | sort | ( while read module src update pattern; do - # We only support git:// urls atm - if [ "${src:0:6}" = "git://" -o "${src:0:8}" = "https://" ]; then + # We only support git://, file:/// and https:// urls at the moment + if [ "${src:0:6}" = "git://" -o "${src:0:8}" = "file:///" -o "${src:0:8}" = "https://" ]; then # Verify git tag cd $CACHE_DIR/scm/$module TAG=$(git tag -l "${pattern:-*}" | sort | tail -1) From e069bd4f0642726dbd6f91250ed8f989346e0fa3 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 15 Jan 2019 13:10:46 +0100 Subject: [PATCH 024/111] remove unused reports that take about 2s per run to create --- global/post-tasks.d/020reports | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/global/post-tasks.d/020reports b/global/post-tasks.d/020reports index 091a236e..c6033bb5 100755 --- a/global/post-tasks.d/020reports +++ b/global/post-tasks.d/020reports @@ -1,4 +1,5 @@ #!/bin/sh -rm -f /var/run/facts.json -facter -p -y > /var/run/facts.yaml +#rm -f /var/run/facts.json +#facter -p -y > /var/run/facts.yaml +rm -f /var/run/facts.yaml From bc027359d10eaa9794f7c982b1ea398a2d876fb2 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 15 Jan 2019 13:11:15 +0100 Subject: [PATCH 025/111] show which manifest is applied to lessen confusion --- global/post-tasks.d/030puppet | 1 + 1 file changed, 1 insertion(+) diff --git a/global/post-tasks.d/030puppet b/global/post-tasks.d/030puppet index b94b9ffe..af450057 100755 --- a/global/post-tasks.d/030puppet +++ b/global/post-tasks.d/030puppet @@ -8,6 +8,7 @@ fi if [ -f /usr/bin/puppet -a -d /etc/puppet/manifests ]; then for m in `find /etc/puppet/manifests -name \*.pp`; do + test "x$COSMOS_VERBOSE" = "xy" && echo "$0: Applying Puppet manifest $m" puppet apply $args $m done fi From 5eeaa2e3ff8172b486522ccb7d24c623935f797b Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 15 Jan 2019 13:12:07 +0100 Subject: [PATCH 026/111] noninteractive to not block when removing packages --- global/post-tasks.d/099autoremove | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/global/post-tasks.d/099autoremove b/global/post-tasks.d/099autoremove index 74b0aa43..c3c809ca 100755 --- a/global/post-tasks.d/099autoremove +++ b/global/post-tasks.d/099autoremove @@ -1,4 +1,6 @@ -#!/bin/sh +#!/bin/bash + +export DEBIAN_FRONTEND='noninteractive' if (( $RANDOM % 20 == 0)); then apt-get -qq update From fc3d3294ed3de90442bbc96d2b23f2b141e0f7f8 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 15 Jan 2019 13:12:41 +0100 Subject: [PATCH 027/111] stage reboots across sites --- global/post-tasks.d/999reboot | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/global/post-tasks.d/999reboot b/global/post-tasks.d/999reboot index 2ed9fa7a..e0a05e1d 100755 --- a/global/post-tasks.d/999reboot +++ b/global/post-tasks.d/999reboot @@ -1,5 +1,26 @@ -#!/bin/sh +#!/bin/bash -if [ -f /var/run/reboot-required -a -f /etc/cosmos-automatic-reboot ]; then - reboot +if [[ -f /var/run/reboot-required && -f /etc/cosmos-automatic-reboot ]]; then + + if [[ $HOSTNAME =~ -tug- ]]; then + # Reboot hosts in site TUG with 15 seconds delay (enough to manually + # cancel the reboot if logged in and seeing the 'emerg' message broadcasted to console) + sleep=15 + elif [[ $HOSTNAME =~ -fre- ]]; then + # reboot hosts in site FRE with 15+180 to 15+180+180 seconds delay + sleep=$(( 180 + ($RANDOM % 180))) + elif [[ $HOSTNAME =~ -lla- ]]; then + # reboot hosts in site LLA with 15+180+180 to 15+180+180+180 seconds delay + sleep=$(( 375 + ($RANDOM % 180))) + else + # reboot hosts in any other site with 15 to 315 seconds delay + sleep=$(( 15 + ($RANDOM % 300))) + fi + + logger -p local0.emerg -i -t cosmos-automatic-reboot "Rebooting automatically in $sleep seconds (if /var/run/reboot-required still exists)" + sleep $sleep + if [ -f /var/run/reboot-required ]; then + logger -p local0.crit -i -t cosmos-automatic-reboot "Rebooting automatically" + reboot + fi fi From f25a6af71280de14e815d48ce5d4eb84e42e4072 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 15 Jan 2019 13:18:22 +0100 Subject: [PATCH 028/111] use python3 --- global/overlay/etc/puppet/cosmos_enc.py | 4 ++-- global/post-tasks.d/018packages | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/global/overlay/etc/puppet/cosmos_enc.py b/global/overlay/etc/puppet/cosmos_enc.py index 131d161f..852fb25c 100755 --- a/global/overlay/etc/puppet/cosmos_enc.py +++ b/global/overlay/etc/puppet/cosmos_enc.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys import yaml @@ -14,5 +14,5 @@ if os.path.exists(db_file): with open(db_file) as fd: db.update(yaml.load(fd)) -print yaml.dump(dict(classes=db['classes'].get(node_name,dict()),parameters=dict(roles=db.get('members',[])))) +print(yaml.dump(dict(classes=db['classes'].get(node_name,dict()),parameters=dict(roles=db.get('members',[]))))) diff --git a/global/post-tasks.d/018packages b/global/post-tasks.d/018packages index 79c33483..ee1889f6 100755 --- a/global/post-tasks.d/018packages +++ b/global/post-tasks.d/018packages @@ -6,7 +6,8 @@ CACHE_DIR=/var/cache/puppet-modules MODULES_DIR=${MODULES_DIR:=/etc/puppet/cosmos-modules} export GNUPGHOME=/etc/cosmos/gnupg -python -c "import yaml" 2>/dev/null || apt-get -y install python-yaml +# /etc/puppet/cosmos_enc.py needs the YAML module +python3 -c "import yaml" 2>/dev/null || apt-get -y install python3-yaml bold='\e[1m' reset='\e[0m' From 59fb131af6429395575630e59aeba76e8892480c Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Tue, 29 Jan 2019 23:27:56 +0100 Subject: [PATCH 029/111] Added the scripts prepair-iaas-debian and prepair-iaas-ubuntu That are used to prepaire a new host based on cloud image for addhost --- prepair-iaas-debian | 24 ++++++++++++++++++++++++ prepair-iaas-ubuntu | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100755 prepair-iaas-debian create mode 100755 prepair-iaas-ubuntu diff --git a/prepair-iaas-debian b/prepair-iaas-debian new file mode 100755 index 00000000..d368e6a4 --- /dev/null +++ b/prepair-iaas-debian @@ -0,0 +1,24 @@ +#!/bin/bash +ip="${1}" + +if [[ -z "${ip}" ]]; then + echo "Please specify a cloud image host that the script should do the following on:" + echo " #1 enable root-login" + echo " #2 remove the default user" + echo " #3 run apt-get update and dist-upgrade without interaction" + echo " #4 reboot to start using the new kernel, updated packages etc." + exit 1 +fi + +set -x + +ssh "debian@${ip}" sudo cp -r /home/debian/.ssh /root/ +ssh "debian@${ip}" sudo chown -R root:root /root/.ssh +ssh "debian@${ip}" sudo chmod 700 /root/.ssh +ssh "debian@${ip}" sudo chmod 600 /root/.ssh/authorized_keys +ssh "root@${ip}" deluser debian +ssh "root@${ip}" rm /home/debian -rf +ssh "root@${ip}" rm /etc/sudoers.d/* +ssh "root@${ip}" DEBIAN_FRONTEND="noninteractive" apt-get -y update +ssh "root@${ip}" DEBIAN_FRONTEND="noninteractive" apt-get -o Dpkg::Options::="--force-confnew" --fix-broken --assume-yes dist-upgrade +ssh "root@${ip}" reboot diff --git a/prepair-iaas-ubuntu b/prepair-iaas-ubuntu new file mode 100755 index 00000000..3fdff8d0 --- /dev/null +++ b/prepair-iaas-ubuntu @@ -0,0 +1,24 @@ +#!/bin/bash +ip="${1}" + +if [[ -z "${ip}" ]]; then + echo "Please specify a cloud image host that the script should do the following on:" + echo " #1 enable root-login" + echo " #2 remove the default user" + echo " #3 run apt-get update and dist-upgrade without interaction" + echo " #4 reboot to start using the new kernel, updated packages etc." + exit 1 +fi + +set -x + +ssh "ubuntu@${ip}" sudo cp -r /home/ubuntu/.ssh /root/ +ssh "ubuntu@${ip}" sudo chown -R root:root /root/.ssh +ssh "ubuntu@${ip}" sudo chmod 700 /root/.ssh +ssh "ubuntu@${ip}" sudo chmod 600 /root/.ssh/authorized_keys +ssh "root@${ip}" deluser ubuntu +ssh "root@${ip}" rm /home/ubuntu -rf +ssh "root@${ip}" rm /etc/sudoers.d/* +ssh "root@${ip}" DEBIAN_FRONTEND="noninteractive" apt-get -y update +ssh "root@${ip}" DEBIAN_FRONTEND="noninteractive" apt-get -o Dpkg::Options::="--force-confnew" --fix-broken --assume-yes dist-upgrade +ssh "root@${ip}" reboot From 108e261bdd9d76b546849c70fdde39cc0d754439 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Tue, 29 Jan 2019 23:29:33 +0100 Subject: [PATCH 030/111] Added the script host-puppet-conf-test that is used to test changes without commiting them --- host-puppet-conf-test | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100755 host-puppet-conf-test diff --git a/host-puppet-conf-test b/host-puppet-conf-test new file mode 100755 index 00000000..e72008c7 --- /dev/null +++ b/host-puppet-conf-test @@ -0,0 +1,44 @@ +#!/bin/bash +set +x +HOSTNAME=$1 +PUPPET_ARGS=$2 + +if [ -z "$HOSTNAME" ]; then + echo "Usage: $0 fqdn" + exit 1 +fi + +if [ ! -d "$HOSTNAME" ]; then + echo "$0: No host-directory for '$HOSTNAME' found - execute in top-level cosmos dir" + exit 1 +fi + +PUPPET_ARGS=${PUPPET_ARGS-"--verbose"} + +# Check if cosmos or puppet is already running on host +echo "Checking if puppet or cosmos is already running..." +ssh root@$HOSTNAME ps aux | egrep -v "grep|edit-secrets|gpg-agent" | egrep -q "cosmos|puppet" + +if [ $? -eq 1 ] +then + echo "Copying files to host..." + rsync -av --exclude '*~' global/overlay/etc/puppet/cosmos-rules.yaml root@$HOSTNAME:/etc/puppet/cosmos-rules.yaml + rsync -av --exclude '*~' global/overlay/etc/puppet/manifests/cosmos-site.pp root@$HOSTNAME:/etc/puppet/manifests/cosmos-site.pp + rsync -av --exclude '*~' global/overlay/etc/puppet/cosmos-db.yaml root@$HOSTNAME:/etc/puppet/cosmos-db.yaml + rsync -av --exclude '*~' global/overlay/etc/hiera/data/common.yaml root@$HOSTNAME:/etc/hiera/data/common.yaml + + # Test if the user has symlinked puppet-sunet correctly + # by first checking if the link exits and then whether + # or not the directory contains any files. + if [ -L global/overlay/etc/puppet/cosmos-modules/sunet ] && \ + [ -n "$(ls -A global/overlay/etc/puppet/cosmos-modules/sunet/*)" ] + then + rsync -av --delete --exclude '*~' global/overlay/etc/puppet/cosmos-modules/sunet/* root@$HOSTNAME:/etc/puppet/cosmos-modules/sunet/. + fi + + echo "Running puppet apply..." + ssh root@$HOSTNAME /usr/bin/puppet apply $PUPPET_ARGS /etc/puppet/manifests/cosmos-site.pp +else + echo "Cosmos or puppet already running. Exiting." + exit 1 +fi From c591d6fe4bfedb89d59a06f6a05f557201339e26 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Tue, 12 Feb 2019 16:20:54 +0100 Subject: [PATCH 031/111] Changed from re.search to re.match in db.py because re.search would match on broken regex, nodes that have a part of the name in common with other nodes etc. --- fabfile/db.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fabfile/db.py b/fabfile/db.py index 129aa502..67b6645d 100644 --- a/fabfile/db.py +++ b/fabfile/db.py @@ -17,7 +17,7 @@ def _load_db(): members = dict() for node_name in all_hosts: for reg,cls in rules.iteritems(): - if re.search(reg,node_name): + if re.match(reg,node_name): for cls_name in cls.keys(): h = members.get(cls_name,[]) h.append(node_name) @@ -28,10 +28,14 @@ def _load_db(): for node_name in all_hosts: node_classes = dict() for reg,cls in rules.iteritems(): - if re.search(reg,node_name): + if re.match(reg,node_name): node_classes.update(cls) classes[node_name] = node_classes + # Sort member lists for a more easy to read diff + for cls in members.keys(): + members[cls].sort() + return dict(classes=classes,members=members) _db = None From fba9ddb8f7168d6042505322271de4c7368e8fe5 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Tue, 12 Feb 2019 16:21:24 +0100 Subject: [PATCH 032/111] Changed example regex to make it a bit more apparent that the regex is to be used with re.match and not re.search --- global/overlay/etc/puppet/cosmos-rules.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/global/overlay/etc/puppet/cosmos-rules.yaml b/global/overlay/etc/puppet/cosmos-rules.yaml index d9dc495a..cffd8081 100644 --- a/global/overlay/etc/puppet/cosmos-rules.yaml +++ b/global/overlay/etc/puppet/cosmos-rules.yaml @@ -1,2 +1,3 @@ -'ns[0-9]?.mnt.se$': +# Note that the matching is done with re.match() +'^ns[0-9]?.mnt.se$': nameserver: From 3f56de1355036e471f3c82c44935a585879d3b20 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Wed, 13 Feb 2019 15:46:57 +0100 Subject: [PATCH 033/111] Force pseudo-terminal when running addhost so that addhost also works on Debian (also contains another small sync with nunoc-ops). --- addhost | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/addhost b/addhost index 1c34ce3d..f8cbe645 100755 --- a/addhost +++ b/addhost @@ -37,6 +37,11 @@ defrepo=`git remote -v | grep ${remote:="ro"} | grep fetch | awk '{print $2}'` rrepo=${repo:="$defrepo"} rtag=${tag:="changeme"} +if [ "x$rrepo" = "x" ]; then + echo "$0: repo not set in cosmos.conf and no git remote named 'ro' found" + exit 1 +fi + if [ ! -d $cmd_hostname ]; then cp -pr default $cmd_fqdn git add $cmd_fqdn @@ -46,7 +51,7 @@ fi if [ "$cmd_do_bootstrap" = "yes" ]; then scp apt/cosmos_1.5-1_all.deb apt/bootstrap-cosmos.sh root@$cmd_hostname: - ssh root@$cmd_hostname ./bootstrap-cosmos.sh $cmd_fqdn $rrepo $rtag - ssh root@$cmd_hostname cosmos update - ssh root@$cmd_hostname cosmos apply + ssh -t root@$cmd_hostname ./bootstrap-cosmos.sh $cmd_fqdn $rrepo $rtag + ssh -t root@$cmd_hostname cosmos update + ssh -t root@$cmd_hostname cosmos apply fi From 7c5a06304533ce5b67ce997334923692e593bccb Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Sun, 17 Mar 2019 13:26:44 +0100 Subject: [PATCH 034/111] gpg import with --no-tty With recent GPG versions, a TTY seems to be required to import keys. Since importing of keys need to work when running from cron, we pass --no-tty to those commands. This should mean that -t doesn't have to be passed to SSH on bootstrapping for new Debian hosts (tested on Raspbian). --- addhost | 6 +++--- global/post-tasks.d/015cosmos-trust | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addhost b/addhost index f8cbe645..2da1e36e 100755 --- a/addhost +++ b/addhost @@ -51,7 +51,7 @@ fi if [ "$cmd_do_bootstrap" = "yes" ]; then scp apt/cosmos_1.5-1_all.deb apt/bootstrap-cosmos.sh root@$cmd_hostname: - ssh -t root@$cmd_hostname ./bootstrap-cosmos.sh $cmd_fqdn $rrepo $rtag - ssh -t root@$cmd_hostname cosmos update - ssh -t root@$cmd_hostname cosmos apply + ssh root@$cmd_hostname ./bootstrap-cosmos.sh $cmd_fqdn $rrepo $rtag + ssh root@$cmd_hostname cosmos update + ssh root@$cmd_hostname cosmos apply fi diff --git a/global/post-tasks.d/015cosmos-trust b/global/post-tasks.d/015cosmos-trust index f9f46676..85649e88 100755 --- a/global/post-tasks.d/015cosmos-trust +++ b/global/post-tasks.d/015cosmos-trust @@ -55,10 +55,10 @@ for k in $COSMOS_KEYS/*.pub; do if [[ ! ${KEYRING[$fp]} ]]; then echo -e "$0: ${bold}Importing new key ${fp}${reset} from ${k}" - cosmos gpg --import < $k + cosmos gpg --no-tty --import < $k elif [[ ${EXPIRED[$fp]} ]]; then echo -e "$0: ${bold}Re-importing expired key ${fp}${reset} from ${k}" - cosmos gpg --import < $k + cosmos gpg --no-tty --import < $k fi done From b5d538ece105eb719ad6b9f8ef147e488b60ba19 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 4 Apr 2019 14:59:36 +0200 Subject: [PATCH 035/111] init, from eduid-ops --- global/pre-tasks.d/010fix-package-manager | 5 +++++ 1 file changed, 5 insertions(+) create mode 100755 global/pre-tasks.d/010fix-package-manager diff --git a/global/pre-tasks.d/010fix-package-manager b/global/pre-tasks.d/010fix-package-manager new file mode 100755 index 00000000..6d10426f --- /dev/null +++ b/global/pre-tasks.d/010fix-package-manager @@ -0,0 +1,5 @@ +#!/bin/sh + +# dpkg frequently breaks with automatic reboots. +# Make an attempt to get it back into working order. +dpkg --configure -a From d033b5890940531d8dbcafcbd0418e22ada2a5bd Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 14 Apr 2022 12:22:44 +0200 Subject: [PATCH 036/111] init, new version with better git update and signature validation --- .../apt/cosmos_1.5-2~sunet20220414_all.deb | Bin 0 -> 12080 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 global/overlay/etc/cosmos/apt/cosmos_1.5-2~sunet20220414_all.deb diff --git a/global/overlay/etc/cosmos/apt/cosmos_1.5-2~sunet20220414_all.deb b/global/overlay/etc/cosmos/apt/cosmos_1.5-2~sunet20220414_all.deb new file mode 100644 index 0000000000000000000000000000000000000000..c1350a458ceafd1c8b2ee42e187ab5c0fd670ddb GIT binary patch literal 12080 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 H59|K`%zHY> literal 0 HcmV?d00001 From 7323626efe12523c371d017224a2fec92b745e96 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 14 Apr 2022 12:31:27 +0200 Subject: [PATCH 037/111] cleanups, and install cosmos_1.5-2~sunet20220414_all.deb - shellcheck fixes - rewrite argument parsing - install new version of cosmos (cosmos_1.5-2~sunet20220414_all.deb) --- addhost | 56 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/addhost b/addhost index 2da1e36e..88f01023 100755 --- a/addhost +++ b/addhost @@ -1,57 +1,63 @@ -#!/bin/sh +#!/bin/bash cmd_hostname="" cmd_do_bootstrap="no" cmd_fqdn="" -set -- $(getopt b?h?n: "$@") +function usage() { + echo "Usage: $0 [-h] [-b] [-n fqdn] [--] []" + echo " -h show help" + echo " -b bootstrap (using ssh)" + echo " -n specify FQDN (if not the same as )" + echo "" + echo " can be an IP number, or something that resolves to one" +} -while [ $# -gt 0 ]; do - case "$1" in - (-h) echo "Usage: $0 [-h] [-b] [--] []"; exit 0;; - (-b) cmd_do_bootstrap="yes" ;; - (-n) cmd_fqdn="$2" ; shift ;; - (--) shift; break;; - (-*) echo "Unknown option $1\nUsage: $0 [-b] [-h] [-n fqdn] [--] "; exit 1;; - (*) break;; +while getopts "bhn:" this; do + case "${this}" in + h) usage; exit 0;; + b) cmd_do_bootstrap="yes" ;; + n) cmd_fqdn="${OPTARG}" ; shift ;; + *) echo "Unknown option ${this}"; echo ""; usage; exit 1;; esac - shift done +shift $((OPTIND-1)) -if [ ! -z "$1" -a -z "$cmd_hostname" ]; then +if [[ ! $cmd_hostname ]]; then cmd_hostname="$1" fi -if [ ! -z "$cmd_hostname" -a -z "$cmd_fqdn" ]; then +if [[ ! $cmd_fqdn ]]; then cmd_fqdn="$cmd_hostname" fi if test -z "$cmd_hostname"; then - echo "Usage: $0 [-h] [-b] [-n fqdn] [--] " + usage exit 1 fi test -f cosmos.conf && . ./cosmos.conf -defrepo=`git remote -v | grep ${remote:="ro"} | grep fetch | awk '{print $2}'` +_remote=${remote:='ro'} +defrepo=$(git remote get-url "${_remote}" 2>/dev/null) rrepo=${repo:="$defrepo"} rtag=${tag:="changeme"} -if [ "x$rrepo" = "x" ]; then - echo "$0: repo not set in cosmos.conf and no git remote named 'ro' found" +if [[ ! $rrepo ]]; then + echo "$0: repo not set in cosmos.conf and no git remote named '${_remote}' found" exit 1 fi -if [ ! -d $cmd_hostname ]; then - cp -pr default $cmd_fqdn - git add $cmd_fqdn - git commit -m "$cmd_fqdn added" $cmd_fqdn +if [ ! -d "$cmd_fqdn" ]; then + cp -pr default "$cmd_fqdn" + git add "$cmd_fqdn" + git commit -m "$cmd_fqdn added" "$cmd_fqdn" ./bump-tag fi if [ "$cmd_do_bootstrap" = "yes" ]; then - scp apt/cosmos_1.5-1_all.deb apt/bootstrap-cosmos.sh root@$cmd_hostname: - ssh root@$cmd_hostname ./bootstrap-cosmos.sh $cmd_fqdn $rrepo $rtag - ssh root@$cmd_hostname cosmos update - ssh root@$cmd_hostname cosmos apply + scp apt/cosmos_1.5-2~sunet20220414_all.deb apt/bootstrap-cosmos.sh root@"$cmd_hostname": + ssh root@"$cmd_hostname" ./bootstrap-cosmos.sh "$cmd_fqdn" "$rrepo" "$rtag" + ssh root@"$cmd_hostname" cosmos update + ssh root@"$cmd_hostname" cosmos apply fi From 42f674edb3f1919914737f833ea25258c6892ed6 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 14 Apr 2022 12:35:26 +0200 Subject: [PATCH 038/111] speling --- prepair-iaas-debian => prepare-iaas-debian | 0 prepair-iaas-ubuntu => prepare-iaas-ubuntu | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename prepair-iaas-debian => prepare-iaas-debian (100%) rename prepair-iaas-ubuntu => prepare-iaas-ubuntu (100%) diff --git a/prepair-iaas-debian b/prepare-iaas-debian similarity index 100% rename from prepair-iaas-debian rename to prepare-iaas-debian diff --git a/prepair-iaas-ubuntu b/prepare-iaas-ubuntu similarity index 100% rename from prepair-iaas-ubuntu rename to prepare-iaas-ubuntu From 300c4283afe2229e26cbe40182451f98e53b1004 Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Fri, 7 Oct 2022 09:50:11 +0200 Subject: [PATCH 039/111] Rework prepare-iaas-debian * Log in as few times as possible to not require a lot if yubikey keypresses * Make sure en_US.UTF-8 is present * Replace `rm -rf` with userdel command * Make sure the debian account is actually deleted * Remove locale related warnings when running script from macOS --- debian-enable-root.sh | 11 +++++++ debian-setup.sh | 67 +++++++++++++++++++++++++++++++++++++++++++ prepare-iaas-debian | 24 +++++++++------- 3 files changed, 92 insertions(+), 10 deletions(-) create mode 100755 debian-enable-root.sh create mode 100755 debian-setup.sh diff --git a/debian-enable-root.sh b/debian-enable-root.sh new file mode 100755 index 00000000..392e0b46 --- /dev/null +++ b/debian-enable-root.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# +# This script is called from prepare-iaas-debian after logging in via ssh as +# the default "debian" user +# +set -ex + +sudo cp -r /home/debian/.ssh /root/ +sudo chown -R root:root /root/.ssh +sudo chmod 700 /root/.ssh +sudo chmod 600 /root/.ssh/authorized_keys diff --git a/debian-setup.sh b/debian-setup.sh new file mode 100755 index 00000000..56e923a3 --- /dev/null +++ b/debian-setup.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# +# This script is called from prepare-iaas-debian after logging in over ssh as +# the root user +# +set -x + +# Get rid of ugly perl messages when running from macOS: +# === +# apt-listchanges: Reading changelogs... +# perl: warning: Setting locale failed. +# perl: warning: Please check that your locale settings: +# LANGUAGE = (unset), +# LC_ALL = (unset), +# LC_CTYPE = "UTF-8", +# LC_TERMINAL = "iTerm2", +# LANG = "C.UTF-8" +# are supported and installed on your system. +# perl: warning: Falling back to a fallback locale ("C.UTF-8"). +# === +export LC_CTYPE=C.UTF-8 + +# Make sure there is no systemd process running as "debian" after the "enable +# root" step in prepare-iaas-debian. If there are any proceses still running as +# the "debian" user the "userdel" command below will fail. +# +# Depending on how long we have waited between running the "enable root" +# script and this one it is possible the process has timed out on its own, +# so run this command before doing "set -e" in case there is no process +# to match. +pkill -u debian -xf "/lib/systemd/systemd --user" + +# Make sure the process has gone away before continuing +sleep_seconds=1 +attempt=1 +max_attempts=10 +while pgrep -u debian -xf "/lib/systemd/systemd --user"; do + if [ $attempt -gt $max_attempts ]; then + echo "failed waiting for systemd process to exit, please investigate" + exit 1 + fi + echo "systemd process still running as debian user, this is attempt $attempt out of $max_attempts, sleeping for $sleep_seconds seconds..." + sleep $sleep_seconds + attempt=$((attempt + 1)) +done + +# From this point we expect all commands to succeed +set -e + +# While the man page for "userdel" recommends using "deluser" we can not +# run "deluser" with "--remove-home" without installing more than the +# already included `perl-base` package, so stick with the low level +# utility. +userdel --remove debian +rm /etc/sudoers.d/* + +# Make sure en_US.UTF-8 is present in the system, expected by at least +# bootstrap-cosmos.sh +locale_gen_file=/etc/locale.gen +if grep -q '^# en_US.UTF-8 UTF-8$' $locale_gen_file; then + sed -i 's/^# \(en_US.UTF-8 UTF-8\)$/\1/' $locale_gen_file + locale-gen +fi + +DEBIAN_FRONTEND="noninteractive" apt-get -y update +DEBIAN_FRONTEND="noninteractive" apt-get -o Dpkg::Options::="--force-confnew" --fix-broken --assume-yes dist-upgrade +reboot diff --git a/prepare-iaas-debian b/prepare-iaas-debian index d368e6a4..41478839 100755 --- a/prepare-iaas-debian +++ b/prepare-iaas-debian @@ -12,13 +12,17 @@ fi set -x -ssh "debian@${ip}" sudo cp -r /home/debian/.ssh /root/ -ssh "debian@${ip}" sudo chown -R root:root /root/.ssh -ssh "debian@${ip}" sudo chmod 700 /root/.ssh -ssh "debian@${ip}" sudo chmod 600 /root/.ssh/authorized_keys -ssh "root@${ip}" deluser debian -ssh "root@${ip}" rm /home/debian -rf -ssh "root@${ip}" rm /etc/sudoers.d/* -ssh "root@${ip}" DEBIAN_FRONTEND="noninteractive" apt-get -y update -ssh "root@${ip}" DEBIAN_FRONTEND="noninteractive" apt-get -o Dpkg::Options::="--force-confnew" --fix-broken --assume-yes dist-upgrade -ssh "root@${ip}" reboot +# Make sure we read the additional scripts from the same directory as +# this script is located at +script_dir=$(dirname "$0") + +# The reason for running two separate logins is that it is tricky to +# remove the initial debian user while logged in as that same user: +# === +# Removing user `debian' ... +# Warning: group `debian' has no more members. +# userdel: user debian is currently used by process 12081 +# /usr/sbin/deluser: `/sbin/userdel debian' returned error code 8. Exiting. +# === +ssh "debian@${ip}" "bash -s" < "$script_dir"/debian-enable-root.sh +ssh "root@${ip}" "bash -s" < "$script_dir"/debian-setup.sh From 87e49a541f5930b0048bb10654576baf954bae05 Mon Sep 17 00:00:00 2001 From: Leif Johansson Date: Wed, 20 Apr 2016 15:07:37 +0200 Subject: [PATCH 040/111] safe update & upgrade --- global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index 613b74e7..fe414568 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -22,7 +22,7 @@ fi set -x -apt-get -y install rsync git-core wget +apt-get -y update && apt-get -y upgrade && apt-get -y install rsync git git-core wget dpkg -i cosmos_1.5-1_all.deb if ! test -d /var/cache/cosmos/repo; then From 7f0c457a3368faec9401a10714f061d36cdb5f4e Mon Sep 17 00:00:00 2001 From: Leif Johansson Date: Wed, 20 Apr 2016 15:37:25 +0200 Subject: [PATCH 041/111] try very hard to find git --- global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index fe414568..d3f219af 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -22,7 +22,10 @@ fi set -x -apt-get -y update && apt-get -y upgrade && apt-get -y install rsync git git-core wget +apt-get -y update && apt-get -y upgrade +for pkg in rsync git git-core wget; do + apt-get -y install $pkg +done dpkg -i cosmos_1.5-1_all.deb if ! test -d /var/cache/cosmos/repo; then From 378dfe04fa4f24743665bd840cea85250e6249b8 Mon Sep 17 00:00:00 2001 From: Leif Johansson Date: Wed, 20 Apr 2016 16:44:14 +0200 Subject: [PATCH 042/111] try very hard to find git --- global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index d3f219af..88bd549a 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -1,6 +1,7 @@ #!/bin/sh -set -e +#set -e +# not all breakage is un-recoverable... cmd_hostname="$1" if test -z "$cmd_hostname"; then @@ -20,9 +21,8 @@ if test -z "$cmd_tags"; then exit 3 fi -set -x - -apt-get -y update && apt-get -y upgrade +apt-get -y update +apt-get -y upgrade for pkg in rsync git git-core wget; do apt-get -y install $pkg done From 19304f2d79b05edc114f8863831d9c7ec0d289df Mon Sep 17 00:00:00 2001 From: Leif Johansson Date: Wed, 20 Apr 2016 17:29:04 +0200 Subject: [PATCH 043/111] short hostname i /etc/hosts --- global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index 88bd549a..1534dc5d 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -33,6 +33,8 @@ if ! test -d /var/cache/cosmos/repo; then fi hostname $cmd_hostname +short=`echo ${cmd_hostname} | awk -F. '{print $1}'` +echo "127.0.1.1 ${cmd_hostname} ${short}" >> /etc/hosts perl -pi -e "s,#COSMOS_REPO_MODELS=.*,COSMOS_REPO_MODELS=\"\\\$COSMOS_REPO/global/:\\\$COSMOS_REPO/$cmd_hostname/\"," /etc/cosmos/cosmos.conf perl -pi -e "s,#COSMOS_UPDATE_VERIFY_GIT_TAG_PATTERN=.*,COSMOS_UPDATE_VERIFY_GIT_TAG_PATTERN=\"${cmd_tags}*\"," /etc/cosmos/cosmos.conf From b2272d409fd6a15e71adfb7af30ccc061f6c53e1 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Fri, 16 Feb 2018 14:40:35 +0100 Subject: [PATCH 044/111] free-hand updates from eduid-ops --- .../etc/cosmos/apt/bootstrap-cosmos.sh | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index 1534dc5d..a93de054 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -21,6 +21,14 @@ if test -z "$cmd_tags"; then exit 3 fi +set -x + + +# cloud-init runs with LANG='US-ASCII' which is likely to fail because of non-US-ASCII chars in the manifest +export LANG='en_US.UTF-8' + +export DEBIAN_FRONTEND='noninteractive' + apt-get -y update apt-get -y upgrade for pkg in rsync git git-core wget; do @@ -32,16 +40,40 @@ if ! test -d /var/cache/cosmos/repo; then cosmos clone "$cmd_repo" fi +# re-run cosmos at reboot until it succeeds - use bash -l to get working proxy settings +grep -v "^exit 0" /etc/rc.local > /etc/rc.local.new +(echo "" + echo "test -f /etc/run-cosmos-at-boot && (bash -l cosmos -v update; bash -l cosmos -v apply && rm /etc/run-cosmos-at-boot)" + echo "" + echo "exit 0" +) >> /etc/rc.local.new +mv -f /etc/rc.local.new /etc/rc.local + +touch /etc/run-cosmos-at-boot + hostname $cmd_hostname short=`echo ${cmd_hostname} | awk -F. '{print $1}'` echo "127.0.1.1 ${cmd_hostname} ${short}" >> /etc/hosts -perl -pi -e "s,#COSMOS_REPO_MODELS=.*,COSMOS_REPO_MODELS=\"\\\$COSMOS_REPO/global/:\\\$COSMOS_REPO/$cmd_hostname/\"," /etc/cosmos/cosmos.conf +# Set up cosmos models. They are in the order of most significant first, so we want +# +_host_type=`echo $cmd_hostname | cut -d - -f 1` +models=$( + echo -n '\\$COSMOS_REPO/'"$cmd_hostname/:" + test -d /var/cache/cosmos/repo/${_host_type}-common && echo -n '\\$COSMOS_REPO/'"${_host_type}-common/:" + echo -n '\\$COSMOS_REPO/global/' +) +echo "Configuring cosmos with the following models:" +echo "${models}" + +perl -pi -e "s,#COSMOS_REPO_MODELS=.*,COSMOS_REPO_MODELS=\"${models}\"," /etc/cosmos/cosmos.conf perl -pi -e "s,#COSMOS_UPDATE_VERIFY_GIT_TAG_PATTERN=.*,COSMOS_UPDATE_VERIFY_GIT_TAG_PATTERN=\"${cmd_tags}*\"," /etc/cosmos/cosmos.conf env COSMOS_BASE=/var/cache/cosmos COSMOS_KEYS=/var/cache/cosmos/repo/global/overlay/etc/cosmos/keys /var/cache/cosmos/repo/global/post-tasks.d/015cosmos-trust -(date; nohup cosmos -v update && nohup cosmos -v apply; date) 2>&1 | tee /var/log/cosmos.log +mkdir -p /var/cache/scriptherder + +(date; nohup cosmos -v update && nohup cosmos -v apply && rm /etc/run-cosmos-at-boot; date) 2>&1 | tee /var/log/cosmos.log exit 0 From 3b80ba32c71d071140dc702f9a3a835114f3cd6f Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Wed, 13 Feb 2019 19:07:04 +0100 Subject: [PATCH 045/111] Set manage_etc_hosts to false for cloudimage based hosts this is needed so that our changes in /etc/hosts are not overwritten. --- global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index a93de054..c1ccf8ca 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -51,6 +51,12 @@ mv -f /etc/rc.local.new /etc/rc.local touch /etc/run-cosmos-at-boot +# If this cloud-config is set, it will interfere with our changes to /etc/hosts +grep -q 'manage_etc_hosts: true' /etc/cloud/cloud.cfg +if [ ${?} -eq 0 ]; then + sed -i 's/manage_etc_hosts: true/manage_etc_hosts: false/g' /etc/cloud/cloud.cfg +fi + hostname $cmd_hostname short=`echo ${cmd_hostname} | awk -F. '{print $1}'` echo "127.0.1.1 ${cmd_hostname} ${short}" >> /etc/hosts From 0692cabba3dc3a8306d1afcb3ee9b46034cd7cb9 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 20 Feb 2019 11:39:38 +0100 Subject: [PATCH 046/111] Remove that '.novalocal' line in /etc/hosts, added by cloud-init It messes up `hostname -f` on Debian, even if there's a correct line further down in /etc/hosts. --- global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index c1ccf8ca..24369bb5 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -57,6 +57,9 @@ if [ ${?} -eq 0 ]; then sed -i 's/manage_etc_hosts: true/manage_etc_hosts: false/g' /etc/cloud/cloud.cfg fi +# Remove potential $hostname.novalocal line from /etc/hosts, added by cloud-init +sed -i.bak -e "s/^127\.0\.1\.1 $(hostname)\..*novalocal.*//1" /etc/hosts + hostname $cmd_hostname short=`echo ${cmd_hostname} | awk -F. '{print $1}'` echo "127.0.1.1 ${cmd_hostname} ${short}" >> /etc/hosts From c55e5535a2428ffab5ac7b959ebae15556fb96f0 Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Mon, 10 Oct 2022 16:06:16 +0200 Subject: [PATCH 047/111] Add gpg to cosmos bootstrap script Without this Debian 11 fails to bootstrap: ``` /etc/cosmos/gpg.d/50gpg: 36: gpg: not found ``` --- global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index 24369bb5..d3c4b808 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -31,7 +31,7 @@ export DEBIAN_FRONTEND='noninteractive' apt-get -y update apt-get -y upgrade -for pkg in rsync git git-core wget; do +for pkg in rsync git git-core wget gpg; do apt-get -y install $pkg done dpkg -i cosmos_1.5-1_all.deb From 020b8fe34c159d1d5f427bcd44d82c07c811ba3f Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Wed, 12 Oct 2022 16:26:20 +0200 Subject: [PATCH 048/111] Enable "set -e" again Good idea to fail when unexpected things go wrong. Additional fixes added to the script to not stop where we can expect a non-zero return code. Requested by @fredrikt who also reviewed the patch before going in, thanks! --- .../overlay/etc/cosmos/apt/bootstrap-cosmos.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index d3c4b808..1426904a 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -1,7 +1,6 @@ #!/bin/sh -#set -e -# not all breakage is un-recoverable... +set -e cmd_hostname="$1" if test -z "$cmd_hostname"; then @@ -32,7 +31,9 @@ export DEBIAN_FRONTEND='noninteractive' apt-get -y update apt-get -y upgrade for pkg in rsync git git-core wget gpg; do - apt-get -y install $pkg + # script is running with "set -e", use "|| true" to allow packages to not + # exist without stopping the script + apt-get -y install $pkg || true done dpkg -i cosmos_1.5-1_all.deb @@ -40,8 +41,10 @@ if ! test -d /var/cache/cosmos/repo; then cosmos clone "$cmd_repo" fi -# re-run cosmos at reboot until it succeeds - use bash -l to get working proxy settings -grep -v "^exit 0" /etc/rc.local > /etc/rc.local.new +# Re-run cosmos at reboot until it succeeds - use bash -l to get working proxy settings. +# It is possible the file does not exist or contains no matching lines, +# both cases are OK +grep -v "^exit 0" /etc/rc.local > /etc/rc.local.new || true (echo "" echo "test -f /etc/run-cosmos-at-boot && (bash -l cosmos -v update; bash -l cosmos -v apply && rm /etc/run-cosmos-at-boot)" echo "" @@ -52,8 +55,7 @@ mv -f /etc/rc.local.new /etc/rc.local touch /etc/run-cosmos-at-boot # If this cloud-config is set, it will interfere with our changes to /etc/hosts -grep -q 'manage_etc_hosts: true' /etc/cloud/cloud.cfg -if [ ${?} -eq 0 ]; then +if [ -f /etc/cloud/cloud.cfg ]; then sed -i 's/manage_etc_hosts: true/manage_etc_hosts: false/g' /etc/cloud/cloud.cfg fi From 16a6a67fd1897181b582f2399c8938923a571b92 Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Mon, 14 Nov 2022 12:41:57 +0100 Subject: [PATCH 049/111] Make debian iaas prepare scripts handle ubuntu Now ubuntu also uses the updated way of preparing iaas instances like debian did before, actually the debian scripts have been remade to also handle ubuntu so we use a common code path. Usage (what scripts to call) stay the same, but the underlying operations takes less logins to complete. --- debian-enable-root.sh | 11 ----------- iaas-enable-root.sh | 17 +++++++++++++++++ debian-setup.sh => iaas-setup.sh | 27 +++++++++++++++++---------- prepare-iaas-debian | 11 ++++------- prepare-iaas-ubuntu | 21 +++++++++++---------- 5 files changed, 49 insertions(+), 38 deletions(-) delete mode 100755 debian-enable-root.sh create mode 100755 iaas-enable-root.sh rename debian-setup.sh => iaas-setup.sh (67%) diff --git a/debian-enable-root.sh b/debian-enable-root.sh deleted file mode 100755 index 392e0b46..00000000 --- a/debian-enable-root.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -# -# This script is called from prepare-iaas-debian after logging in via ssh as -# the default "debian" user -# -set -ex - -sudo cp -r /home/debian/.ssh /root/ -sudo chown -R root:root /root/.ssh -sudo chmod 700 /root/.ssh -sudo chmod 600 /root/.ssh/authorized_keys diff --git a/iaas-enable-root.sh b/iaas-enable-root.sh new file mode 100755 index 00000000..d6bb1072 --- /dev/null +++ b/iaas-enable-root.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# +# This script is called from prepare-iaas-$os after logging in via ssh as +# the default user existing in cloud images +# +set -ex + +os=$(lsb_release -si | tr '[:upper:]' '[:lower:]') +if [ "$os" != "ubuntu" ] && [ "$os" != "debian" ]; then + echo "unsupported os: '$os'" + exit 1 +fi + +sudo cp -r /home/"$os"/.ssh /root/ +sudo chown -R root:root /root/.ssh +sudo chmod 700 /root/.ssh +sudo chmod 600 /root/.ssh/authorized_keys diff --git a/debian-setup.sh b/iaas-setup.sh similarity index 67% rename from debian-setup.sh rename to iaas-setup.sh index 56e923a3..30c9db06 100755 --- a/debian-setup.sh +++ b/iaas-setup.sh @@ -1,10 +1,16 @@ #!/usr/bin/env bash # -# This script is called from prepare-iaas-debian after logging in over ssh as +# This script is called from prepare-iaas-$os after logging in over ssh as # the root user # set -x +os=$(lsb_release -si | tr '[:upper:]' '[:lower:]') +if [ "$os" != "ubuntu" ] && [ "$os" != "debian" ]; then + echo "unsupported os: '$os'" + exit 1 +fi + # Get rid of ugly perl messages when running from macOS: # === # apt-listchanges: Reading changelogs... @@ -20,26 +26,27 @@ set -x # === export LC_CTYPE=C.UTF-8 -# Make sure there is no systemd process running as "debian" after the "enable -# root" step in prepare-iaas-debian. If there are any proceses still running as -# the "debian" user the "userdel" command below will fail. +# Make sure there is no systemd process running as the initial cloud image user +# # after the "enable root" step in prepare-iaas-$os. If there are any # +# proceses still running as the specified user the "userdel" command # below +# will fail. # # Depending on how long we have waited between running the "enable root" # script and this one it is possible the process has timed out on its own, # so run this command before doing "set -e" in case there is no process # to match. -pkill -u debian -xf "/lib/systemd/systemd --user" +pkill -u "$os" -xf "/lib/systemd/systemd --user" # Make sure the process has gone away before continuing sleep_seconds=1 attempt=1 max_attempts=10 -while pgrep -u debian -xf "/lib/systemd/systemd --user"; do +while pgrep -u "$os" -xf "/lib/systemd/systemd --user"; do if [ $attempt -gt $max_attempts ]; then echo "failed waiting for systemd process to exit, please investigate" exit 1 fi - echo "systemd process still running as debian user, this is attempt $attempt out of $max_attempts, sleeping for $sleep_seconds seconds..." + echo "systemd process still running as '$os' user, this is attempt $attempt out of $max_attempts, sleeping for $sleep_seconds seconds..." sleep $sleep_seconds attempt=$((attempt + 1)) done @@ -49,9 +56,9 @@ set -e # While the man page for "userdel" recommends using "deluser" we can not # run "deluser" with "--remove-home" without installing more than the -# already included `perl-base` package, so stick with the low level -# utility. -userdel --remove debian +# already included `perl-base` package on debian, so stick with the low +# level utility. +userdel --remove "$os" rm /etc/sudoers.d/* # Make sure en_US.UTF-8 is present in the system, expected by at least diff --git a/prepare-iaas-debian b/prepare-iaas-debian index 41478839..cf36fb3b 100755 --- a/prepare-iaas-debian +++ b/prepare-iaas-debian @@ -17,12 +17,9 @@ set -x script_dir=$(dirname "$0") # The reason for running two separate logins is that it is tricky to -# remove the initial debian user while logged in as that same user: +# remove the initial user while logged in as that same user: # === -# Removing user `debian' ... -# Warning: group `debian' has no more members. -# userdel: user debian is currently used by process 12081 -# /usr/sbin/deluser: `/sbin/userdel debian' returned error code 8. Exiting. +# userdel: user debian is currently used by process 1082 # === -ssh "debian@${ip}" "bash -s" < "$script_dir"/debian-enable-root.sh -ssh "root@${ip}" "bash -s" < "$script_dir"/debian-setup.sh +ssh "debian@${ip}" "bash -s" < "$script_dir"/iaas-enable-root.sh +ssh "root@${ip}" "bash -s" < "$script_dir"/iaas-setup.sh diff --git a/prepare-iaas-ubuntu b/prepare-iaas-ubuntu index 3fdff8d0..c21bf877 100755 --- a/prepare-iaas-ubuntu +++ b/prepare-iaas-ubuntu @@ -12,13 +12,14 @@ fi set -x -ssh "ubuntu@${ip}" sudo cp -r /home/ubuntu/.ssh /root/ -ssh "ubuntu@${ip}" sudo chown -R root:root /root/.ssh -ssh "ubuntu@${ip}" sudo chmod 700 /root/.ssh -ssh "ubuntu@${ip}" sudo chmod 600 /root/.ssh/authorized_keys -ssh "root@${ip}" deluser ubuntu -ssh "root@${ip}" rm /home/ubuntu -rf -ssh "root@${ip}" rm /etc/sudoers.d/* -ssh "root@${ip}" DEBIAN_FRONTEND="noninteractive" apt-get -y update -ssh "root@${ip}" DEBIAN_FRONTEND="noninteractive" apt-get -o Dpkg::Options::="--force-confnew" --fix-broken --assume-yes dist-upgrade -ssh "root@${ip}" reboot +# Make sure we read the additional scripts from the same directory as +# this script is located at +script_dir=$(dirname "$0") + +# The reason for running two separate logins is that it is tricky to +# remove the initial user while logged in as that same user: +# === +# userdel: user ubuntu is currently used by process 44063 +# === +ssh "ubuntu@${ip}" "bash -s" < "$script_dir"/iaas-enable-root.sh +ssh "root@${ip}" "bash -s" < "$script_dir"/iaas-setup.sh From 3ef4e47ff65ac5ccbe1c53f6f36ffedf5e933ddb Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Tue, 15 Nov 2022 18:11:51 +0100 Subject: [PATCH 050/111] Handle multiple versions of cosmos .deb Before this change there was a need to keep addhost and bootstrap-cosmos.sh in sync regarding what version of the cosmos deb to scp over and later run. Now we find the latest version as decided by `sort -V` in both addhost and bootstrap-cosmos.sh. Solution discussed with @fredrikt. --- addhost | 3 ++- global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/addhost b/addhost index 88f01023..cc1a479f 100755 --- a/addhost +++ b/addhost @@ -56,7 +56,8 @@ if [ ! -d "$cmd_fqdn" ]; then fi if [ "$cmd_do_bootstrap" = "yes" ]; then - scp apt/cosmos_1.5-2~sunet20220414_all.deb apt/bootstrap-cosmos.sh root@"$cmd_hostname": + cosmos_deb=$(find apt/ -maxdepth 1 -name 'cosmos_*.deb' | sort -V | tail -1) + scp "$cosmos_deb" apt/bootstrap-cosmos.sh root@"$cmd_hostname": ssh root@"$cmd_hostname" ./bootstrap-cosmos.sh "$cmd_fqdn" "$rrepo" "$rtag" ssh root@"$cmd_hostname" cosmos update ssh root@"$cmd_hostname" cosmos apply diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index 1426904a..c31cea78 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -35,7 +35,8 @@ for pkg in rsync git git-core wget gpg; do # exist without stopping the script apt-get -y install $pkg || true done -dpkg -i cosmos_1.5-1_all.deb +cosmos_deb=$(find ./ -maxdepth 1 -name 'cosmos_*.deb' | sort -V | tail -1) +dpkg -i "$cosmos_deb" if ! test -d /var/cache/cosmos/repo; then cosmos clone "$cmd_repo" From 68d0083557b138ce55ffd37ecce2accca9ede72a Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Mon, 5 Dec 2022 13:26:20 +0100 Subject: [PATCH 051/111] Make overlay permission script global This will make sure /root has proper permissions on our machines. --- global/pre-tasks.d/015set-overlay-permissions | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 global/pre-tasks.d/015set-overlay-permissions diff --git a/global/pre-tasks.d/015set-overlay-permissions b/global/pre-tasks.d/015set-overlay-permissions new file mode 100755 index 00000000..373ef68f --- /dev/null +++ b/global/pre-tasks.d/015set-overlay-permissions @@ -0,0 +1,19 @@ +#!/bin/sh +# +# Set overlay file permissions in model directory before apply.d/60overlay +# rsyncs it to / +# + +set -e +self=$(basename "$0") + +MODEL_OVERLAY="$COSMOS_MODEL/overlay" + +if ! test -d "$MODEL_OVERLAY"; then + test -z "$COSMOS_VERBOSE" || echo "$self: overlay is a no-op" + exit 0 +fi + +if [ -d "$MODEL_OVERLAY/root" ]; then + chmod -v 0700 "$MODEL_OVERLAY"/root +fi From fb4849a0dfe95d45a4d14471f329515aebca14a3 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Tue, 17 Jan 2023 13:53:13 +0100 Subject: [PATCH 052/111] Use puppet that comes with OS nunoc-ops does like this since 2018 so I think it will fly. Also the package `puppet` seems to been around since at-least Ubuntu 14.04. --- global/overlay/etc/cosmos/apt/SHA1SUM | 6 ------ .../cosmos/apt/puppetlabs-release-jessie.deb | Bin 16950 -> 0 bytes .../cosmos/apt/puppetlabs-release-stretch.deb | Bin 13706 -> 0 bytes .../cosmos/apt/puppetlabs-release-trusty.deb | Bin 9554 -> 0 bytes .../cosmos/apt/puppetlabs-release-xenial.deb | Bin 13646 -> 0 bytes .../cosmos/apt/puppetlabs-release-yakkety.deb | Bin 13932 -> 0 bytes global/pre-tasks.d/030puppet | 10 +--------- 7 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 global/overlay/etc/cosmos/apt/SHA1SUM delete mode 100644 global/overlay/etc/cosmos/apt/puppetlabs-release-jessie.deb delete mode 100644 global/overlay/etc/cosmos/apt/puppetlabs-release-stretch.deb delete mode 100644 global/overlay/etc/cosmos/apt/puppetlabs-release-trusty.deb delete mode 100644 global/overlay/etc/cosmos/apt/puppetlabs-release-xenial.deb delete mode 100644 global/overlay/etc/cosmos/apt/puppetlabs-release-yakkety.deb diff --git a/global/overlay/etc/cosmos/apt/SHA1SUM b/global/overlay/etc/cosmos/apt/SHA1SUM deleted file mode 100644 index 663473cc..00000000 --- a/global/overlay/etc/cosmos/apt/SHA1SUM +++ /dev/null @@ -1,6 +0,0 @@ -c8c591fc7bcc54c4a7cf35759ee35ef11936b9a8 puppetlabs-release_1.0-12_all.deb -d69b9a005a604a6739dbcf2524de53fdd93f135f puppetlabs-release_1.1-1_all.deb -761a213324fd1bfa7bc76dc46d6a58b29f17b1a3 puppetlabs-release-pc1_1.1.0-4xenial_all.deb -cfead6a6242a5407ea45ca9dd148c0e694df9ff8 puppetlabs-release-pc1_1.1.0-5yakkety_all.deb -f0c104d210956b4a934076b49fb124107237a4ca puppetlabs-release-pc1_1.1.0-5stretch_all.deb - diff --git a/global/overlay/etc/cosmos/apt/puppetlabs-release-jessie.deb b/global/overlay/etc/cosmos/apt/puppetlabs-release-jessie.deb deleted file mode 100644 index 2ca91fac5c491dd91104c22c163d4e6cddcc5965..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16950 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 BEKC3Z diff --git a/global/overlay/etc/cosmos/apt/puppetlabs-release-stretch.deb b/global/overlay/etc/cosmos/apt/puppetlabs-release-stretch.deb deleted file mode 100644 index b5ce6d690232ff71d29f217fd148722d7526bc42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13706 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

6hSPk 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 r@C$W6YybV0fOPI&NR*2$1pyuW?+*pYNf)SKmU diff --git a/global/overlay/etc/cosmos/apt/puppetlabs-release-trusty.deb b/global/overlay/etc/cosmos/apt/puppetlabs-release-trusty.deb deleted file mode 100644 index 2d924af989e32b0dcf5249e7613968fd495f0834..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9554 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 diff --git a/global/overlay/etc/cosmos/apt/puppetlabs-release-yakkety.deb b/global/overlay/etc/cosmos/apt/puppetlabs-release-yakkety.deb deleted file mode 100644 index 197e5b992cab624e49a91ccc2928e456b38245bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13932 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 z Date: Thu, 2 Jan 2020 13:23:11 +0100 Subject: [PATCH 053/111] copy edit-secrets from eduid-ops --- edit-secrets | 312 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 196 insertions(+), 116 deletions(-) diff --git a/edit-secrets b/edit-secrets index 149715e0..a82eba5d 100755 --- a/edit-secrets +++ b/edit-secrets @@ -18,91 +18,10 @@ umask 077 LAST_OUTPUT_FILENAME="/root/.last_edit-secrets_output" -if [[ "x${EDITOR}" != "x" ]]; then - declare -r REMOTE_EDITOR="${EDITOR}" -else - declare -r REMOTE_EDITOR='/usr/bin/vim.tiny' -fi +test -d /dev/shm && export TMPDIR='/dev/shm' -if [ "x$1" = "x" ]; then - echo "Syntax: $0 -l OR fqdn" - exit 1 -fi - -if [ "x$1" != "x-l" ]; then - host=$(echo $1 | sed -e 's!/*$!!') # remove trailing slashes - - if [ ! -d $host ]; then - echo "$0: No host-directory for '$host' found - execute in top-level cosmos dir" - exit 1 - fi - - # Execute this very script, on a remote host - TMPFILE=$(mktemp edit-secrets.$$.XXXXXXX) - if [ ! -f $TMPFILE ]; then - echo "$0: Failed creating temporary file" - exit 1 - fi - TMPFILE2=$(mktemp edit-secrets.$$.XXXXXXX) - if [ ! -f $TMPFILE2 ]; then - echo "$0: Failed creating temporary file" - exit 1 - fi - - trap "rm -f $TMPFILE $TMPFILE2" EXIT - - ssh -t root@$host EDITOR="${REMOTE_EDITOR}" /var/cache/cosmos/repo/edit-secrets -l - scp -q root@$host:$LAST_OUTPUT_FILENAME $TMPFILE - - if grep ^"STATUS=UPDATED" $TMPFILE > /dev/null; then - # extract the path of the file that should be updated in the Cosmos repo - save_to="${host}/overlay/etc/hiera/data/secrets.yaml.asc" - mkdir -p "`dirname $save_to`" - # extract the GPG output - perl -e '$a = 0; while (<>) { $a = 1 if ($_ =~ /-+BEGIN PGP MESSAGE-+/); - print $_ if $a; $a = 0 if ($_ =~ /-+END PGP MESSAGE-+/); }' < $TMPFILE > $TMPFILE2 - - if ! grep "END PGP MESSAGE" $TMPFILE2 > /dev/null; then - echo "$0: Failed extracting PGP output from file $TMPFILE into $TMPFILE2" - exit 1 - fi - # use cat to preserve permissions etc. - cat $TMPFILE > $save_to - git add $save_to - - echo "" - echo "$save_to updated" - echo "" - else - echo "" - echo "Not updated" - echo "" - fi - - rm $TMPFILE $TMPFILE2 - - exit 0 -fi - -# -# Local execution on a host -# - -SECRETFILE=/etc/hiera/data/secrets.yaml.asc -GNUPGHOME=/etc/hiera/gpg/ -export GNUPGHOME - -GPG=`which gpg2 || true` -if [ ! -x "$GPG" ]; then - GPG=`which gpg || true` - if [ ! -x "$GPG" ]; then - echo "$0: gpg2 or gpg not found" - exit 1 - fi -fi - -TMPFILE=$(mktemp --tmpdir=/dev/shm) -TMPFILE2=$(mktemp --tmpdir=/dev/shm) +TMPFILE=$(mktemp edit-secrets.XXXXXXXXXX) +TMPFILE2=$(mktemp edit-secrets.XXXXXXXXXX) if [ ! -f $TMPFILE ]; then echo "$TMPFILE" @@ -117,47 +36,208 @@ fi trap "rm -f $TMPFILE $TMPFILE2" EXIT -if ! $GPG --list-secret-keys | grep -q ^"sec\s"; then - echo "$0: Secret key does not exist (in $GNUPGHOME)." - echo "" - echo "Generate it with /var/cache/cosmos/model/pre-tasks.d/040hiera-gpg" - echo "" + +if [[ ! $1 ]]; then + # deliberately don't mention the --on-host argument + echo "Syntax: $0 fqdn" exit 1 fi -if [ -s $SECRETFILE ]; then - $GPG -d $SECRETFILE > $TMPFILE -fi -cp $TMPFILE $TMPFILE2 -sensible-editor $TMPFILE -rm -f ${TMPFILE}~ ${TMPFILE2}~ +function edit_copy_and_commit() +{ + # + # This code runs on the administrators local machine + # + local host=$1 -echo "" -echo "" + if [[ ${EDITOR} ]]; then + declare -r REMOTE_EDITOR="${EDITOR}" + else + declare -r REMOTE_EDITOR='/usr/bin/vim.tiny' + fi -status=0 -cmp -s $TMPFILE $TMPFILE2 || status=1 -if [ $status -eq 0 ]; then - ( - echo "STATUS=NOT_CHANGED" - ) > $LAST_OUTPUT_FILENAME - echo "" - echo "$0: No changes detected" -else - # figure out this hosts gpg key id - recipient=$($GPG --list-secret-key | grep ^sec | head -1 | awk '{print $2}' | cut -d / -f 2) + # Execute this script, on a remote host + ssh -t root@"${host}" EDITOR="${REMOTE_EDITOR}" /var/cache/cosmos/repo/edit-secrets --on-host + scp -q root@"${host}:${LAST_OUTPUT_FILENAME}" ${TMPFILE} - save_to="`hostname --fqdn`/overlay${SECRETFILE}" - echo "" - ( - echo "STATUS=UPDATED" + local save_to + if grep ^"STATUS=UPDATED" $TMPFILE > /dev/null; then + save_to="${host}/overlay/etc/hiera/data/secrets.yaml.asc" + + # extract the GPG output + perl -e '$a = 0; while (<>) { $a = 1 if ($_ =~ /-+BEGIN PGP MESSAGE-+/); + print $_ if $a; $a = 0 if ($_ =~ /-+END PGP MESSAGE-+/); }' < $TMPFILE > $TMPFILE2 + + if ! grep "END PGP MESSAGE" $TMPFILE2 > /dev/null; then + echo "$0: Failed extracting PGP output from file $TMPFILE into $TMPFILE2" + exit 1 + fi + elif grep ^"STATUS=EYAML_UPDATED" $TMPFILE > /dev/null; then + save_to="${host}/overlay/etc/hiera/data/local.eyaml" + + # extract the eyaml output + perl -e '$a = 0; while (<>) { $a = 1 if ($_ =~ /^---$/); + print $_ if $a }' < $TMPFILE > $TMPFILE2 + + if ! grep "^---$" $TMPFILE2 > /dev/null; then + echo "$0: Failed extracting yaml output from file $TMPFILE into $TMPFILE2" + exit 1 + fi + else echo "" - ) > $LAST_OUTPUT_FILENAME - $GPG --output - --armor --recipient $recipient --sign --encrypt $TMPFILE >> $LAST_OUTPUT_FILENAME + echo "Not updated" + echo "" + + exit 0 + fi + + # use cat to preserve permissions etc. + mkdir -p "`dirname ${save_to}`" + cat $TMPFILE2 > "${save_to}" + git add "${save_to}" + + if grep ^"STATUS=EYAML_UPDATED" $TMPFILE > /dev/null; then + git diff --cached "${save_to}" + fi + echo "" - echo "GPG output saved in $LAST_OUTPUT_FILENAME - save it in Cosmos as" + echo "$save_to updated" echo "" - echo " $save_to" + + exit 0 +} + +function edit_file_on_host() { + # + # Local execution on a host + # + + local SECRETFILE=/etc/hiera/data/secrets.yaml.asc + local EYAMLFILE=/etc/hiera/data/local.eyaml + + if [ -f "${EYAMLFILE}" ]; then + edit_eyaml_file ${EYAMLFILE} + elif [ -f "${SECRETFILE}" ]; then + edit_gpg_file ${SECRETFILE} + elif [ -f /etc/hiera/eyaml/public_certkey.pkcs7.pem ]; then + # default to eyaml if the key exists and none of the secrets-file above exist + touch ${EYAMLFILE} + edit_eyaml_file ${EYAMLFILE} + fi +} + +function edit_gpg_file() +{ + local SECRETFILE=$1 + + GNUPGHOME=/etc/hiera/gpg/ + export GNUPGHOME + + local GPG=`which gpg2 || true` + if [ ! -x "$GPG" ]; then + GPG=`which gpg || true` + if [ ! -x "$GPG" ]; then + echo "$0: gpg2 or gpg not found" + exit 1 + fi + fi + + if ! $GPG --list-secret-keys | grep -q ^"sec\s"; then + echo "$0: Secret key does not exist (in $GNUPGHOME)." + echo "" + echo "Generate it with /var/cache/cosmos/model/pre-tasks.d/040hiera-gpg" + echo "" + exit 1 + fi + + if [ -s $SECRETFILE ]; then + $GPG -d $SECRETFILE > $TMPFILE + fi + + cp $TMPFILE $TMPFILE2 + sensible-editor $TMPFILE + rm -f ${TMPFILE}~ ${TMPFILE2}~ + echo "" + echo "" + + local status=0 + cmp -s $TMPFILE $TMPFILE2 || status=1 + if [ $status -eq 0 ]; then + ( + echo "STATUS=NOT_CHANGED" + ) > $LAST_OUTPUT_FILENAME + echo "" + echo "$0: No changes detected" + else + # figure out this hosts gpg key id + if lsb_release -r | grep -q 18.04; then + recipient=$($GPG --list-secret-keys | grep -A1 '^sec' | tail -1 | awk '{print $1}') + else + recipient=$($GPG --list-secret-key | grep ^sec | head -1 | awk '{print $2}' | cut -d / -f 2) + fi + + save_to="`hostname --fqdn`/overlay${SECRETFILE}" + echo "" + ( + echo "STATUS=UPDATED" + echo "" + ) > $LAST_OUTPUT_FILENAME + $GPG --output - --armor --recipient $recipient --sign --encrypt $TMPFILE >> $LAST_OUTPUT_FILENAME + echo "" + echo "GPG output saved in $LAST_OUTPUT_FILENAME - save it in Cosmos as" + echo "" + echo " $save_to" + echo "" + fi +} + +function edit_eyaml_file() +{ + local EYAMLFILE=$1 + + local FQDN=$(hostname --fqdn) + local privkey='/etc/hiera/eyaml/private_key.pkcs7.pem' + local pubkey='/etc/hiera/eyaml/public_certkey.pkcs7.pem' + for f in $privkey $pubkey; do + test -f "${f}" || { echo "$0: eyaml key file ${f} not found"; exit 1; } + done + + # save source file for comparision afterwards + cp "${EYAMLFILE}" "${TMPFILE}" + eyaml edit --pkcs7-private-key "${privkey}" --pkcs7-public-key "${pubkey}" "${EYAMLFILE}" + + local status=0 + cmp -s "${EYAMLFILE}" $TMPFILE || status=1 + if [ $status -eq 0 ]; then + ( + echo "STATUS=NOT_CHANGED" + ) > $LAST_OUTPUT_FILENAME + echo "" + echo "$0: No changes detected" + else + echo "" + ( + echo "STATUS=EYAML_UPDATED" + echo "" + ) > $LAST_OUTPUT_FILENAME + cat "${EYAMLFILE}" >> $LAST_OUTPUT_FILENAME + fi +} + + +if [[ $1 == '--on-host' ]]; then + edit_file_on_host +else + host=$(echo $1 | sed -e 's!/*$!!') # remove trailing slashes + + if [ ! -d $host ]; then + echo "$0: No host-directory for '$host' found - execute in top-level cosmos dir" + exit 1 + fi + + edit_copy_and_commit $host fi + +exit 0 From d12f6297eddfc2b0d0d015f5dee157bbf3665465 Mon Sep 17 00:00:00 2001 From: Kristofer Hallin Date: Mon, 14 Sep 2020 10:02:20 +0200 Subject: [PATCH 054/111] Support Ubuntu 20 as well for edit-secrets. --- edit-secrets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edit-secrets b/edit-secrets index a82eba5d..e10ad3bc 100755 --- a/edit-secrets +++ b/edit-secrets @@ -172,7 +172,7 @@ function edit_gpg_file() echo "$0: No changes detected" else # figure out this hosts gpg key id - if lsb_release -r | grep -q 18.04; then + if lsb_release -r | grep -qE '(18|20).04'; then recipient=$($GPG --list-secret-keys | grep -A1 '^sec' | tail -1 | awk '{print $1}') else recipient=$($GPG --list-secret-key | grep ^sec | head -1 | awk '{print $2}' | cut -d / -f 2) From a7d0a189da5c4c465aa1f2b60dc8daedab71679b Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Wed, 18 Jan 2023 13:50:09 +0100 Subject: [PATCH 055/111] Work around broken hiera-eyaml on 22.04 This can be removed once the linked bug report is solved. Idea from, and implementation reviewed by, @fredrikt --- edit-secrets | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/edit-secrets b/edit-secrets index e10ad3bc..b4d816cd 100755 --- a/edit-secrets +++ b/edit-secrets @@ -43,6 +43,35 @@ if [[ ! $1 ]]; then exit 1 fi +function patch_broken_eyaml { + # + # Ubuntu 22.04 (jammy) has a broken hiera-eyaml package, a bug report + # exists here: https://bugs.launchpad.net/ubuntu/+source/hiera-eyaml/+bug/1974059 + # + + if [ "$(lsb_release -cs)" == "jammy" ]; then + plugins_file="/usr/share/rubygems-integration/all/gems/hiera-eyaml-3.2.2/lib/hiera/backend/eyaml/plugins.rb" + if [ -f $plugins_file ]; then + # We only want to try patching the file if it is the known broken version + bad_sum="1d0f14765ebcfcdae300d8ac5d715845ef9b283345d19114a23d96161556618f" + sum=$(sha256sum $plugins_file | awk '{print $1}') + if [ "$sum" == "$bad_sum" ]; then + patch --fuzz=0 --directory=/ --strip=0 <<'EOF' +--- /usr/share/rubygems-integration/all/gems/hiera-eyaml-3.2.2/lib/hiera/backend/eyaml/plugins.rb.orig 2023-01-18 08:20:22.140338419 +0000 ++++ /usr/share/rubygems-integration/all/gems/hiera-eyaml-3.2.2/lib/hiera/backend/eyaml/plugins.rb 2023-01-18 08:21:05.654053501 +0000 +@@ -32,6 +32,7 @@ + specs = Gem::VERSION >= "1.6.0" ? source.latest_specs(true) : source.latest_specs + + specs.each do |spec| ++ spec = spec.to_spec if spec.respond_to?(:to_spec) + next if @@plugins.include? spec + + dependency = spec.dependencies.find { |d| d.name == "hiera-eyaml" } +EOF + fi + fi + fi +} function edit_copy_and_commit() { @@ -204,6 +233,8 @@ function edit_eyaml_file() test -f "${f}" || { echo "$0: eyaml key file ${f} not found"; exit 1; } done + patch_broken_eyaml + # save source file for comparision afterwards cp "${EYAMLFILE}" "${TMPFILE}" eyaml edit --pkcs7-private-key "${privkey}" --pkcs7-public-key "${pubkey}" "${EYAMLFILE}" From 187e3bc9bebb77a222a08aac627750aa8f6a83c8 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 19 Jan 2023 11:40:42 +0100 Subject: [PATCH 056/111] add script and Makefile target to test multiverse in a docker container --- Makefile | 12 +++++++++-- scripts/test-in-docker.sh | 42 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100755 scripts/test-in-docker.sh diff --git a/Makefile b/Makefile index 4c378d24..8936489e 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ +DIST := "ubuntu:latest" + cosmos: - fab all cosmos + fab all cosmos upgrade: fab upgrade @@ -9,4 +11,10 @@ db: @git add global/overlay/etc/puppet/cosmos-db.yaml && git commit -m "update db" global/overlay/etc/puppet/cosmos-db.yaml tag: db - ./bump-tag + ./bump-tag + +test_in_docker: + docker run --rm -it \ + -v ${CURDIR}:/multiverse:ro \ + \ + $(DIST) /multiverse/scripts/test-in-docker.sh diff --git a/scripts/test-in-docker.sh b/scripts/test-in-docker.sh new file mode 100755 index 00000000..dae44e12 --- /dev/null +++ b/scripts/test-in-docker.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# This script runs in a Docker container (started with the 'make test_in_docker' command) +# and installs multiverse as it is in your source directory. +# + +set -e + +apt -y update +apt -y install git rsync gpg + +cosmos_deb=$(find /multiverse/apt/ -maxdepth 1 -name 'cosmos_*.deb' | sort -V | tail -1) +dpkg -i "$cosmos_deb" + +test -d /var/cache/cosmos/repo || mkdir -p /var/cache/cosmos/repo +test -d /var/cache/cosmos/model || mkdir -p /var/cache/cosmos/model + +# Make every "cosmos update" copy the contents from /multiverse +# without requiring the changes in there to be checked into git. +cat >/etc/cosmos/update.d/50update-while-testing << EOF +#!/bin/sh + +rsync -a --delete --exclude .git /multiverse/ /var/cache/cosmos/repo +EOF +chmod 755 /etc/cosmos/update.d/50update-while-testing + +sed -i -e 's!^#COSMOS_REPO_MODELS=.*!COSMOS_REPO_MODELS="\$COSMOS_REPO/global/"!' /etc/cosmos/cosmos.conf + +export DEBIAN_FRONTEND=noninteractive + +echo "" +echo "***" +echo "" +echo "$0: Configured docker container for testing of files in /multiverse." +echo "" +echo "You should now be able to do" +echo "" +echo " cosmos -v update" +echo " cosmos -v apply" +echo "" + +exec bash -l From e2e394a9afbcb4d9cac2cca979bd40aeecda48b4 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 19 Jan 2023 17:15:37 +0100 Subject: [PATCH 057/111] generate /etc/puppet/cosmos-modules.conf dynamically --- global/overlay/etc/puppet/cosmos-modules.conf | 36 ------------------ .../etc/puppet/manifests/cosmos-site.pp | 13 +++---- global/post-tasks.d/010cosmos-modules | 38 +++++++++++++++++++ 3 files changed, 44 insertions(+), 43 deletions(-) delete mode 100644 global/overlay/etc/puppet/cosmos-modules.conf create mode 100755 global/post-tasks.d/010cosmos-modules diff --git a/global/overlay/etc/puppet/cosmos-modules.conf b/global/overlay/etc/puppet/cosmos-modules.conf deleted file mode 100644 index 991a570a..00000000 --- a/global/overlay/etc/puppet/cosmos-modules.conf +++ /dev/null @@ -1,36 +0,0 @@ -# -# name source (puppetlabs fq name or git url) upgrade (yes/no) tag-pattern -# -# NOTE that Git packages MUST be tagged with signatures by someone -# in the Cosmos trust list. That is why all the URLs point to forked -# versions in the SUNET github organization. -# -concat https://github.com/SUNET/puppetlabs-concat.git yes sunet-* -stdlib https://github.com/SUNET/puppetlabs-stdlib.git yes sunet-* -cosmos https://github.com/SUNET/puppet-cosmos.git yes sunet-* -ufw https://github.com/SUNET/puppet-module-ufw.git yes sunet_dev-* -apt https://github.com/SUNET/puppetlabs-apt.git yes sunet_dev-* -vcsrepo https://github.com/SUNET/puppetlabs-vcsrepo.git yes sunet-* -xinetd https://github.com/SUNET/puppetlabs-xinetd.git yes sunet-* -hiera-gpg https://github.com/SUNET/hiera-gpg.git yes sunet-* -# -# Alternate sources you might or might not want to use: -#concat puppetlabs/concat no -#stdlib puppetlabs/stdlib no -#ufw attachmentgenie/ufw no -#apt puppetlabs/apt no -#vcsrepo puppetlabs/vcsrepo no -#xinetd puppetlabs/xinetd no -#cosmos https://github.com/SUNET/puppet-cosmos.git yes -#python https://github.com/SUNET/puppet-python.git yes sunet-* -#erlang https://github.com/SUNET/garethr-erlang.git yes sunet-* -#rabbitmq https://github.com/SUNET/puppetlabs-rabbitmq.git yes sunet_dev-* -#pound https://github.com/SUNET/puppet-pound.git yes sunet_dev-* -#augeas https://github.com/SUNET/puppet-augeas.git yes sunet-* -#bastion https://github.com/SUNET/puppet-bastion.git yes sunet-* -#postgresql https://github.com/SUNET/puppetlabs-postgresql.git yes sunet_dev-* -#munin https://github.com/SUNET/ssm-munin.git yes sunet-* -#nagios https://github.com/SUNET/puppet-nagios.git yes sunet-* -#staging https://github.com/SUNET/puppet-staging.git yes sunet-* -#apparmor https://github.com/SUNET/puppet-apparmor.git yes sunet-* -#docker https://github.com/SUNET/garethr-docker.git yes sunet_dev-* diff --git a/global/overlay/etc/puppet/manifests/cosmos-site.pp b/global/overlay/etc/puppet/manifests/cosmos-site.pp index c276f847..1549a00d 100644 --- a/global/overlay/etc/puppet/manifests/cosmos-site.pp +++ b/global/overlay/etc/puppet/manifests/cosmos-site.pp @@ -11,13 +11,13 @@ Exec { #include cosmos::ntp #include cosmos::rngtools #include cosmos::preseed -include ufw -include apt -include cosmos +#include ufw +#include apt +#include cosmos # you need a default node -node default { +node default { } @@ -33,8 +33,8 @@ node default { #class nameserver { # package {'bind9': -# ensure => latest -# } +# ensure => latest +# } # service {'bind9': # ensure => running # } @@ -49,4 +49,3 @@ node default { # proto => "tcp" # } #} - diff --git a/global/post-tasks.d/010cosmos-modules b/global/post-tasks.d/010cosmos-modules new file mode 100755 index 00000000..f099a860 --- /dev/null +++ b/global/post-tasks.d/010cosmos-modules @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Dynamically configure /etc/puppet/cosmos-modules.conf +# +# The content of that file is chosen according to: +# +# 1. If the file is actually present in the model, use that. +# 2. If there is a script called /etc/puppet/setup_cosmos_models, run that. +# 3. If the file still doesn't exist, create it with the defaults in this script. +# + +set -e + +if [ -f "${COSMOS_MODEL}/overlay/etc/puppet/cosmos-modules.conf" ]; then + test "$COSMOS_VERBOSE" = "y" && \ + echo "$0: /etc/puppet/cosmos-modules.conf is present in the model, exiting" + exit 0 +fi + +if [ -x /etc/puppet/setup_cosmos_models ]; then + test "$COSMOS_VERBOSE" = "y" && \ + echo "$0: Updating /etc/puppet/cosmos-modules.conf with /etc/puppet/setup_cosmos_models" + /etc/puppet/setup_cosmos_models + + test -f /etc/puppet/cosmos-modules.conf && exit 0 +fi + +test "$COSMOS_VERBOSE" = "y" && \ + echo "$0: Creating/updating /etc/puppet/cosmos-modules.conf with defaults from this script" + +cat > /etc/puppet/cosmos-modules.conf << EOF +# File created/updated by $0 +# +concat puppetlabs/concat yes +stdlib puppetlabs/stdlib yes +#ufw attachmentgenie/ufw yes +#apt puppetlabs/apt yes +EOF From c3c6171f965ba9914d37fe1b38fab96e3a8c97da Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 19 Jan 2023 17:30:18 +0100 Subject: [PATCH 058/111] modules, not models --- global/post-tasks.d/010cosmos-modules | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/global/post-tasks.d/010cosmos-modules b/global/post-tasks.d/010cosmos-modules index f099a860..af116964 100755 --- a/global/post-tasks.d/010cosmos-modules +++ b/global/post-tasks.d/010cosmos-modules @@ -5,7 +5,7 @@ # The content of that file is chosen according to: # # 1. If the file is actually present in the model, use that. -# 2. If there is a script called /etc/puppet/setup_cosmos_models, run that. +# 2. If there is a script called /etc/puppet/setup_cosmos_modules, run that. # 3. If the file still doesn't exist, create it with the defaults in this script. # @@ -17,10 +17,10 @@ if [ -f "${COSMOS_MODEL}/overlay/etc/puppet/cosmos-modules.conf" ]; then exit 0 fi -if [ -x /etc/puppet/setup_cosmos_models ]; then +if [ -x /etc/puppet/setup_cosmos_modules ]; then test "$COSMOS_VERBOSE" = "y" && \ - echo "$0: Updating /etc/puppet/cosmos-modules.conf with /etc/puppet/setup_cosmos_models" - /etc/puppet/setup_cosmos_models + echo "$0: Updating /etc/puppet/cosmos-modules.conf with /etc/puppet/setup_cosmos_modules" + /etc/puppet/setup_cosmos_modules test -f /etc/puppet/cosmos-modules.conf && exit 0 fi From 906e483c53fe1b28deea8fe31d54e54a6ee6d9a9 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 19 Jan 2023 17:46:23 +0100 Subject: [PATCH 059/111] speling --- docs/cosmos-puppet-ops.mkd | 105 ++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 53 deletions(-) diff --git a/docs/cosmos-puppet-ops.mkd b/docs/cosmos-puppet-ops.mkd index 0d8515bf..b1e0a4da 100644 --- a/docs/cosmos-puppet-ops.mkd +++ b/docs/cosmos-puppet-ops.mkd @@ -5,10 +5,10 @@ Introduction ============ -This document describes how to setup and run systems and service operations for a small to midsized +This document describes how to setup and run systems and service operations for a small to mid-sized systems collection while maintaining scalability, security and auditability for changes. -The process described below is based on opensource components and assumes a Linux-based hosting -infrastructure. These limitations could easily be removed though. This document describes the +The process described below is based on open source components and assumes a Linux-based hosting +infrastructure. These limitations could easily be removed though. This document describes the multiverse template for combining cosmos and puppet. @@ -16,18 +16,18 @@ Design Requirements =================== The cosmos system has been used to operate security-critical infrastructure for a few years before -it was combined with puppet into the multiverse template. +it was combined with puppet into the multiverse template. -Several of the design requirements below are fulfilled by comos alone, while some (eg consistency) +Several of the design requirements below are fulfilled by cosmos alone, while some (eg consistency) are easier to achieve using puppet than with cosmos alone. Consistency ----------- -Changes should be applied atomically (locally on each host) across multiple system components on multiple +Changes should be applied atomically (locally on each host) across multiple system components on multiple physical and logical hosts (aka system state). The change mechanism should permit verification of state -consistency and all modifications should be idempotents, i.e the same operation -performend twice on the same system state should not in itself cause a problem. +consistency and all modifications should be idempotents, i.e the same operation +performed twice on the same system state should not in itself cause a problem. Auditability ------------ @@ -40,12 +40,12 @@ Authenticity ------------ All changes must be authenticated by private keys in the personal possession of privileged -system operators before applied to system state aswell as at any point in the future. +system operators before applied to system state as well as at any point in the future. Simplicity ---------- -The system must be simple and must not rely on external services to be online to maintain +The system must be simple and must not rely on external services to be online to maintain state except when new state is being requested and applied. When new state is being requested external dependencies must be kept to a minimum. @@ -53,8 +53,8 @@ Architecture ============ The basic architecture of puppet is to use a VCS (git) to manage and distribute changes to a -staging area on each managed host. At the staging area the changes are authenticated (using -tag signatures) and if valid, distributed to the host using local rsync. Before and after +staging area on each managed host. At the staging area the changes are authenticated (using +tag signatures) and if valid, distributed to the host using local rsync. Before and after hooks (using run-parts) are used to provide programmatic hooks. Administrative Scope @@ -62,15 +62,15 @@ Administrative Scope The repository constitutes the administrative domain of a multiverse setup: each host is connected to (i.e runs cosmos off of) a single GIT repository and derives trust from signed -tags on that repository. A host cannot belong to more than 1 administratve domain but each -administrative domains can host multiple DNS domains - all hosts in a single repository +tags on that repository. A host cannot belong to more than 1 administrative domain but each +administrative domains can host multiple DNS domains - all hosts in a single repository doesn't need to be in the same zone. The role of Puppet ------------------ -In the multiverse template, the cosmos system is used to authenticate and distribute changes -and prepare the system state for running puppet. Puppet is used to apply idempotent changes +In the multiverse template, the cosmos system is used to authenticate and distribute changes +and prepare the system state for running puppet. Puppet is used to apply idempotent changes to the system state using "puppet apply". ~~~~~ {.ditaa .no-separation} @@ -79,7 +79,7 @@ to the system state using "puppet apply". +------------+ +------+ | ^ | | | - (change) (manifests) + (change) (manifests) | | +--------+ | | puppet |<---+ @@ -87,44 +87,44 @@ to the system state using "puppet apply". ~~~~~ Note that there is no puppet master in this setup so collective resources cannot be used -in multiverse. Instead 'fabric' is used to provide a simple way to loop over subsets of +in multiverse. Instead 'fabric' is used to provide a simple way to loop over subsets of the hosts in a managed domain. -Private data (eg system credentials, application passwords, or private keys) are encrypted +Private data (eg system credentials, application passwords, or private keys) are encrypted to a master host-specific PGP key before stored in the cosmos repo. System state can be tied to classes used to classify systems into roles (eg "database server" -or "webserver"). System classes can be assigned by regular expressions on the fqdn (eg all -hosts named db-\* is assigned to the "database server" class) using a custom puppet ENC. +or "webserver"). System classes can be assigned by regular expressions on the fqdn (eg all +hosts named db-\* is assigned to the "database server" class) using a custom puppet ENC. The system classes are also made available to 'fabric' in a custom fabfile. Fabric (or fab) -is a simple frontend to ssh that allows an operator to run commands on multiple remote +is a simple frontend to ssh that allows an operator to run commands on multiple remote hosts at once. Trust ----- -All data in the system is maintained in a cosmos GIT repository. A change is -requested by signing a tag in the repository with a system-wide well-known name-prefix. -The tag name typically includes the date and a counter to make it unique. +All data in the system is maintained in a cosmos GIT repository. A change is +requested by signing a tag in the repository with a system-wide well-known name-prefix. +The tag name typically includes the date and a counter to make it unique. -The signature on the tag is authenticated against a set of trusted keys maintained in the +The signature on the tag is authenticated against a set of trusted keys maintained in the repository itself - so that one trusted system operator must be present to authenticate addition or -removal of another trusted system operator. This authentication of tags is done in addition +removal of another trusted system operator. This authentication of tags is done in addition to authenticating access to the GIT repository when the changes are pushed. Trust is typically -bootstrapped when a repository is first established. This model also serves to provide auditability +bootstrapped when a repository is first established. This model also serves to provide auditability of all changes for as long as repository history is retained. Access to hosts is done through ssh with ssh-key access. The ssh keys are typically maintained -using either puppet or cosmos natively. +using either puppet or cosmos natively. Consistency ----------- As a master-less architecture, multiverse relies on _eventual consistency_: changes will eventually -be applied to all hosts. In such a model it becomes very imporant that changes are idempotent, so +be applied to all hosts. In such a model it becomes very important that changes are idempotent, so that applying a change multiple times (in an effort to get dependent changes through) won't cause -an issue. Using native cosmos, such changes are achived using timestamp-files that control entry +an issue. Using native cosmos, such changes are archived using timestamp-files that control entry into code-blocks: ``` @@ -136,20 +136,20 @@ fi ``` This pattern is mostly replaced in multiverse by using puppet manifests and modules that -are inherently indempotent but it can nevertheless be a useful addition to the toolchain. +are inherently idempotent but it can nevertheless be a useful addition to the toolchain. Implementation ============== Implementation is based on two major components: cosmos and puppet. The cosmos system was created by Simon Josefsson and Fredrik Thulin as a simple and secure way to distribute files -and run pre- and post-processors (using run-parts). This allows for a simple, yet complete +and run pre- and post-processors (using run-parts). This allows for a simple, yet complete mechanism for updating system state. The second component is puppet which is run in masterless (aka puppet apply) mode on files distributed and authenticated using cosmos. Puppet is a widely deployed way to describe system state using a set of idempotent operations. In theory, anything that can de done -using puppet can be done using cosmos post-processors but puppet allows for greater +using puppet can be done using cosmos post-processors but puppet allows for greater abstraction which greatly increases readability. The combination of puppet and cosmos is maintained on github in the 'SUNET/multiverse' @@ -177,14 +177,14 @@ this is in the 'git-core' package: # apt-get install git-core ``` -Also install 'fabric' - a very useful too for multiple-host-ssh that is integrated into +Also install 'fabric' - a very useful too for multiple-host-ssh that is integrated into multiverse. Fabric provides the 'fab' command which will be introduced later on. ``` # apt-get install fabric ``` -These two tools (git & fabric) are only needed on mashines where system operators work. +These two tools (git & fabric) are only needed on machines where system operators work. Next clone git@github.com:SUNET/multiverse.git - this will form the basis of your cosmos+puppet repository: @@ -201,8 +201,8 @@ features as the multiverse codebase evolves. # git remote rename origin multiverse ``` -Now add a new remote pointing to the git repo where you are going to be pushing -changes for your administrative domain. Also add a read-only version of this remote +Now add a new remote pointing to the git repo where you are going to be pushing +changes for your administrative domain. Also add a read-only version of this remote as 'ro'. The read-only remote is used by multiverse scripts during host bootstrap. ``` @@ -226,7 +226,7 @@ Finally create a branch for the 'multiverse' upstream so you can merge changes t ``` Note that you can maintain your repo on just about any git hosting platform, including -github, gitorius or your own local setup as long as it supports read-only access to your +github, gitorious or your own local setup as long as it supports read-only access to your repository. It is important that the remotes called 'origin' and 'ro' refer to your repository and not to anything else (like a private version of multiverse). @@ -266,7 +266,7 @@ ssh as root. This requires that root key trust be established in advance. The ad command creates and commits the necessary changes to the repository to add a host named $fqdn. Only fully qualified hostnames should ever be used in cosmos+puppet. -The boostrap process will create a cron-job on $fqdn that runs +The bootstrap process will create a cron-job on $fqdn that runs ``` # cosmos update && cosmos apply @@ -284,8 +284,8 @@ To bootstrap a machine that is not yet configured in DNS, use the following opti Defining naming rules --------------------- -A naming rule is a mapping from a name to a set of puppet classes. These are defined in -the file 'global/overlay/etc/puppet/cosmos-rules.yaml' (linked to the toplevel directory +A naming rule is a mapping from a name to a set of puppet classes. These are defined in +the file 'global/overlay/etc/puppet/cosmos-rules.yaml' (linked to the top level directory in multiverse). This is a YAML format file whose keys are regular expressions and whose values are lists of puppet class definitions. Here is an example that assigns all hosts with names on the form ns\.example.com to the 'nameserver' class. @@ -295,7 +295,7 @@ with names on the form ns\.example.com to the 'nameserver' class. nameserver: ``` -Note that the value is a hash with an empty value ('namserver:') and not just a string +Note that the value is a hash with an empty value ('nameserver:') and not just a string value. Since regular expressions can also match on whole strings so the following is also @@ -307,7 +307,7 @@ smtp.example.com: relay: smtp.upstream.example.com ``` -In this example the mailserver puppet class is given the relay argument (cf puppet +In this example the mailserver puppet class is given the relay argument (cf puppet documentation). Fabric integration @@ -323,11 +323,11 @@ Given the above example the following command would reload all nameservers: Creating a change-request ------------------------- -After performing whatever changes you want to the reqpository, commit the changes as usual +After performing whatever changes you want to the repository, commit the changes as usual and then sign an appropriately formatted tag. This last operation is wrapped in the 'bump-tag' command: ``` -# git commit -m "some changes" global/overlay/somethig or/other/files +# git commit -m "some changes" global/overlay/something or/other/files # ./bump-tag ``` @@ -337,7 +337,7 @@ gpg commands to create, sign and push the correct tag. Puppet modules -------------- -Puppet modules can be maintained using a designated cosmos pre-task that reads a file +Puppet modules can be maintained using a designated cosmos pre-task that reads a file global/overlay/etc/puppet/cosmos-modules.conf. This file is a simple text-format file with 3 columns: @@ -357,17 +357,17 @@ python https://github.com/SUNET/puppet-python.git yes hiera-gpg https://github.com/SUNET/hiera-gpg.git no ``` -This is an example file - the first field is the name of the module, the second is +This is an example file - the first field is the name of the module, the second is the source: either a puppetlabs path or a git URL. The final field is 'yes' if the module should be automatically updated or 'no' if it should only be installed. As usual lines beginning with '#' are silently ignored. -This file is processed in a cosmos pre-hook so the modules should be available for +This file is processed in a cosmos pre-hook so the modules should be available for use in the puppet post-hook. By default the file contains several lines that are commented out so review this file as you start a new multiverse setup. In order to add a new module, the best way is to commit a change to this file and -tag this change, allowing time for the module to get installed everywhere before +tag this change, allowing time for the module to get installed everywhere before adding a change that relies on this module. HOWTO and Common Tasks @@ -379,7 +379,7 @@ Adding a new operator Add the ascii-armoured key in a file in `global/overlay/etc/cosmos/keys` with a `.pub` extension ``` -# git add global/overlay/etc/cosmos/keys/thenewoperator.pub +# git add global/overlay/etc/cosmos/keys/thenewoperator.pub # git commit -m "the new operator" \ global/overlay/etc/cosmos/keys/thenewoperator.pub # ./bump-tag @@ -388,7 +388,7 @@ Add the ascii-armoured key in a file in `global/overlay/etc/cosmos/keys` with a Removing an operator -------------------- -Identitfy the public key file in `global/overlay/etc/cosmos/keys` +Identify the public key file in `global/overlay/etc/cosmos/keys` ``` # git rm global/overlay/etc/cosmos/keys/X.pub @@ -465,4 +465,3 @@ On all hosts: ``` # fab -- reboot # danger Will Robinsson! ``` - From 715105aadba4c53cb2a60990d18330c9e1a26b55 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 19 Jan 2023 17:56:51 +0100 Subject: [PATCH 060/111] add documentation for dynamically generated cosmos-modules.conf --- docs/cosmos-puppet-ops.mkd | 38 +++++++++++++++++---------- global/post-tasks.d/010cosmos-modules | 1 + 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/docs/cosmos-puppet-ops.mkd b/docs/cosmos-puppet-ops.mkd index b1e0a4da..af437459 100644 --- a/docs/cosmos-puppet-ops.mkd +++ b/docs/cosmos-puppet-ops.mkd @@ -337,30 +337,30 @@ gpg commands to create, sign and push the correct tag. Puppet modules -------------- -Puppet modules can be maintained using a designated cosmos pre-task that reads a file -global/overlay/etc/puppet/cosmos-modules.conf. This file is a simple text-format file -with 3 columns: +Puppet modules can be maintained using a designated cosmos pre-task that reads the file +/etc/puppet/cosmos-modules.conf. This file is a simple text-format file +with either three (for puppetlabs modules) or four columns: ``` # -# name source (puppetlabs fq name or git url) upgrade (yes/no) +# name source (puppetlabs fq name or git url) upgrade (yes/no) tag_pattern # -concat puppetlabs/concat no -stdlib puppetlabs/stdlib no -cosmos https://github.com/SUNET/puppet-cosmos.git yes -ufw https://github.com/SUNET/puppet-module-ufw.git yes apt puppetlabs/apt no +concat puppetlabs/concat no +cosmos https://github.com/SUNET/puppet-cosmos.git yes sunet-2* +#golang elithrar/golang yes +python https://github.com/SUNET/puppet-python.git yes sunet-2* +stdlib puppetlabs/stdlib no +ufw https://github.com/SUNET/puppet-module-ufw.git yes sunet-2* vcsrepo puppetlabs/vcsrepo no xinetd puppetlabs/xinetd no -#golang elithrar/golang yes -python https://github.com/SUNET/puppet-python.git yes -hiera-gpg https://github.com/SUNET/hiera-gpg.git no ``` This is an example file - the first field is the name of the module, the second is -the source: either a puppetlabs path or a git URL. The final field is 'yes' if the -module should be automatically updated or 'no' if it should only be installed. As usual -lines beginning with '#' are silently ignored. +the source: either a puppetlabs path or a git URL. The third field is 'yes' if the +module should be automatically updated or 'no' if it should only be installed. The +fourth field is a tag pattern to use (same style as the cosmos tag pattern). +As usual lines beginning with '#' are silently ignored. This file is processed in a cosmos pre-hook so the modules should be available for use in the puppet post-hook. By default the file contains several lines that are @@ -370,6 +370,16 @@ In order to add a new module, the best way is to commit a change to this file an tag this change, allowing time for the module to get installed everywhere before adding a change that relies on this module. +As there might be a need to use different sets of modules (or different tag patterns) +on different hosts in an ops-repo, the contents of this file can be controlled in +different ways: + + 1. If the file is present in the model, it is used as such. + 2. If there is a script called /etc/puppet/setup_cosmos_modules, that script is executed. + If the file /etc/puppet/cosmos-modules.conf does not exist after this script runs, + proceed to step 3, otherwise use this dynamically generated list of modules. + 3. Use a (very small) default set of modules from the pre-hook global/post-tasks.d/010cosmos-modules. + HOWTO and Common Tasks ====================== diff --git a/global/post-tasks.d/010cosmos-modules b/global/post-tasks.d/010cosmos-modules index af116964..092815a2 100755 --- a/global/post-tasks.d/010cosmos-modules +++ b/global/post-tasks.d/010cosmos-modules @@ -35,4 +35,5 @@ concat puppetlabs/concat yes stdlib puppetlabs/stdlib yes #ufw attachmentgenie/ufw yes #apt puppetlabs/apt yes +#cosmos https://github.com/SUNET/puppet-cosmos.git yes EOF From bc17ee13541337bf30fc3dcd2767db73dd131806 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Tue, 24 Jan 2023 10:01:59 +0100 Subject: [PATCH 061/111] Don't confuse containers to connect to them self When the hostname pointed to loopback the containers tried to connect to them self instead of the host. --- .../etc/cosmos/apt/bootstrap-cosmos.sh | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh index c31cea78..5e27f3dd 100755 --- a/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh +++ b/global/overlay/etc/cosmos/apt/bootstrap-cosmos.sh @@ -30,7 +30,7 @@ export DEBIAN_FRONTEND='noninteractive' apt-get -y update apt-get -y upgrade -for pkg in rsync git git-core wget gpg; do +for pkg in rsync git git-core wget gpg jq; do # script is running with "set -e", use "|| true" to allow packages to not # exist without stopping the script apt-get -y install $pkg || true @@ -56,16 +56,43 @@ mv -f /etc/rc.local.new /etc/rc.local touch /etc/run-cosmos-at-boot # If this cloud-config is set, it will interfere with our changes to /etc/hosts -if [ -f /etc/cloud/cloud.cfg ]; then - sed -i 's/manage_etc_hosts: true/manage_etc_hosts: false/g' /etc/cloud/cloud.cfg -fi +# The configuration seems to move around between cloud-config versions +for file in /etc/cloud/cloud.cfg /etc/cloud/cloud.cfg.d/01_debian_cloud.cfg; do + if [ -f ${file} ]; then + sed -i 's/manage_etc_hosts: true/manage_etc_hosts: false/g' ${file} + fi +done -# Remove potential $hostname.novalocal line from /etc/hosts, added by cloud-init -sed -i.bak -e "s/^127\.0\.1\.1 $(hostname)\..*novalocal.*//1" /etc/hosts +# Remove potential $hostname.novalocal, added by cloud-init or Debian default +# from /etc/hosts. We add our own further down. +# +# From # https://www.debian.org/doc/manuals/debian-reference/ch05.en.html#_the_hostname_resolution: +# "For a system with a permanent IP address, that permanent IP address should +# be used here instead of 127.0.1.1." +sed -i.bak -e "/127\.0\.1\.1/d" /etc/hosts + +vendor=$(lsb_release -is) +version=$(lsb_release -rs) +min_version=1337 +host_ip=127.0.1.1 +if [ "${vendor}" = "Ubuntu" ]; then + min_version=20.04 +elif [ "${vendor}" = "Debian" ]; then + min_version=11 +fi hostname $cmd_hostname short=`echo ${cmd_hostname} | awk -F. '{print $1}'` -echo "127.0.1.1 ${cmd_hostname} ${short}" >> /etc/hosts +# Only change behavior on modern OS where `ip -j` outputs a json predictuble +# enought to work with. +# +# Use `dpkg` to easier compare ubuntu versions. +if dpkg --compare-versions "${version}" "ge" "${min_version}"; then + # When hostname pointed to loopback in /etc/hosts containers running on the + # host tried to connect to the container itself instead of the host. + host_ip=$(ip -j address show "$(ip -j route show default | jq -r '.[0].dev')" | jq -r .[0].addr_info[0].local) +fi +echo "${host_ip} ${cmd_hostname} ${short}" >> /etc/hosts # Set up cosmos models. They are in the order of most significant first, so we want # From f1ab4506f198d3d5934a9d3c1e7b5bbdc63d44b4 Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Wed, 25 Jan 2023 21:52:20 +0100 Subject: [PATCH 062/111] iaas-setup.sh: support default user not existing For CNaaS machines we supply cloud-init user-data that does not create a default user, in this case the script would exit half-way through. Now it only tries to remove a user if it exists in the first place. --- iaas-setup.sh | 58 ++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/iaas-setup.sh b/iaas-setup.sh index 30c9db06..4ce578ba 100755 --- a/iaas-setup.sh +++ b/iaas-setup.sh @@ -26,39 +26,45 @@ fi # === export LC_CTYPE=C.UTF-8 -# Make sure there is no systemd process running as the initial cloud image user -# # after the "enable root" step in prepare-iaas-$os. If there are any # -# proceses still running as the specified user the "userdel" command # below -# will fail. -# -# Depending on how long we have waited between running the "enable root" -# script and this one it is possible the process has timed out on its own, -# so run this command before doing "set -e" in case there is no process -# to match. -pkill -u "$os" -xf "/lib/systemd/systemd --user" +# Remove default user if present +if id "$os"; then + # Make sure there is no systemd process running as the initial cloud image user + # after the "enable root" step in prepare-iaas-$os. If there are any + # proceses still running as the specified user the "userdel" command + # below will fail. + # + # Depending on how long we have waited between running the "enable root" + # script and this one it is possible the process has timed out on its own, + # so run this command before doing "set -e" in case there is no process + # to match. + pkill -u "$os" -xf "/lib/systemd/systemd --user" -# Make sure the process has gone away before continuing -sleep_seconds=1 -attempt=1 -max_attempts=10 -while pgrep -u "$os" -xf "/lib/systemd/systemd --user"; do - if [ $attempt -gt $max_attempts ]; then - echo "failed waiting for systemd process to exit, please investigate" + # Make sure the process has gone away before continuing + sleep_seconds=1 + attempt=1 + max_attempts=10 + while pgrep -u "$os" -xf "/lib/systemd/systemd --user"; do + if [ $attempt -gt $max_attempts ]; then + echo "failed waiting for systemd process to exit, please investigate" + exit 1 + fi + echo "systemd process still running as '$os' user, this is attempt $attempt out of $max_attempts, sleeping for $sleep_seconds seconds..." + sleep $sleep_seconds + attempt=$((attempt + 1)) + done + + # While the man page for "userdel" recommends using "deluser" we can not + # run "deluser" with "--remove-home" without installing more than the + # already included `perl-base` package on debian, so stick with the low + # level utility. + if ! userdel --remove "$os"; then exit 1 fi - echo "systemd process still running as '$os' user, this is attempt $attempt out of $max_attempts, sleeping for $sleep_seconds seconds..." - sleep $sleep_seconds - attempt=$((attempt + 1)) -done +fi # From this point we expect all commands to succeed set -e -# While the man page for "userdel" recommends using "deluser" we can not -# run "deluser" with "--remove-home" without installing more than the -# already included `perl-base` package on debian, so stick with the low -# level utility. -userdel --remove "$os" rm /etc/sudoers.d/* # Make sure en_US.UTF-8 is present in the system, expected by at least From 2e0ccdd92d76e4ab8ea170cb96a8affbcc35aa2a Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Thu, 26 Jan 2023 09:53:36 +0100 Subject: [PATCH 063/111] Add example setup_cosmos_modules script This patch adds an example script written in python to help people get started with writing their own implementation. The docs are also updated. --- docs/cosmos-puppet-ops.mkd | 3 + .../etc/puppet/setup_cosmos_modules.example | 134 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100755 global/overlay/etc/puppet/setup_cosmos_modules.example diff --git a/docs/cosmos-puppet-ops.mkd b/docs/cosmos-puppet-ops.mkd index af437459..5933cfec 100644 --- a/docs/cosmos-puppet-ops.mkd +++ b/docs/cosmos-puppet-ops.mkd @@ -380,6 +380,9 @@ different ways: proceed to step 3, otherwise use this dynamically generated list of modules. 3. Use a (very small) default set of modules from the pre-hook global/post-tasks.d/010cosmos-modules. +There is an example implementation of the script to help you get started with writing your own, +available in global/etc/puppet/setup_cosmos_modules.example. + HOWTO and Common Tasks ====================== diff --git a/global/overlay/etc/puppet/setup_cosmos_modules.example b/global/overlay/etc/puppet/setup_cosmos_modules.example new file mode 100755 index 00000000..9b4c7e25 --- /dev/null +++ b/global/overlay/etc/puppet/setup_cosmos_modules.example @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 + +try: + from configobj import ConfigObj + + os_info = ConfigObj("/etc/os-release") +except (IOError, ModuleNotFoundError): + os_info = None + + +modulesfile: str = "/etc/puppet/cosmos-modules.conf" +modules: dict = { + "concat": { + "repo": "https://github.com/SUNET/puppetlabs-concat.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "stdlib": { + "repo": "https://github.com/SUNET/puppetlabs-stdlib.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "cosmos": { + "repo": "https://github.com/SUNET/puppet-cosmos.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "ufw": { + "repo": "https://github.com/SUNET/puppet-module-ufw.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "apt": { + "repo": "https://github.com/SUNET/puppetlabs-apt.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "vcsrepo": { + "repo": "https://github.com/SUNET/puppetlabs-vcsrepo.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "xinetd": { + "repo": "https://github.com/SUNET/puppetlabs-xinetd.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "python": { + "repo": "https://github.com/SUNET/puppet-python.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "hiera-gpg": { + "repo": "https://github.com/SUNET/hiera-gpg.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "pound": { + "repo": "https://github.com/SUNET/puppet-pound.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "augeas": { + "repo": "https://github.com/SUNET/puppet-augeas.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "bastion": { + "repo": "https://github.com/SUNET/puppet-bastion.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "pyff": { + "repo": "https://github.com/samlbits/puppet-pyff.git", + "upgrade": "yes", + "tag": "puppet-pyff-*", + }, + "dhcp": { + "repo": "https://github.com/SUNET/puppetlabs-dhcp.git", + "upgrade": "yes", + "tag": "sunet_dev-2*", + }, + "varnish": { + "repo": "https://github.com/samlbits/puppet-varnish.git", + "upgrade": "yes", + "tag": "puppet-varnish-*", + }, + "apparmor": { + "repo": "https://github.com/SUNET/puppet-apparmor.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "docker": { + "repo": "https://github.com/SUNET/garethr-docker.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "network": { + "repo": "https://github.com/SUNET/attachmentgenie-network.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "sunet": { + "repo": "https://github.com/SUNET/puppet-sunet.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "sysctl": { + "repo": "https://github.com/SUNET/puppet-sysctl.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "nagioscfg": { + "repo": "https://github.com/SUNET/puppet-nagioscfg.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, +} + +# When/if we want we can do stuff to modules here +if os_info: + if os_info["VERSION_CODENAME"] == "bullseye": + pass + +with open(modulesfile, "w") as fh: + for key in modules: + fh.write( + "{0:11} {1} {2} {3}\n".format( + key, + modules[key]["repo"], + modules[key]["upgrade"], + modules[key]["tag"], + ) + ) From bb6288945484a9fa5210f1d167ff5619bc774ba7 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Fri, 27 Jan 2023 10:34:59 +0100 Subject: [PATCH 064/111] Move example script to docs --- docs/cosmos-puppet-ops.mkd | 2 +- .../overlay/etc/puppet => docs}/setup_cosmos_modules.example | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {global/overlay/etc/puppet => docs}/setup_cosmos_modules.example (100%) diff --git a/docs/cosmos-puppet-ops.mkd b/docs/cosmos-puppet-ops.mkd index 5933cfec..1d121b89 100644 --- a/docs/cosmos-puppet-ops.mkd +++ b/docs/cosmos-puppet-ops.mkd @@ -381,7 +381,7 @@ different ways: 3. Use a (very small) default set of modules from the pre-hook global/post-tasks.d/010cosmos-modules. There is an example implementation of the script to help you get started with writing your own, -available in global/etc/puppet/setup_cosmos_modules.example. +available in docs/setup_cosmos_modules.example. HOWTO and Common Tasks ====================== diff --git a/global/overlay/etc/puppet/setup_cosmos_modules.example b/docs/setup_cosmos_modules.example similarity index 100% rename from global/overlay/etc/puppet/setup_cosmos_modules.example rename to docs/setup_cosmos_modules.example From 57b302a299f14caead2ddeba285093aeab3cf760 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Mon, 30 Jan 2023 11:21:01 +0100 Subject: [PATCH 065/111] Only update the database when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this fix: ``` ➜ nunoc-ops git:(master) make db On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean make: *** [db] Error 1 ``` With this fix: ``` ➜ swamid-ops git:(master) ✗ make db make: Nothing to be done for `db'. ``` Will make it easier to only use `make tag` when to sign changes. --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8936489e..7ad799ef 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,9 @@ cosmos: upgrade: fab upgrade -db: +db: global/overlay/etc/puppet/cosmos-db.yaml + +global/overlay/etc/puppet/cosmos-db.yaml: global/overlay/etc/puppet/cosmos-rules.yaml: @python ./fabfile/db.py > global/overlay/etc/puppet/cosmos-db.yaml @git add global/overlay/etc/puppet/cosmos-db.yaml && git commit -m "update db" global/overlay/etc/puppet/cosmos-db.yaml From d604d2fab58f2c7432c0cc5fd8ec532a2c7f0795 Mon Sep 17 00:00:00 2001 From: Leif Johansson Date: Mon, 9 Jan 2017 22:03:38 +0100 Subject: [PATCH 066/111] set no-protection on the private key --- global/pre-tasks.d/040hiera-gpg | 1 + 1 file changed, 1 insertion(+) diff --git a/global/pre-tasks.d/040hiera-gpg b/global/pre-tasks.d/040hiera-gpg index e5de6da5..3aa30376 100755 --- a/global/pre-tasks.d/040hiera-gpg +++ b/global/pre-tasks.d/040hiera-gpg @@ -44,6 +44,7 @@ Name-Comment: Hiera GPG key Name-Email: root@`hostname --fqdn` Expire-Date: 0 # Do a commit here, so that we can later print "done" :-) +%no-protection %commit %echo done EOF From 4601e0bf08ade3b7d94ed436aad9d011a5b62d2d Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Mon, 30 Jan 2023 14:12:13 +0100 Subject: [PATCH 067/111] make sure we get clean checkouts --- global/post-tasks.d/018packages | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/global/post-tasks.d/018packages b/global/post-tasks.d/018packages index ee1889f6..a48efbee 100755 --- a/global/post-tasks.d/018packages +++ b/global/post-tasks.d/018packages @@ -42,7 +42,8 @@ if [ -f $CONFIG -o $LOCALCONFIG ]; then if [ "$src" != "$(git config remote.origin.url)" ]; then git config remote.origin.url $src fi - git pull -q + # Update repo and clean out any local inconsistencies + git pull -q || (git fetch && git reset --hard) else continue fi From e212b6f56f73f3038a4fcfd7921528cb8335a25b Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Tue, 31 Jan 2023 08:19:41 +0100 Subject: [PATCH 068/111] Support master branch being renamed to main Fixes: ``` 70run-post-tasks: invoking /var/cache/cosmos/model/post-tasks.d/018packages Your configuration specifies to merge with the ref 'refs/heads/master' from the remote, but no such ref was fetched. ``` --- global/post-tasks.d/018packages | 2 ++ 1 file changed, 2 insertions(+) diff --git a/global/post-tasks.d/018packages b/global/post-tasks.d/018packages index a48efbee..39569b28 100755 --- a/global/post-tasks.d/018packages +++ b/global/post-tasks.d/018packages @@ -42,6 +42,8 @@ if [ -f $CONFIG -o $LOCALCONFIG ]; then if [ "$src" != "$(git config remote.origin.url)" ]; then git config remote.origin.url $src fi + # Support master branch being renamed to main + git branch --all | grep -q '^[[:space:]]*remotes/origin/main$' && git checkout main # Update repo and clean out any local inconsistencies git pull -q || (git fetch && git reset --hard) else From 281f818062bc00d81344c8c24026abaf130f024d Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Wed, 1 Feb 2023 11:19:49 +0100 Subject: [PATCH 069/111] Update setup_cosmos_modules.example * Only update cosmos-modules.conf if a change is needed * Do an atomic replace of the file if updating it * Add a note at the top mentioning that it is tool-generated * Make pylint and black happy Tested in ubuntu 18.04. --- docs/setup_cosmos_modules.example | 318 +++++++++++++++++++----------- 1 file changed, 200 insertions(+), 118 deletions(-) diff --git a/docs/setup_cosmos_modules.example b/docs/setup_cosmos_modules.example index 9b4c7e25..6b1b9c61 100755 --- a/docs/setup_cosmos_modules.example +++ b/docs/setup_cosmos_modules.example @@ -1,134 +1,216 @@ #!/usr/bin/env python3 +""" Write out a puppet cosmos-modules.conf """ + +import hashlib +import os +import os.path +import sys try: from configobj import ConfigObj - os_info = ConfigObj("/etc/os-release") + OS_INFO = ConfigObj("/etc/os-release") except (IOError, ModuleNotFoundError): - os_info = None + OS_INFO = None -modulesfile: str = "/etc/puppet/cosmos-modules.conf" -modules: dict = { - "concat": { - "repo": "https://github.com/SUNET/puppetlabs-concat.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "stdlib": { - "repo": "https://github.com/SUNET/puppetlabs-stdlib.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "cosmos": { - "repo": "https://github.com/SUNET/puppet-cosmos.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "ufw": { - "repo": "https://github.com/SUNET/puppet-module-ufw.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "apt": { - "repo": "https://github.com/SUNET/puppetlabs-apt.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "vcsrepo": { - "repo": "https://github.com/SUNET/puppetlabs-vcsrepo.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "xinetd": { - "repo": "https://github.com/SUNET/puppetlabs-xinetd.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "python": { - "repo": "https://github.com/SUNET/puppet-python.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "hiera-gpg": { - "repo": "https://github.com/SUNET/hiera-gpg.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "pound": { - "repo": "https://github.com/SUNET/puppet-pound.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "augeas": { - "repo": "https://github.com/SUNET/puppet-augeas.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "bastion": { - "repo": "https://github.com/SUNET/puppet-bastion.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "pyff": { - "repo": "https://github.com/samlbits/puppet-pyff.git", - "upgrade": "yes", - "tag": "puppet-pyff-*", - }, - "dhcp": { - "repo": "https://github.com/SUNET/puppetlabs-dhcp.git", - "upgrade": "yes", - "tag": "sunet_dev-2*", - }, - "varnish": { - "repo": "https://github.com/samlbits/puppet-varnish.git", - "upgrade": "yes", - "tag": "puppet-varnish-*", - }, - "apparmor": { - "repo": "https://github.com/SUNET/puppet-apparmor.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "docker": { - "repo": "https://github.com/SUNET/garethr-docker.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "network": { - "repo": "https://github.com/SUNET/attachmentgenie-network.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "sunet": { - "repo": "https://github.com/SUNET/puppet-sunet.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "sysctl": { - "repo": "https://github.com/SUNET/puppet-sysctl.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, - "nagioscfg": { - "repo": "https://github.com/SUNET/puppet-nagioscfg.git", - "upgrade": "yes", - "tag": "sunet-2*", - }, -} +def get_file_hash(modulesfile): + """ + Based on https://github.com/python/cpython/pull/31930: should use + hashlib.file_digest() but it is only available in python 3.11 + """ + try: + with open(modulesfile, "rb") as fileobj: + digestobj = hashlib.sha256() + _bufsize = 2**18 + buf = bytearray(_bufsize) # Reusable buffer to reduce allocations. + view = memoryview(buf) + while True: + size = fileobj.readinto(buf) + if size == 0: + break # EOF + digestobj.update(view[:size]) + except FileNotFoundError: + return "" -# When/if we want we can do stuff to modules here -if os_info: - if os_info["VERSION_CODENAME"] == "bullseye": - pass + return digestobj.hexdigest() -with open(modulesfile, "w") as fh: + +def get_list_hash(file_lines): + """Get hash of list contents""" + + file_lines_hash = hashlib.sha256() + for line in file_lines: + file_lines_hash.update(line) + + return file_lines_hash.hexdigest() + + +def create_file_content(modules): + """ + Write out the expected file contents to a list so we can check the + expected checksum before writing anything + """ + file_lines = [] + file_lines.append( + "# Generated by {}\n".format( # pylint: disable=consider-using-f-string + os.path.basename(sys.argv[0]) + ).encode("utf-8") + ) for key in modules: - fh.write( - "{0:11} {1} {2} {3}\n".format( + file_lines.append( + "{0:11} {1} {2} {3}\n".format( # pylint: disable=consider-using-f-string key, modules[key]["repo"], modules[key]["upgrade"], modules[key]["tag"], - ) + ).encode("utf-8") ) + + return file_lines + + +def main(): + """Starting point of the program""" + + modulesfile: str = "/etc/puppet/cosmos-modules.conf" + modulesfile_tmp: str = modulesfile + ".tmp" + + modules: dict = { + "concat": { + "repo": "https://github.com/SUNET/puppetlabs-concat.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "stdlib": { + "repo": "https://github.com/SUNET/puppetlabs-stdlib.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "cosmos": { + "repo": "https://github.com/SUNET/puppet-cosmos.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "ufw": { + "repo": "https://github.com/SUNET/puppet-module-ufw.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "apt": { + "repo": "https://github.com/SUNET/puppetlabs-apt.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "vcsrepo": { + "repo": "https://github.com/SUNET/puppetlabs-vcsrepo.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "xinetd": { + "repo": "https://github.com/SUNET/puppetlabs-xinetd.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "python": { + "repo": "https://github.com/SUNET/puppet-python.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "hiera-gpg": { + "repo": "https://github.com/SUNET/hiera-gpg.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "pound": { + "repo": "https://github.com/SUNET/puppet-pound.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "augeas": { + "repo": "https://github.com/SUNET/puppet-augeas.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "bastion": { + "repo": "https://github.com/SUNET/puppet-bastion.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "pyff": { + "repo": "https://github.com/samlbits/puppet-pyff.git", + "upgrade": "yes", + "tag": "puppet-pyff-*", + }, + "dhcp": { + "repo": "https://github.com/SUNET/puppetlabs-dhcp.git", + "upgrade": "yes", + "tag": "sunet_dev-2*", + }, + "varnish": { + "repo": "https://github.com/samlbits/puppet-varnish.git", + "upgrade": "yes", + "tag": "puppet-varnish-*", + }, + "apparmor": { + "repo": "https://github.com/SUNET/puppet-apparmor.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "docker": { + "repo": "https://github.com/SUNET/garethr-docker.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "network": { + "repo": "https://github.com/SUNET/attachmentgenie-network.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "sunet": { + "repo": "https://github.com/SUNET/puppet-sunet.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "sysctl": { + "repo": "https://github.com/SUNET/puppet-sysctl.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + "nagioscfg": { + "repo": "https://github.com/SUNET/puppet-nagioscfg.git", + "upgrade": "yes", + "tag": "sunet-2*", + }, + } + + # When/if we want we can do stuff to modules here + if OS_INFO: + if OS_INFO["VERSION_CODENAME"] == "bullseye": + pass + + # Build list of expected file content + file_lines = create_file_content(modules) + + # Get hash of the list + list_hash = get_list_hash(file_lines) + + # Get hash of the existing file on disk + file_hash = get_file_hash(modulesfile) + + # Update the file if necessary + if list_hash != file_hash: + # Since we are reading the file with 'rb' when computing our hash use 'wb' when + # writing so we dont end up creating a file that does not match the + # expected hash + with open(modulesfile_tmp, "wb") as fileobj: + for line in file_lines: + fileobj.write(line) + + # Rename it in place so the update is atomic for anything else trying to + # read the file + os.rename(modulesfile_tmp, modulesfile) + + +if __name__ == "__main__": + main() From 49ba964897da59f4208a566dfa1a41c9fe417a93 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Thu, 2 Feb 2023 11:45:30 +0100 Subject: [PATCH 070/111] Wrap cosmos in scriptherder if available nunoc-ops and others has been doing this for ages by just modifing the cron file. --- global/overlay/etc/cron.d/cosmos | 2 +- global/overlay/usr/local/libexec/cosmos-cron-wrapper | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 global/overlay/usr/local/libexec/cosmos-cron-wrapper diff --git a/global/overlay/etc/cron.d/cosmos b/global/overlay/etc/cron.d/cosmos index 4eab8de1..38d14f58 100644 --- a/global/overlay/etc/cron.d/cosmos +++ b/global/overlay/etc/cron.d/cosmos @@ -1,4 +1,4 @@ SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin -*/15 * * * * root test -f /etc/no-automatic-cosmos || /usr/local/bin/run-cosmos +*/15 * * * * root test -f /etc/no-automatic-cosmos || /usr/local/libexec/cosmos-cron-wrapper diff --git a/global/overlay/usr/local/libexec/cosmos-cron-wrapper b/global/overlay/usr/local/libexec/cosmos-cron-wrapper new file mode 100644 index 00000000..2df85b50 --- /dev/null +++ b/global/overlay/usr/local/libexec/cosmos-cron-wrapper @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +RUN_COSMOS=/usr/local/bin/run-cosmos +SCRIPTHERDER_CMD='' + +if [ -f /usr/local/bin/scriptherder ]; then + SCRIPTHERDER_CMD='/usr/local/bin/scriptherder --mode wrap --syslog --name cosmos --' +fi + +${SCRIPTHERDER_CMD} ${RUN_COSMOS} From 84b29e4eaaaf6dd45e9ef10b38c26962d3899dc4 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Thu, 2 Feb 2023 11:49:10 +0100 Subject: [PATCH 071/111] Executable --- global/overlay/usr/local/libexec/cosmos-cron-wrapper | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 global/overlay/usr/local/libexec/cosmos-cron-wrapper diff --git a/global/overlay/usr/local/libexec/cosmos-cron-wrapper b/global/overlay/usr/local/libexec/cosmos-cron-wrapper old mode 100644 new mode 100755 From 17288b9d0be3c7491f3dbec93e3bd0c052af3b59 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 2 Feb 2023 18:32:18 +0100 Subject: [PATCH 072/111] init --- docs/setup_cosmos_modules.eduid.example | 300 ++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100755 docs/setup_cosmos_modules.eduid.example diff --git a/docs/setup_cosmos_modules.eduid.example b/docs/setup_cosmos_modules.eduid.example new file mode 100755 index 00000000..2b9dfdc4 --- /dev/null +++ b/docs/setup_cosmos_modules.eduid.example @@ -0,0 +1,300 @@ +#!/usr/bin/env python3 +# +# This script is responsible for creating/updating /etc/puppet/cosmos-modules.conf. +# +# If this script exits without creating that file, a default list of modules will be +# selected (by post-tasks.d/010cosmos-modules, the script that invokes this script). +# +# NOTES ABOUT THE IMPLEMENTATION: +# +# - Avoid any third party modules. We want this script to be re-usable in all ops-repos. +# - To make merging easier, try to keep all local alterations in the local_* functions. +# - Format with black and isort. Line width 120. +# - You probably ONLY want to change things in the local_get_modules_hook() function. +# + +import argparse +import csv +import json +import logging +import logging.handlers +import os +import re +import socket +import sys +from pathlib import Path +from typing import Dict, NewType, Optional, cast + +from pkg_resources import parse_version + +logger = logging.getLogger(__name__) # will be overwritten by _setup_logging() + +# Set up types for data that is passed around in functions in this script. +# Need to use Dict (not dict) here since these aren't stripped by strip-hints, and doesn't work on Ubuntu <= 20.04. +Arguments = NewType("Arguments", argparse.Namespace) +OSInfo = Dict[str, str] +HostInfo = Dict[str, Optional[str]] +Modules = Dict[str, Dict[str, str]] + + +def parse_args() -> Arguments: + """ + Parse the command line arguments + """ + parser = argparse.ArgumentParser( + description="Setup cosmos-modules.conf", + add_help=True, + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + + parser.add_argument("--debug", dest="debug", action="store_true", default=False, help="Enable debug operation") + parser.add_argument( + "--filename", dest="filename", type=str, default="/etc/puppet/cosmos-modules.conf", help="Filename to write to" + ) + + return cast(Arguments, parser.parse_args()) + + +def get_os_info() -> OSInfo: + """Load info about the current OS (distro, release etc.)""" + os_info: OSInfo = {} + if Path("/etc/os-release").exists(): + os_info.update({k.lower(): v for k, v in _parse_bash_vars("/etc/os-release").items()}) + res = local_os_info_hook(os_info) + logger.debug(f"OS info:\n{json.dumps(res, sort_keys=True, indent=4)}") + return res + + +def get_host_info() -> HostInfo: + """Load info about the current host (hostname, fqdn, domain name etc.)""" + try: + fqdn = socket.getfqdn() + hostname = socket.gethostname() + except OSError: + host_info = {} + else: + _domainname = fqdn[len(hostname + ".") :] + + host_info: HostInfo = { + "domainname": _domainname, + "fqdn": fqdn, + "hostname": hostname, + } + res = local_host_info_hook(host_info) + logger.debug(f"Host info: {json.dumps(res, sort_keys=True, indent=4)}") + return res + + +def _parse_bash_vars(path: str) -> dict[str, str]: + """ + Parses a bash script and returns a dictionary representing the + variables declared in that script. + + Source: https://dev.to/htv2012/how-to-parse-bash-variables-b4f + + :param path: The path to the bash script + :return: Variables as a dictionary + """ + with open(path) as stream: + contents = stream.read().strip() + + var_declarations = re.findall(r"^[a-zA-Z0-9_]+=.*$", contents, flags=re.MULTILINE) + reader = csv.reader(var_declarations, delimiter="=") + bash_vars = dict(reader) + return bash_vars + + +def get_modules(os_info: OSInfo, host_info: HostInfo) -> Modules: + """Load the list of default modules. + + This is more or less an inventory of all the modules we have. If you don't want + to use all modules in your OPS repo, you can filter them in the local hook. + + If you want to use a different tag for a module on a specific host/os, you can + do that in the local hook as well. + """ + default_modules = """ + # name repo upgrade tag + apparmor https://github.com/SUNET/puppet-apparmor.git yes sunet-2* + apt https://github.com/SUNET/puppetlabs-apt.git yes sunet-2* + augeas https://github.com/SUNET/puppet-augeas.git yes sunet-2* + bastion https://github.com/SUNET/puppet-bastion.git yes sunet-2* + concat https://github.com/SUNET/puppetlabs-concat.git yes sunet-2* + cosmos https://github.com/SUNET/puppet-cosmos.git yes sunet-2* + dhcp https://github.com/SUNET/puppetlabs-dhcp.git yes sunet_dev-2* + docker https://github.com/SUNET/garethr-docker.git yes sunet-2* + hiera-gpg https://github.com/SUNET/hiera-gpg.git yes sunet-2* + munin https://github.com/SUNET/ssm-munin.git yes sunet-2* + nagioscfg https://github.com/SUNET/puppet-nagioscfg.git yes sunet-2* + network https://github.com/SUNET/attachmentgenie-network.git yes sunet-2* + pound https://github.com/SUNET/puppet-pound.git yes sunet-2* + pyff https://github.com/samlbits/puppet-pyff.git yes puppet-pyff-* + python https://github.com/SUNET/puppet-python.git yes sunet-2* + stdlib https://github.com/SUNET/puppetlabs-stdlib.git yes sunet-2* + sunet https://github.com/SUNET/puppet-sunet.git yes sunet-2* + sysctl https://github.com/SUNET/puppet-sysctl.git yes sunet-2* + ufw https://github.com/SUNET/puppet-module-ufw.git yes sunet-2* + varnish https://github.com/samlbits/puppet-varnish.git yes puppet-varnish-* + vcsrepo https://github.com/SUNET/puppetlabs-vcsrepo.git yes sunet-2* + xinetd https://github.com/SUNET/puppetlabs-xinetd.git yes sunet-2* + """ + modules: Modules = {} + for line in default_modules.splitlines(): + try: + if not line.strip() or line.strip().startswith("#"): + continue + _name, _url, _upgrade, _tag = line.split() + modules[_name] = { + "repo": _url, + "upgrade": _upgrade, + "tag": _tag, + } + except ValueError: + logger.error(f"Failed to parse line: {repr(line)}") + raise + + # Remove the UFW module on Ubuntu >= 22.04 (nftables is used there instead) + if os_info.get("name") == "Ubuntu": + ver = os_info.get("version_id") + if ver: + if parse_version(ver) >= parse_version("22.04"): + logger.debug("Removing UFW module for Ubuntu >= 22.04") + del modules["ufw"] + else: + logger.debug("Keeping UFW module for Ubuntu < 22.04") + else: + logger.debug("Unknown Ubuntu module version, keeping UFW module") + + return local_get_modules_hook(os_info, host_info, modules) + + +def local_os_info_hook(os_info: OSInfo) -> OSInfo: + """Local hook to modify os_info in an OPS repo.""" + # Start local changes in this repository + # End local changes + return os_info + + +def local_host_info_hook(host_info: HostInfo) -> HostInfo: + """Local hook to modify host_info in an OPS repo.""" + # Start local changes in this repository + + # Regular expression to tease apart an eduID hostname + hostname_re = re.compile( + r"""^ + (\w+) # function ('idp', 'apps', ...) + - + (\w+) # site ('tug', 'sthb', ...) + - + (\d+) # 1 for staging, 3 for production + """, + re.VERBOSE, + ) + _hostname = host_info.get("hostname") + if _hostname: + m = hostname_re.match(_hostname) + if m: + _function, _site, _num = m.groups() + host_info["function"] = _function + host_info["site"] = _site + if _num == "1": + host_info["environment"] = "staging" + + # End local changes + return host_info + + +def local_get_modules_hook(os_info: OSInfo, host_info: HostInfo, modules: Modules) -> Modules: + """Local hook to modify default set of modules in an OPS repo.""" + # Start local changes in this repository + + _eduid_modules = { + "apparmor", + "apt", + "augeas", + "bastion", + "concat", + "docker", + "munin", + "stdlib", + "sunet", + "ufw", + } + # Only keep the modules eduID actually uses + modules = {k: v for k, v in modules.items() if k in _eduid_modules} + logger.debug(f"Adding modules: {json.dumps(modules, sort_keys=True, indent=4)}") + + # Use eduID tag for puppet-sunet + modules["sunet"]["tag"] = "eduid-stable-2*" + if host_info.get("environment") == "staging": + modules["sunet"]["tag"] = "eduid_dev-2*" + + # use sunet_dev-2* for some modules in staging + for dev_module in ["munin"]: + if host_info.get("environment") == "staging" and dev_module in modules: + modules[dev_module]["tag"] = "sunet_dev-2*" + + # End local changes + return modules + + +def update_cosmos_modules(filename: str, modules: Modules) -> None: + """Create/update the cosmos-modules.conf file. + + First, we check if the file already have the right content. If so, we do nothing. + """ + content = "# This file is automatically generated by the setup_cosmos_modules script.\n# Do not edit it manually.\n" + for k, v in sorted(modules.items()): + content += f"{k:15} {v['repo']:55} {v['upgrade']:5} {v['tag']}\n" + _file = Path(filename) + if _file.exists(): + # Check if the content is already correct, and avoid updating the file if so (so that the timestamp + # of the file at least indicates when the content was last updated) + with _file.open("r") as f: + current = f.read() + if current == content: + logger.debug(f"{filename} is up to date") + return + + # Create/update the file by writing the content to a temporary file and then renaming it + _tmp_file = _file.with_suffix(".tmp") + with _tmp_file.open("w") as f: + f.write(content) + _tmp_file.rename(_file) + logger.debug(f"Updated {filename}") + + +def _setup_logging(my_name: str, args: Arguments): + level = logging.INFO + if args.debug: + level = logging.DEBUG + logging.basicConfig(level=level, stream=sys.stderr, format="{asctime} | {levelname:7} | {message}", style="{") + global logger + logger = logging.getLogger(my_name) + # If stderr is not a TTY, change the log level of the StreamHandler (stream = sys.stderr above) to ERROR + if not sys.stderr.isatty() and not args.debug: + for this_h in logging.getLogger("").handlers: + this_h.setLevel(logging.ERROR) + if args.debug: + logger.setLevel(logging.DEBUG) + + +def main(my_name: str, args: Arguments) -> bool: + _setup_logging(my_name, args) + + os_info = get_os_info() + host_info = get_host_info() + modules = get_modules(os_info, host_info) + + update_cosmos_modules(args.filename, modules) + + return True + + +if __name__ == "__main__": + my_name = os.path.basename(sys.argv[0]) + args = parse_args() + res = main(my_name, args=args) + if res: + sys.exit(0) + sys.exit(1) From 4c877bc6ea86fe80b6e438de01fb479feedc5b97 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Fri, 3 Feb 2023 10:58:25 +0100 Subject: [PATCH 073/111] Syntax error --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7ad799ef..fac9f2b0 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ upgrade: db: global/overlay/etc/puppet/cosmos-db.yaml -global/overlay/etc/puppet/cosmos-db.yaml: global/overlay/etc/puppet/cosmos-rules.yaml: +global/overlay/etc/puppet/cosmos-db.yaml: global/overlay/etc/puppet/cosmos-rules.yaml @python ./fabfile/db.py > global/overlay/etc/puppet/cosmos-db.yaml @git add global/overlay/etc/puppet/cosmos-db.yaml && git commit -m "update db" global/overlay/etc/puppet/cosmos-db.yaml From 948cc803891580047d3cf73e252fe95ce448f0d8 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Fri, 3 Feb 2023 11:24:55 +0100 Subject: [PATCH 074/111] Update cosmos-puppet-ops.mkd --- docs/cosmos-puppet-ops.mkd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cosmos-puppet-ops.mkd b/docs/cosmos-puppet-ops.mkd index 1d121b89..fc7fa9f2 100644 --- a/docs/cosmos-puppet-ops.mkd +++ b/docs/cosmos-puppet-ops.mkd @@ -222,7 +222,7 @@ you'll try to push to the multiverse remote! Finally create a branch for the 'multiverse' upstream so you can merge changes to multiverse: ``` -# git checkout -b multiverse --track multiverse/master +# git checkout -b multiverse --track multiverse/main ``` Note that you can maintain your repo on just about any git hosting platform, including From e08346aa3018fcd50a650b48cafd2c4a1e834659 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Fri, 3 Feb 2023 15:39:49 +0100 Subject: [PATCH 075/111] cleanup, use stamp-file, only run on old OS versions --- global/pre-tasks.d/040hiera-gpg | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/global/pre-tasks.d/040hiera-gpg b/global/pre-tasks.d/040hiera-gpg index 3aa30376..bc1da35f 100755 --- a/global/pre-tasks.d/040hiera-gpg +++ b/global/pre-tasks.d/040hiera-gpg @@ -9,12 +9,21 @@ set -e GNUPGHOME=/etc/hiera/gpg export GNUPGHOME +vendor=$(lsb_release -is) +version=$(lsb_release -rs) +# If the OS is Ubuntu 18.04 or newer, or Debian 10 or newer, we don't need to do anything (those use eyaml instead) +test "${vendor}" = "Ubuntu" && dpkg --compare-versions "${version}" "ge" "18.04" && exit 0 +test "${vendor}" = "Debian" && dpkg --compare-versions "${version}" "ge" "10" && exit 0 + +stamp="$COSMOS_BASE/stamps/hiera-gpg-v01.stamp" + +test -f "$stamp" && exit 0 + if [ ! -f /usr/lib/ruby/vendor_ruby/gpgme.rb ]; then apt-get update apt-get -y install ruby-gpgme fi - if [ ! -s $GNUPGHOME/secring.gpg ]; then if [ "x$1" != "x--force" ]; then @@ -35,19 +44,21 @@ if [ ! -s $GNUPGHOME/secring.gpg ]; then chmod 700 $GNUPGHOME TMPFILE=$(mktemp /tmp/hiera-gpg.XXXXXX) - cat > $TMPFILE < "$TMPFILE" < Date: Fri, 3 Feb 2023 15:40:15 +0100 Subject: [PATCH 076/111] install eyaml on Ubuntu from 18.04 and Debian from version 10 --- global/pre-tasks.d/040hiera-eyaml | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100755 global/pre-tasks.d/040hiera-eyaml diff --git a/global/pre-tasks.d/040hiera-eyaml b/global/pre-tasks.d/040hiera-eyaml new file mode 100755 index 00000000..1f2758d4 --- /dev/null +++ b/global/pre-tasks.d/040hiera-eyaml @@ -0,0 +1,36 @@ +#!/bin/sh +# +# Set up eyaml for Hiera +# + +set -e + +EYAMLDIR=/etc/hiera/eyaml + +vendor=$(lsb_release -is) +version=$(lsb_release -rs) +# eyaml is only used on Ubuntu 20.04 and newer, and Debian 11 and newer (earlier OSes use hiera-gpg instead) +test "${vendor}" = "Ubuntu" && dpkg --compare-versions "${version}" "lt" "18.04" && exit 0 +test "${vendor}" = "Debian" && dpkg --compare-versions "${version}" "lt" "10" && exit 0 + +stamp="$COSMOS_BASE/stamps/hiera-eyaml-v01.stamp" + +test -f "$stamp" && exit 0 + +if [ ! -f /usr/bin/eyaml ] || [ ! -d /usr/share/doc/yaml-mode ]; then + apt-get update + apt-get -y install hiera-eyaml yaml-mode +fi + +if [ ! -f ${EYAMLDIR}/public_certkey.pkcs7.pem ] || [ ! -f ${EYAMLDIR}/private_key.pkcs7.pem ]; then + # hiera-eyaml wants a certificate and public key, not just a public key oddly enough + echo "$0: Generating eyaml key in ${EYAMLDIR} - this might take a while..." + mkdir -p /etc/hiera/eyaml + openssl req -x509 -newkey rsa:4096 -keyout ${EYAMLDIR}/private_key.pkcs7.pem \ + -out ${EYAMLDIR}/public_certkey.pkcs7.pem -days 3653 -nodes -sha256 \ + -subj "/C=SE/O=SUNET/OU=EYAML/CN=$(hostname)" + rm -f ${EYAMLDIR}/public_key.pkcs7.pem # cleanup +fi + +mkdir -p "$(dirname "${stamp}")" +touch "$stamp" From 25463e6013a2d387e48916b496a860cfe7d56ae1 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Fri, 3 Feb 2023 16:04:51 +0100 Subject: [PATCH 077/111] respect COSMOS_VERBOSE --- global/pre-tasks.d/015set-overlay-permissions | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/global/pre-tasks.d/015set-overlay-permissions b/global/pre-tasks.d/015set-overlay-permissions index 373ef68f..37f98441 100755 --- a/global/pre-tasks.d/015set-overlay-permissions +++ b/global/pre-tasks.d/015set-overlay-permissions @@ -15,5 +15,9 @@ if ! test -d "$MODEL_OVERLAY"; then fi if [ -d "$MODEL_OVERLAY/root" ]; then - chmod -v 0700 "$MODEL_OVERLAY"/root + args="" + if [ "x$COSMOS_VERBOSE" = "xy" ]; then + args="-v" + fi + chmod ${args} 0700 "$MODEL_OVERLAY"/root fi From 708c6c1b64faa7e175133bc9d96dc2d082708477 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Fri, 3 Feb 2023 16:05:09 +0100 Subject: [PATCH 078/111] add set -e, and do some shellcheck cleanup --- global/post-tasks.d/030puppet | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/global/post-tasks.d/030puppet b/global/post-tasks.d/030puppet index af450057..561ebc4b 100755 --- a/global/post-tasks.d/030puppet +++ b/global/post-tasks.d/030puppet @@ -1,13 +1,15 @@ #!/bin/sh +set -e + if [ "x$COSMOS_VERBOSE" = "xy" ]; then args="--verbose --show_diff" else args="--logdest=syslog" fi -if [ -f /usr/bin/puppet -a -d /etc/puppet/manifests ]; then - for m in `find /etc/puppet/manifests -name \*.pp`; do +if [ -f /usr/bin/puppet ] && [ -d /etc/puppet/manifests ]; then + find /etc/puppet/manifests -name \*.pp | while read -r m; do test "x$COSMOS_VERBOSE" = "xy" && echo "$0: Applying Puppet manifest $m" puppet apply $args $m done From 3988f5beb000cb48bc90e775ad5bc6afed60644f Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Mon, 6 Feb 2023 16:41:04 +0100 Subject: [PATCH 079/111] shellcheck fixes --- global/overlay/usr/local/bin/run-cosmos | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/global/overlay/usr/local/bin/run-cosmos b/global/overlay/usr/local/bin/run-cosmos index 5f2cbc1e..fdfb85d3 100755 --- a/global/overlay/usr/local/bin/run-cosmos +++ b/global/overlay/usr/local/bin/run-cosmos @@ -16,29 +16,29 @@ lock() { eval "exec $fd>$lock_file" # acquier the lock - flock -n $fd \ + flock -n "$fd" \ && return 0 \ || return 1 } eexit() { - local error_str="$@" + local error_str="$*" - echo $error_str + echo "$error_str" exit 1 } main () { - lock $PROGNAME || eexit "Only one instance of $PROGNAME can run at one time." - cosmos $* update - cosmos $* apply + lock "$PROGNAME" || eexit "Only one instance of $PROGNAME can run at one time." + cosmos "$@" update + cosmos "$@" apply touch /var/run/last-cosmos-ok.stamp - find /var/lib/puppet/reports/ -type f -mtime +10 | xargs rm -f + find /var/lib/puppet/reports/ -type f -mtime +10 -print0 | xargs -0 rm -f } -main $* +main "$@" if [ -f /cosmos-reboot ]; then rm -f /cosmos-reboot From 79606f2a6d1919d30902769b58dd61c43b31a023 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Mon, 6 Feb 2023 16:45:53 +0100 Subject: [PATCH 080/111] check for /etc/no-automatic-cosmos in the wrapper, and allow arguments to be passed --- global/overlay/etc/cron.d/cosmos | 2 +- global/overlay/usr/local/libexec/cosmos-cron-wrapper | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/global/overlay/etc/cron.d/cosmos b/global/overlay/etc/cron.d/cosmos index 38d14f58..e7abc17a 100644 --- a/global/overlay/etc/cron.d/cosmos +++ b/global/overlay/etc/cron.d/cosmos @@ -1,4 +1,4 @@ SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin -*/15 * * * * root test -f /etc/no-automatic-cosmos || /usr/local/libexec/cosmos-cron-wrapper +*/15 * * * * root /usr/local/libexec/cosmos-cron-wrapper diff --git a/global/overlay/usr/local/libexec/cosmos-cron-wrapper b/global/overlay/usr/local/libexec/cosmos-cron-wrapper index 2df85b50..ae668108 100755 --- a/global/overlay/usr/local/libexec/cosmos-cron-wrapper +++ b/global/overlay/usr/local/libexec/cosmos-cron-wrapper @@ -1,10 +1,12 @@ #!/usr/bin/env bash -RUN_COSMOS=/usr/local/bin/run-cosmos +test -f /etc/no-automatic-cosmos && exit 0 + +RUN_COSMOS='/usr/local/bin/run-cosmos' SCRIPTHERDER_CMD='' -if [ -f /usr/local/bin/scriptherder ]; then +if [ -x /usr/local/bin/scriptherder ]; then SCRIPTHERDER_CMD='/usr/local/bin/scriptherder --mode wrap --syslog --name cosmos --' fi -${SCRIPTHERDER_CMD} ${RUN_COSMOS} +exec ${SCRIPTHERDER_CMD} ${RUN_COSMOS} "$@" From 12b2412ea78cc5b8302a0be5608d8f10a972f917 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Mon, 6 Feb 2023 17:12:01 +0100 Subject: [PATCH 081/111] run cron at boot too, to e.g. get new firewall rules installed --- global/overlay/etc/cron.d/cosmos | 2 ++ 1 file changed, 2 insertions(+) diff --git a/global/overlay/etc/cron.d/cosmos b/global/overlay/etc/cron.d/cosmos index e7abc17a..3840f8c4 100644 --- a/global/overlay/etc/cron.d/cosmos +++ b/global/overlay/etc/cron.d/cosmos @@ -2,3 +2,5 @@ SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin */15 * * * * root /usr/local/libexec/cosmos-cron-wrapper + +@reboot root sleep 30; /usr/local/libexec/cosmos-cron-wrapper From cae694d1ceea9a94acda4d595bf5fbeae2d609c6 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Tue, 7 Feb 2023 08:49:31 +0100 Subject: [PATCH 082/111] Make sure of separator We use the separator later on to determine where the yaml document starts. `eyaml edit` adds the separator to new (non-existing) files by itself but since we want to create the file before in order to diff later the separator needs to be added in order to get a valid document. --- edit-secrets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edit-secrets b/edit-secrets index b4d816cd..a2c67ac3 100755 --- a/edit-secrets +++ b/edit-secrets @@ -151,7 +151,7 @@ function edit_file_on_host() { edit_gpg_file ${SECRETFILE} elif [ -f /etc/hiera/eyaml/public_certkey.pkcs7.pem ]; then # default to eyaml if the key exists and none of the secrets-file above exist - touch ${EYAMLFILE} + echo "---" > ${EYAMLFILE} edit_eyaml_file ${EYAMLFILE} fi } From c400bba97d8dae9c422937691ab1c174277fe77d Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 7 Feb 2023 14:21:29 +0100 Subject: [PATCH 083/111] remove 'make db' The db-file, essentially providing reverse lookup of classes to host names, is only used by some Nagios configuration instances and causes continuing operational headaches in those ops-repos. It should be kept/refactored to only apply to the monitoring hosts in the cases where it is used, but we don't want any new ops-repos to use it hence it should be removed from upstream multiverse. --- fabfile/db.py | 49 ------------------------- global/overlay/etc/puppet/cosmos_enc.py | 35 ++++++++++++++---- 2 files changed, 27 insertions(+), 57 deletions(-) delete mode 100644 fabfile/db.py diff --git a/fabfile/db.py b/fabfile/db.py deleted file mode 100644 index 67b6645d..00000000 --- a/fabfile/db.py +++ /dev/null @@ -1,49 +0,0 @@ -import os -import yaml -import re - -def _all_hosts(): - return filter(lambda fn: '.' in fn and not fn.startswith('.') and os.path.isdir(fn),os.listdir(".")) - -def _load_db(): - rules = dict() - rules_file = "cosmos-rules.yaml"; - if os.path.exists(rules_file): - with open(rules_file) as fd: - rules.update(yaml.load(fd)) - - all_hosts = _all_hosts() - - members = dict() - for node_name in all_hosts: - for reg,cls in rules.iteritems(): - if re.match(reg,node_name): - for cls_name in cls.keys(): - h = members.get(cls_name,[]) - h.append(node_name) - members[cls_name] = h - members['all'] = all_hosts - - classes = dict() - for node_name in all_hosts: - node_classes = dict() - for reg,cls in rules.iteritems(): - if re.match(reg,node_name): - node_classes.update(cls) - classes[node_name] = node_classes - - # Sort member lists for a more easy to read diff - for cls in members.keys(): - members[cls].sort() - - return dict(classes=classes,members=members) - -_db = None -def cosmos_db(): - global _db - if _db is None: - _db = _load_db() - return _db - -if __name__ == '__main__': - print yaml.dump(cosmos_db()) diff --git a/global/overlay/etc/puppet/cosmos_enc.py b/global/overlay/etc/puppet/cosmos_enc.py index 852fb25c..dca12d33 100755 --- a/global/overlay/etc/puppet/cosmos_enc.py +++ b/global/overlay/etc/puppet/cosmos_enc.py @@ -1,18 +1,37 @@ #!/usr/bin/env python3 +# +# Puppet 'External Node Classifier' to tell puppet what classes to apply to this node. +# +# Docs: https://puppet.com/docs/puppet/5.3/nodes_external.html +# -import sys -import yaml import os import re +import sys + +import yaml + +rules_path = os.environ.get("COSMOS_RULES_PATH", "/etc/puppet") node_name = sys.argv[1] -db_file = os.environ.get("COSMOS_ENC_DB","/etc/puppet/cosmos-db.yaml") -db = dict(classes=dict()) +rules = dict() +for p in rules_path.split(":"): + rules_file = os.path.join(p, "cosmos-rules.yaml") + if os.path.exists(rules_file): + with open(rules_file) as fd: + rules.update(yaml.safe_load(fd)) -if os.path.exists(db_file): - with open(db_file) as fd: - db.update(yaml.load(fd)) +found = False +classes = dict() +for reg, cls in rules.items(): + if re.search(reg, node_name): + classes.update(cls) + found = True -print(yaml.dump(dict(classes=db['classes'].get(node_name,dict()),parameters=dict(roles=db.get('members',[]))))) +if not found: + sys.stderr.write(f"{sys.argv[0]}: {node_name} not found in cosmos-rules.yaml\n") +print("---\n" + yaml.dump(dict(classes=classes))) + +sys.exit(0) From 1bddf21049e8ded369e6319de78adb0ad9b880f5 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 7 Feb 2023 15:04:01 +0100 Subject: [PATCH 084/111] remove 'make db' target as well --- Makefile | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Makefile b/Makefile index fac9f2b0..a284f955 100644 --- a/Makefile +++ b/Makefile @@ -6,13 +6,7 @@ cosmos: upgrade: fab upgrade -db: global/overlay/etc/puppet/cosmos-db.yaml - -global/overlay/etc/puppet/cosmos-db.yaml: global/overlay/etc/puppet/cosmos-rules.yaml - @python ./fabfile/db.py > global/overlay/etc/puppet/cosmos-db.yaml - @git add global/overlay/etc/puppet/cosmos-db.yaml && git commit -m "update db" global/overlay/etc/puppet/cosmos-db.yaml - -tag: db +tag: ./bump-tag test_in_docker: From 252d478e2d309ade7c3bddf63bb3110a56712794 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 7 Feb 2023 16:09:25 +0100 Subject: [PATCH 085/111] cosmos-db.yaml is no more --- host-puppet-conf-test | 1 - 1 file changed, 1 deletion(-) diff --git a/host-puppet-conf-test b/host-puppet-conf-test index e72008c7..0844d086 100755 --- a/host-puppet-conf-test +++ b/host-puppet-conf-test @@ -24,7 +24,6 @@ then echo "Copying files to host..." rsync -av --exclude '*~' global/overlay/etc/puppet/cosmos-rules.yaml root@$HOSTNAME:/etc/puppet/cosmos-rules.yaml rsync -av --exclude '*~' global/overlay/etc/puppet/manifests/cosmos-site.pp root@$HOSTNAME:/etc/puppet/manifests/cosmos-site.pp - rsync -av --exclude '*~' global/overlay/etc/puppet/cosmos-db.yaml root@$HOSTNAME:/etc/puppet/cosmos-db.yaml rsync -av --exclude '*~' global/overlay/etc/hiera/data/common.yaml root@$HOSTNAME:/etc/hiera/data/common.yaml # Test if the user has symlinked puppet-sunet correctly From 496b9f4b31d02d101f7e5cf3bcee603ea199d02e Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 7 Feb 2023 16:09:37 +0100 Subject: [PATCH 086/111] shellcheck fixes --- host-puppet-conf-test | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/host-puppet-conf-test b/host-puppet-conf-test index 0844d086..2ddcbe99 100755 --- a/host-puppet-conf-test +++ b/host-puppet-conf-test @@ -17,14 +17,14 @@ PUPPET_ARGS=${PUPPET_ARGS-"--verbose"} # Check if cosmos or puppet is already running on host echo "Checking if puppet or cosmos is already running..." -ssh root@$HOSTNAME ps aux | egrep -v "grep|edit-secrets|gpg-agent" | egrep -q "cosmos|puppet" +ssh root@"$HOSTNAME" ps aux | grep -Ev "grep|edit-secrets|gpg-agent" | grep -Eq "cosmos|puppet" if [ $? -eq 1 ] then echo "Copying files to host..." - rsync -av --exclude '*~' global/overlay/etc/puppet/cosmos-rules.yaml root@$HOSTNAME:/etc/puppet/cosmos-rules.yaml - rsync -av --exclude '*~' global/overlay/etc/puppet/manifests/cosmos-site.pp root@$HOSTNAME:/etc/puppet/manifests/cosmos-site.pp - rsync -av --exclude '*~' global/overlay/etc/hiera/data/common.yaml root@$HOSTNAME:/etc/hiera/data/common.yaml + rsync -av --exclude '*~' global/overlay/etc/puppet/cosmos-rules.yaml root@"$HOSTNAME":/etc/puppet/cosmos-rules.yaml + rsync -av --exclude '*~' global/overlay/etc/puppet/manifests/cosmos-site.pp root@"$HOSTNAME":/etc/puppet/manifests/cosmos-site.pp + rsync -av --exclude '*~' global/overlay/etc/hiera/data/common.yaml root@"$HOSTNAME":/etc/hiera/data/common.yaml # Test if the user has symlinked puppet-sunet correctly # by first checking if the link exits and then whether @@ -36,7 +36,7 @@ then fi echo "Running puppet apply..." - ssh root@$HOSTNAME /usr/bin/puppet apply $PUPPET_ARGS /etc/puppet/manifests/cosmos-site.pp + ssh root@"$HOSTNAME" /usr/bin/puppet apply $PUPPET_ARGS /etc/puppet/manifests/cosmos-site.pp else echo "Cosmos or puppet already running. Exiting." exit 1 From 5af80933389b713c2ec76425760602509a5cab64 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Thu, 16 Feb 2023 07:44:00 +0100 Subject: [PATCH 087/111] Add support for eyaml in Hiera And at the same time remove support for gpg. The modern version of the configuration (v5) has been tested with 20.04 but might work with older dists. --- global/overlay/etc/puppet/hiera.yaml | 36 ++++++++++++++++------------ 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/global/overlay/etc/puppet/hiera.yaml b/global/overlay/etc/puppet/hiera.yaml index 3663305b..3de986b9 100644 --- a/global/overlay/etc/puppet/hiera.yaml +++ b/global/overlay/etc/puppet/hiera.yaml @@ -1,21 +1,27 @@ +# Hiera version 5 configuration +# --- -:backends: - - yaml - - gpg +version: 5 +defaults: + datadir: /etc/hiera/data + data_hash: yaml_data -:logger: console +hierarchy: + - name: "Per-node data" + path: "local.yaml" -:hierarchy: - - "%{env}/%{location}/%{calling_module}" - - "%{env}/%{calling_module}" - - local - - secrets.yaml - - common + - name: "Per-group data" + path: "group.yaml" + - name: "Per-host secrets" + path: "local.eyaml" + lookup_key: eyaml_lookup_key + options: + pkcs7_private_key: /etc/hiera/eyaml/private_key.pkcs7.pem + pkcs7_public_key: /etc/hiera/eyaml/public_certkey.pkcs7.pem -:yaml: - :datadir: /etc/hiera/data + - name: "Overrides per distribution" + path: "dist_%{::lsbdistcodename}_override.yaml" -:gpg: - :datadir: /etc/hiera/data - :key_dir: /etc/hiera/gpg + - name: "Data common to whole environment" + path: "common.yaml" \ No newline at end of file From 0f1c5ec93ff3df4ef8f072478a78b7959da500f5 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Wed, 15 Mar 2023 13:08:24 +0100 Subject: [PATCH 088/111] Don't throw away v6 route when IP forwarding In environments where we relay on RAs for IPv6 (e.g Safespring) we need to forcely allow RAs even if IP forwarding is enabled by some service(s). E.g docker: https://github.com/SUNET/puppet-sunet/blob/2dc4de00de1d2404d5dffaf17d18723e2b369cd0/templates/dockerhost/systemd_dropin_nftables_ns.conf.erb#L46 --- iaas-setup.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/iaas-setup.sh b/iaas-setup.sh index 4ce578ba..a236b698 100755 --- a/iaas-setup.sh +++ b/iaas-setup.sh @@ -75,6 +75,29 @@ if grep -q '^# en_US.UTF-8 UTF-8$' $locale_gen_file; then locale-gen fi +if [ "$(lsb_release -is)" == "Debian" ]; then + interfaces_file='/etc/network/interfaces.d/50-cloud-init' + + if [ -f "${interfaces_file}" ]; then + interface_string='iface ens3 inet6 dhcp' + accept_ra_string=' accept_ra 2' + + if ! grep -qPz "${interface_string}\n${accept_ra_string}" ${interfaces_file} ; then + + # By default net.ipv6.conf.ens3.accept_ra is set to 1 which + # makes the kernel throw a way the IPv6 route when + # net.ipv6.conf.all.forwarding is set to 1 by our service for + # Docker. + echo "Configuring interfaces to always accept Router Advertisements even with IP Forwarding enabled" + sed -i -r "s/(${interface_string})/\1\n${accept_ra_string}/" ${interfaces_file} + else + echo "WARN: Configuration already applied or no match for \"${interface_string}\" in ${interfaces_file}" + fi + else + echo "WARN: ${interfaces_file} not found. File renamed in this image?" + fi +fi + DEBIAN_FRONTEND="noninteractive" apt-get -y update DEBIAN_FRONTEND="noninteractive" apt-get -o Dpkg::Options::="--force-confnew" --fix-broken --assume-yes dist-upgrade reboot From cf2e6b6518cb18ce1ebb8bfcbfd7945ffada873c Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Tue, 4 Apr 2023 15:21:15 +0200 Subject: [PATCH 089/111] File provided by Sunet::Dockerhost --- global/overlay/etc/logrotate.d/docker-containers | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 global/overlay/etc/logrotate.d/docker-containers diff --git a/global/overlay/etc/logrotate.d/docker-containers b/global/overlay/etc/logrotate.d/docker-containers deleted file mode 100644 index e9c90b8c..00000000 --- a/global/overlay/etc/logrotate.d/docker-containers +++ /dev/null @@ -1,7 +0,0 @@ -/var/lib/docker/containers/*/*.log { - rotate 7 - daily - compress - delaycompress - copytruncate -} From 3fd4791273f552bdbf9e0c9956e022a902aae1a6 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Tue, 25 Apr 2023 17:19:18 +0200 Subject: [PATCH 090/111] Make bump-tag branch agnostic --- bump-tag | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bump-tag b/bump-tag index 440809ba..4516f38e 100755 --- a/bump-tag +++ b/bump-tag @@ -24,7 +24,8 @@ git tag -v $last_tag > /dev/null 2>&1 echo "" echo "Differences between tag $last_tag and what you are about to sign:" -PAGER=cat git diff --color $last_tag..master +this_branch=$(git rev-parse --abbrev-ref HEAD) +PAGER=cat git diff --color $last_tag..$this_branch iter=1 ok= From 876e72e2ae93d4983e25e9edca96dded5f4408c4 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Tue, 25 Apr 2023 17:31:18 +0200 Subject: [PATCH 091/111] Make shfmt happy --- bump-tag | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/bump-tag b/bump-tag index 4516f38e..31bb72dd 100755 --- a/bump-tag +++ b/bump-tag @@ -8,50 +8,53 @@ echo "Fetching any updates from server:" git pull echo "" -if [ "x$1" = "x" ]; then - deftag=`basename $PWD` +if [[ -z $1 ]]; then + deftag=$(basename "$PWD") else - deftag="$1" + deftag="$1" fi -tagpfx=${tag:="$deftag"} +tagpfx=${tag:="${deftag}"} -last_tag=`git tag -l "${tagpfx}-*"|sort|tail -1` +last_tag=$(git tag -l "${tagpfx}-*" | sort | tail -1) -echo "Verifying last tag $last_tag:" -(git tag -v $last_tag | grep ^gpg:) || true +echo "Verifying last tag ${last_tag}:" +(git tag -v "${last_tag}" | grep ^gpg:) || true # again to not mask exit status of git with grep -git tag -v $last_tag > /dev/null 2>&1 +git tag -v "${last_tag}" >/dev/null 2>&1 echo "" -echo "Differences between tag $last_tag and what you are about to sign:" +echo "Differences between tag ${last_tag} and what you are about to sign:" this_branch=$(git rev-parse --abbrev-ref HEAD) -PAGER=cat git diff --color $last_tag..$this_branch +env PAGER=cat git diff --color "${last_tag}..${this_branch}" iter=1 ok= while test -z "$ok"; do - this_tag=$(date +${tagpfx}-%Y-%m-%d-v`printf "%02d" $iter`) - iter=`expr $iter + 1` - case `(echo $this_tag; echo $last_tag) | sort | tail -1` in - $last_tag) - ;; - $this_tag) - ok=yes - ;; - esac + this_tag=$(date "+${tagpfx}-%Y-%m-%d-v$(printf "%02d" $iter)") + iter=$((iter + 1)) + case $( ( + echo "${this_tag}" + echo "${last_tag}" + ) | sort | tail -1) in + "${last_tag}") ;; + + "${this_tag}") + ok=yes + ;; + esac done -if [ "$deftag" != "$tagpfx" ]; then - echo -e "Using new tag \e[94m$this_tag\e[0m according to pattern in cosmos.conf" +if [[ "${deftag}" != "${tagpfx}" ]]; then + echo -e "Using new tag \e[94m${this_tag}\e[0m according to pattern in cosmos.conf" else - echo -e "Using new tag \e[94m$this_tag\e[0m" + echo -e "Using new tag \e[94m${this_tag}\e[0m" fi echo -e "\e[1mONLY SIGN IF YOU APPROVE OF VERIFICATION AND DIFF ABOVE\e[0m" # GITTAGEXTRA is for putting things like "-u 2117364A" -git tag $GITTAGEXTRA -m bump. -s $this_tag +git tag "${GITTAGEXTRA}" -m bump. -s "${this_tag}" git push git push --tags From 397f0595f75406241ea0fc65438418c031e23e55 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Mon, 15 May 2023 14:29:05 +0200 Subject: [PATCH 092/111] If the variable GITTAGEXTRA is double quoted we get issues. Disable shellcheck for this instance --- bump-tag | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bump-tag b/bump-tag index 31bb72dd..a6ccec74 100755 --- a/bump-tag +++ b/bump-tag @@ -53,8 +53,8 @@ fi echo -e "\e[1mONLY SIGN IF YOU APPROVE OF VERIFICATION AND DIFF ABOVE\e[0m" # GITTAGEXTRA is for putting things like "-u 2117364A" - -git tag "${GITTAGEXTRA}" -m bump. -s "${this_tag}" +# shellcheck disable=SC2086 +git tag ${GITTAGEXTRA} -m bump. -s "${this_tag}" git push git push --tags From 7baf9affb1145123d18e5833d6dbf0fc2fd22c7e Mon Sep 17 00:00:00 2001 From: Patrik Lundin Date: Fri, 16 Jun 2023 11:30:54 +0200 Subject: [PATCH 093/111] Add fleetlock support to run-cosmos Makes run-cosmos request a fleetlock lock before running cosmos "update" and "apply" steps. This is helpful for making sure only one (or several) machine out of some set of machines runs cosmos changes at a time. This way if cosmos (or puppet) decides that a service needs to be restarted this will only happen on a subset of machines at a time. When the cosmos "apply" is done a fleetlock unlock request will be performed so the other machines can progress. The unlock code in run-cosmos will also run the new tool sunet-machine-healthy to decide things are good before unlocking. This way if a restarted service breaks this will stop the unlock attempt and in turn make it so the others should not break their service as well, giving an operator time to figure out what is wrong. --- global/overlay/usr/local/bin/run-cosmos | 46 ++++ global/overlay/usr/local/bin/sunet-fleetlock | 240 ++++++++++++++++++ .../usr/local/bin/sunet-machine-healthy | 103 ++++++++ 3 files changed, 389 insertions(+) create mode 100755 global/overlay/usr/local/bin/sunet-fleetlock create mode 100755 global/overlay/usr/local/bin/sunet-machine-healthy diff --git a/global/overlay/usr/local/bin/run-cosmos b/global/overlay/usr/local/bin/run-cosmos index fdfb85d3..7da725e6 100755 --- a/global/overlay/usr/local/bin/run-cosmos +++ b/global/overlay/usr/local/bin/run-cosmos @@ -6,6 +6,11 @@ readonly PROGNAME=$(basename "$0") readonly LOCKFILE_DIR=/tmp readonly LOCK_FD=200 +readonly FLEETLOCK_CONFIG=/etc/run-cosmos-fleetlock-conf +readonly FLEETLOCK_DISABLE_FILE=/etc/run-cosmos-fleetlock-disable +readonly FLEETLOCK_TOOL=/usr/local/bin/sunet-fleetlock +readonly HEALTHCHECK_TOOL=/usr/local/bin/sunet-machine-healthy +readonly HEALTHCHECK_DISABLE_FILE=/etc/run-cosmos-healthcheck-disable lock() { local prefix=$1 @@ -28,10 +33,51 @@ eexit() { exit 1 } +fleetlock_lock() { + if [ ! -f $FLEETLOCK_DISABLE_FILE ] && [ -f $FLEETLOCK_CONFIG ] && [ -x $FLEETLOCK_TOOL ]; then + local fleetlock_group="" + # shellcheck source=/dev/null + . $FLEETLOCK_CONFIG || return 1 + if [ -z "$fleetlock_group" ]; then + echo "Unable to set fleetlock_group" + return 1 + fi + echo "Getting fleetlock lock" + $FLEETLOCK_TOOL --lock-group "$fleetlock_group" --lock || return 1 + fi + return 0 +} + +fleetlock_unlock() { + if [ ! -f $FLEETLOCK_DISABLE_FILE ] && [ -f $FLEETLOCK_CONFIG ] && [ -x $FLEETLOCK_TOOL ]; then + local fleetlock_group="" + # shellcheck source=/dev/null + . $FLEETLOCK_CONFIG || return 1 + if [ -z "$fleetlock_group" ]; then + echo "Unable to set fleetlock_group" + return 1 + fi + machine_is_healthy || return 1 + echo "Releasing fleetlock lock" + $FLEETLOCK_TOOL --lock-group "$fleetlock_group" --unlock || return 1 + fi + return 0 +} + +machine_is_healthy() { + if [ ! -f $HEALTHCHECK_DISABLE_FILE ] && [ -x $HEALTHCHECK_TOOL ]; then + echo "Running any health checks" + $HEALTHCHECK_TOOL || return 1 + fi + return 0 +} + main () { lock "$PROGNAME" || eexit "Only one instance of $PROGNAME can run at one time." + fleetlock_lock || eexit "Unable to acquire fleetlock lock." cosmos "$@" update cosmos "$@" apply + fleetlock_unlock || eexit "Unable to release fleetlock lock." touch /var/run/last-cosmos-ok.stamp diff --git a/global/overlay/usr/local/bin/sunet-fleetlock b/global/overlay/usr/local/bin/sunet-fleetlock new file mode 100755 index 00000000..e2ee6d98 --- /dev/null +++ b/global/overlay/usr/local/bin/sunet-fleetlock @@ -0,0 +1,240 @@ +#!/usr/bin/env python3 +# pylint: disable=invalid-name +# pylint: enable=invalid-name +""" Tool for taking and releasing fleetlock locks, used by run-cosmos if fleetlock is configured """ + +# +# You need a config file in "configparser" format with a section for the +# lock group you are using, so if the file describes two lock groups where one +# is called "fl-test1" and the other "fl-test2" then example contents would +# look like this: +# === +# [fl-test1] +# server = https://fleetlock-server1.example.com +# password = mysecret1 +# +# [fl-test2] +# server = https://fleetlock-server2.example.com +# password = mysecret2 +# === +# +# The password needs to match an acl configured for the lock group in the +# knubbis-fleetlock service. +# +# When modifying this code please make sure it is passed through the following +# tools: +# === +# black +# pylint +# mypy --strict +# === + +import platform +import sys +import signal +import time +import argparse +import configparser +import os.path +from typing import Optional, Union +from types import FrameType + +import requests + + +class TimeoutException(Exception): + """Exception raised when we hit tool timeout""" + + +def timeout_handler(signum: int, frame: Optional[FrameType]) -> None: + """This is called if the tool takes too long to run""" + raise TimeoutException(f"{os.path.basename(sys.argv[0])} hit --timeout limit") + + +def do_fleetlock_request( + config: configparser.ConfigParser, args: argparse.Namespace, operation: str +) -> bool: + """Perform fleetlock request based on given operation and return true if it succeeded""" + fleetlock_data = { + "client_params": { + "group": args.lock_group, + "id": args.lock_id, + }, + } + + fleetlock_headers = { + "fleet-lock-protocol": "true", + } + + if operation == "lock": + fleetlock_path = "/v1/pre-reboot" + url = config[args.lock_group]["server"] + fleetlock_path + elif operation == "unlock": + fleetlock_path = "/v1/steady-state" + url = config[args.lock_group]["server"] + fleetlock_path + else: + raise ValueError(f"unsupported operation: {operation}") + + # Log the request-id header from responses so we can track requests in + # the knubbis-fleetlock logs more easily + request_id_key = "request-id" + request_id = None + + # Loop forever: we depend on the SIGALRM timout to raise an error if it + # takes too long + while True: + if args.verbose: + print(f"{operation} POST at url {url}") + + resp = requests.post( + url, + headers=fleetlock_headers, + json=fleetlock_data, + timeout=args.timeout, + auth=("", config[args.lock_group]["password"]), + ) + + if request_id_key in resp.headers: + request_id = resp.headers[request_id_key] + + if resp.status_code == requests.codes.ok: # pylint: disable=no-member + if args.verbose: + print( + f"successful {operation} request for lock ID '{args.lock_id}'", + f"in lock group '{args.lock_group}' ({request_id_key}: {request_id})", + ) + + return True + + # If the request is unauthorized this means we probably either try to + # use a lock group that does not exist, or we are using the wrong + # credentials and in either case we can give up immediately + if resp.status_code == requests.codes.unauthorized: # pylint: disable=no-member + print( + f"{operation} request unauthorized: incorrect lock group name '{args.lock_group}'", + f"or wrong credentials? ({request_id_key}: {request_id})", + ) + return False + + # If the request failed in some other way we expect a JSON formatted + # response message: + print( + f"{operation} request failed:" + + " " + + resp.content.decode("utf-8").rstrip() + + " " + + f"({request_id_key}: {request_id})" + ) + + time.sleep(1) + + +def read_config(args: argparse.Namespace) -> Union[configparser.ConfigParser, None]: + """Read lock group specific settings from config file""" + config = configparser.ConfigParser() + with open(args.config, encoding="utf-8") as config_fileobj: + config.read_file(config_fileobj) + + if args.lock_group not in config: + print(f"missing required config section for lock group '{args.lock_group}'") + return None + + required_settings = { + "server", + "password", + } + + have_required_settings = True + for setting in required_settings: + if setting not in config[args.lock_group]: + print( + f"missing required setting '{setting}' in lock group '{args.lock_group}'" + ) + have_required_settings = False + + if not have_required_settings: + return None + + return config + + +def main() -> None: + """Starting point of the program""" + + # How long to wait per HTTP request to fleetlock service + default_request_timeout = 5 + + # How to long before giving up and exiting the tool with a failure + default_timeout = 60 + + default_config_file = "/etc/sunet-fleetlock/sunet-fleetlock.conf" + parser = argparse.ArgumentParser(description="Take and release fleetlock lock.") + parser.add_argument("--verbose", help="print more information", action="store_true") + parser.add_argument( + "--config", + help=f"the conf file to read (default: {default_config_file})", + default=default_config_file, + ) + parser.add_argument( + "--lock-group", required=True, help="the group to take a lock in" + ) + parser.add_argument( + "--lock-id", + help=f"the lock ID to use in the group (default: {platform.node()})", + default=platform.node(), + ) + parser.add_argument( + "--timeout", + type=int, + help=f"how many seconds before giving up and exiting tool (default: {default_timeout}s)", + default=default_timeout, + ) + parser.add_argument( + "--request_timeout", + type=int, + help=f"individal fleetlock HTTP request timeout (default: {default_request_timeout}s)", + default=default_request_timeout, + ) + action_group = parser.add_mutually_exclusive_group(required=True) + action_group.add_argument("--lock", action="store_true", help="lock a reboot slot") + action_group.add_argument( + "--unlock", action="store_true", help="unlock a reboot slot" + ) + args = parser.parse_args() + + config = read_config(args) + + if config is None: + sys.exit(1) + + # Give up if tool has been running for more than --timeout seconds: + signal.signal(signal.SIGALRM, timeout_handler) + signal.alarm(args.timeout) + + if args.lock: + locked = False + + try: + locked = do_fleetlock_request(config, args, "lock") + except TimeoutException as exc: + print(exc) + + if locked: + sys.exit(0) + + if args.unlock: + unlocked = False + + try: + unlocked = do_fleetlock_request(config, args, "unlock") + except TimeoutException as exc: + print(exc) + + if unlocked: + sys.exit(0) + + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/global/overlay/usr/local/bin/sunet-machine-healthy b/global/overlay/usr/local/bin/sunet-machine-healthy new file mode 100755 index 00000000..b34664cb --- /dev/null +++ b/global/overlay/usr/local/bin/sunet-machine-healthy @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# pylint: disable=invalid-name +# pylint: enable=invalid-name + +""" Run any check tools in a directory to decide if the machine is considered +healthy, called by run-cosmos if fleetlock locking is configured """ + +import pathlib +import os +import os.path +import subprocess +import sys +import signal +import argparse + +from typing import List, Optional +from types import FrameType + + +class TimeoutException(Exception): + """Exception returned when checks takes too long""" + + +def timeout_handler(signum: int, frame: Optional[FrameType]) -> None: + """This is called if the tool takes too long to run""" + raise TimeoutException(f"{os.path.basename(sys.argv[0])} hit --timeout limit") + + +def find_checks(check_dir: str) -> List[pathlib.Path]: + """Find all executable .check files in the given directory""" + check_files = [] + + dirobj = pathlib.Path(check_dir) + + # iterdir() will raise error if the directory does not exist, and in this + # case we will just return an empty list + try: + for entry in dirobj.iterdir(): + if entry.is_file(): + if str(entry).endswith(".check") and os.access(entry, os.X_OK): + check_files.append(entry) + + # run checks in alphabetical order + check_files = sorted(check_files) + except FileNotFoundError: + pass + + return check_files + + +def run_checks(check_files: List[pathlib.Path]) -> bool: + """Run all checks""" + for check_file in check_files: + try: + subprocess.run([str(check_file)], check=True) + except subprocess.CalledProcessError as exc: + print(f"error: {exc}") + return False + + return True + + +def main() -> None: + """Starting point of the program""" + + default_timeout = 60 + default_health_check_dir = "/etc/sunet-machine-healthy/health-checks.d" + + parser = argparse.ArgumentParser( + description="Determine if machine is considered healthy." + ) + parser.add_argument("--verbose", help="print more information", action="store_true") + parser.add_argument( + "--health-check-dir", + help=f"directory to run checks from (default: {default_health_check_dir}", + default=default_health_check_dir, + ) + parser.add_argument( + "--timeout", + type=int, + help=f"seconds before giving up and exiting tool (default: {default_timeout}s)", + default=default_timeout, + ) + args = parser.parse_args() + + checks_ok = False + + # Give up if checks has been running for more than --timeout seconds: + signal.signal(signal.SIGALRM, timeout_handler) + signal.alarm(args.timeout) + + check_files = find_checks(args.health_check_dir) + + checks_ok = run_checks(check_files) + + if checks_ok: + sys.exit(0) + + sys.exit(1) + + +if __name__ == "__main__": + main() From aebaccd5ba7acbaa0d93057e893413ef73f61bc3 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Mon, 3 Jul 2023 15:14:52 +0200 Subject: [PATCH 094/111] Multiverse master has been renamed to main, so updating documentation to reflect that --- docs/cosmos-puppet-ops.mkd | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/cosmos-puppet-ops.mkd b/docs/cosmos-puppet-ops.mkd index fc7fa9f2..afbd9143 100644 --- a/docs/cosmos-puppet-ops.mkd +++ b/docs/cosmos-puppet-ops.mkd @@ -206,25 +206,31 @@ changes for your administrative domain. Also add a read-only version of this rem as 'ro'. The read-only remote is used by multiverse scripts during host bootstrap. ``` -# git remote add origin git@yourhost:myproj-cosmos.git +# git remote add origin git+ssh://git@yourhost:myproj-cosmos.git # git remote add ro https://yourhost/myproj-cosmos.git ``` -Now edit .git/config and rename the 'master' branch to use the new 'origin' remote or +Now edit .git/config and rename the 'main' branch to use the new 'origin' remote or you'll try to push to the multiverse remote! ``` -[branch "master"] +[branch "main"] remote = origin - merge = refs/heads/master + merge = refs/heads/main ``` -Finally create a branch for the 'multiverse' upstream so you can merge changes to multiverse: +Now create a branch for the 'multiverse' upstream so you can merge changes to multiverse: ``` # git checkout -b multiverse --track multiverse/main ``` +Finally, you might need to push you main branch upstream to the new origin +``` +# git checkout main +# git push -u origin main +``` + Note that you can maintain your repo on just about any git hosting platform, including github, gitorious or your own local setup as long as it supports read-only access to your repository. It is important that the remotes called 'origin' and 'ro' refer to your @@ -246,7 +252,7 @@ At this point you should create and sign your first tag: ``` If Git complains during the first run of bump-tag that "Your configuration specifies to -merge with the ref 'master' from the remote, but no such ref was fetched." then you +merge with the ref 'main' from the remote, but no such ref was fetched." then you have run 'git push' to initialize the connection with the remote repository. Make sure that you are using the key whose public key you just added to the repository! You @@ -418,7 +424,7 @@ The multiverse template will continue to evolve and sometimes it may be desirabl ``` # git checkout multiverse # git pull -# git checkout master +# git checkout main # git merge multiverse ``` From 3aac1f97d8e1d199b0e2aedc1413ce230a316ad0 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Mon, 10 Jul 2023 16:32:20 +0200 Subject: [PATCH 095/111] Add additional packages for use with debian 12 This patch will install three packages that is needed for normal operations of puppet using puppet-sunet with multiverse on Debian 12: cron puppet-module-puppetlabs-cron-core puppet-module-camptocamp-augeas --- global/pre-tasks.d/030puppet | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/global/pre-tasks.d/030puppet b/global/pre-tasks.d/030puppet index 1a7f69a0..4cfa3a21 100755 --- a/global/pre-tasks.d/030puppet +++ b/global/pre-tasks.d/030puppet @@ -7,10 +7,17 @@ set -e stamp="$COSMOS_BASE/stamps/puppet-tools-v01.stamp" -if ! test -f $stamp -a -f /usr/bin/puppet; then +if ! test -f "${stamp}" -a -f /usr/bin/puppet; then apt-get update apt-get -y install puppet + . /etc/os-release - mkdir -p `dirname $stamp` - touch $stamp + # Note: in posix shell, string comparison is done with a single = + if [ "${ID}" = "debian" ] && [ "${VERSION_ID}" -ge 12 ]; then + apt-get -y install cron puppet-module-puppetlabs-cron-core puppet-module-camptocamp-augeas + fi + + mkdir -p "$(dirname "${stamp}")" + touch "${stamp}" fi + From 6ac9294dea377245ce6947e053da753a9a3b9ba7 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Wed, 12 Jul 2023 16:29:42 +0200 Subject: [PATCH 096/111] A newer bump-tag --- bump-tag | 73 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/bump-tag b/bump-tag index a6ccec74..0f858660 100755 --- a/bump-tag +++ b/bump-tag @@ -2,59 +2,64 @@ set -e -test -f cosmos.conf && . ./cosmos.conf - echo "Fetching any updates from server:" git pull echo "" -if [[ -z $1 ]]; then - deftag=$(basename "$PWD") +if [[ -f ./cosmos.conf ]]; then + . ./cosmos.conf +fi +if [[ -z ${1} ]]; then + deftag=$(basename "${PWD}") else - deftag="$1" + deftag="${1}" fi tagpfx=${tag:="${deftag}"} last_tag=$(git tag -l "${tagpfx}-*" | sort | tail -1) +if [[ -n ${last_tag} ]]; then + echo "Verifying last tag ${last_tag}:" + (git tag -v "${last_tag}" | grep ^gpg:) || true + # again to not mask exit status of git with grep + git tag -v "${last_tag}" >/dev/null 2>&1 + echo "" -echo "Verifying last tag ${last_tag}:" -(git tag -v "${last_tag}" | grep ^gpg:) || true -# again to not mask exit status of git with grep -git tag -v "${last_tag}" >/dev/null 2>&1 -echo "" + echo "Differences between tag ${last_tag} and what you are about to sign:" + env PAGER=cat git diff --color "${last_tag}..main" -echo "Differences between tag ${last_tag} and what you are about to sign:" -this_branch=$(git rev-parse --abbrev-ref HEAD) -env PAGER=cat git diff --color "${last_tag}..${this_branch}" + iter=1 + ok= + while test -z "$ok"; do + this_tag=$(date "+${tagpfx}-%Y-%m-%d-v$(printf "%02d" ${iter})") + iter=$(( iter + 1)) + case $( ( + echo "${this_tag}" + echo "${last_tag}" + ) | sort | tail -1) in + "${last_tag}") ;; -iter=1 -ok= -while test -z "$ok"; do - this_tag=$(date "+${tagpfx}-%Y-%m-%d-v$(printf "%02d" $iter)") - iter=$((iter + 1)) - case $( ( - echo "${this_tag}" - echo "${last_tag}" - ) | sort | tail -1) in - "${last_tag}") ;; + "${this_tag}") + ok=yes + ;; + esac + done - "${this_tag}") - ok=yes - ;; - esac -done + if [ "${deftag}" != "${tagpfx}" ]; then + echo -e "Using new tag \e[94m${this_tag}\e[0m according to pattern in cosmos.conf" + else + echo -e "Using new tag \e[94m${this_tag}\e[0m" + fi -if [[ "${deftag}" != "${tagpfx}" ]]; then - echo -e "Using new tag \e[94m${this_tag}\e[0m according to pattern in cosmos.conf" + echo -e "\e[1mONLY SIGN IF YOU APPROVE OF VERIFICATION AND DIFF ABOVE\e[0m" else - echo -e "Using new tag \e[94m${this_tag}\e[0m" + echo -e "\e[1mCOULD NOT FIND LAST TAG, ASSUMING NEW TAG\e[0m" + iter=1 + this_tag=$(date "+${tagpfx}-%Y-%m-%d-v$(printf "%02d" ${iter})") fi -echo -e "\e[1mONLY SIGN IF YOU APPROVE OF VERIFICATION AND DIFF ABOVE\e[0m" - # GITTAGEXTRA is for putting things like "-u 2117364A" # shellcheck disable=SC2086 -git tag ${GITTAGEXTRA} -m bump. -s "${this_tag}" +git tag ${GITTAGEXTRA} -s "${this_tag}" -m bump. git push git push --tags From 58a9ca7aa9374f77786a00171d048ae7e155a505 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Mon, 2 Oct 2023 12:39:44 +0200 Subject: [PATCH 097/111] No need of x11 on our servers --- global/pre-tasks.d/040hiera-eyaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/global/pre-tasks.d/040hiera-eyaml b/global/pre-tasks.d/040hiera-eyaml index 1f2758d4..96564138 100755 --- a/global/pre-tasks.d/040hiera-eyaml +++ b/global/pre-tasks.d/040hiera-eyaml @@ -19,6 +19,9 @@ test -f "$stamp" && exit 0 if [ ! -f /usr/bin/eyaml ] || [ ! -d /usr/share/doc/yaml-mode ]; then apt-get update + # If we don't install emacs before yaml-mode the default emacs package + # will be emacs-gtk which brings x11 with friends which we don't need. + apt-get -y install emacs-nox apt-get -y install hiera-eyaml yaml-mode fi From 69377631a8c63d63ce929d2cd0df5a95c249b0a3 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Mon, 16 Oct 2023 09:25:57 +0200 Subject: [PATCH 098/111] Bookwork image runs netplan --- iaas-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iaas-setup.sh b/iaas-setup.sh index a236b698..cc3e914e 100755 --- a/iaas-setup.sh +++ b/iaas-setup.sh @@ -75,7 +75,7 @@ if grep -q '^# en_US.UTF-8 UTF-8$' $locale_gen_file; then locale-gen fi -if [ "$(lsb_release -is)" == "Debian" ]; then +if [ "$(lsb_release -is)" == "Debian" ] && [ "$(lsb_release -cs)" == "bullseye" ]; then interfaces_file='/etc/network/interfaces.d/50-cloud-init' if [ -f "${interfaces_file}" ]; then From 120c4a5a93984e22f0db9469bee0f3284490f520 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Tue, 14 Nov 2023 15:27:45 +0100 Subject: [PATCH 099/111] A few more depends for Bookworm --- global/pre-tasks.d/030puppet | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/global/pre-tasks.d/030puppet b/global/pre-tasks.d/030puppet index 4cfa3a21..5ce09468 100755 --- a/global/pre-tasks.d/030puppet +++ b/global/pre-tasks.d/030puppet @@ -14,7 +14,8 @@ if ! test -f "${stamp}" -a -f /usr/bin/puppet; then # Note: in posix shell, string comparison is done with a single = if [ "${ID}" = "debian" ] && [ "${VERSION_ID}" -ge 12 ]; then - apt-get -y install cron puppet-module-puppetlabs-cron-core puppet-module-camptocamp-augeas + apt-get -y install cron puppet-module-puppetlabs-stdlib puppet-module-puppetlabs-cron-core puppet-module-camptocamp-augeas puppet-module-puppetlabs-concat puppet-module-puppetlabs-apt puppet-module-puppetlabs-vcsrepo + fi mkdir -p "$(dirname "${stamp}")" From a6a67d355f0ede6325320ee656fa18e8bc623f9f Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Tue, 14 Nov 2023 15:28:46 +0100 Subject: [PATCH 100/111] Diffable --- global/pre-tasks.d/030puppet | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/global/pre-tasks.d/030puppet b/global/pre-tasks.d/030puppet index 5ce09468..c431f0a3 100755 --- a/global/pre-tasks.d/030puppet +++ b/global/pre-tasks.d/030puppet @@ -14,7 +14,14 @@ if ! test -f "${stamp}" -a -f /usr/bin/puppet; then # Note: in posix shell, string comparison is done with a single = if [ "${ID}" = "debian" ] && [ "${VERSION_ID}" -ge 12 ]; then - apt-get -y install cron puppet-module-puppetlabs-stdlib puppet-module-puppetlabs-cron-core puppet-module-camptocamp-augeas puppet-module-puppetlabs-concat puppet-module-puppetlabs-apt puppet-module-puppetlabs-vcsrepo + apt-get -y install \ + cron \ + puppet-module-camptocamp-augeas \ + puppet-module-puppetlabs-apt \ + puppet-module-puppetlabs-concat \ + puppet-module-puppetlabs-cron-core \ + puppet-module-puppetlabs-stdlib \ + puppet-module-puppetlabs-vcsrepo fi From 083d6eda834580b8aba4558cf2428ca87c2d232b Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Wed, 15 Nov 2023 12:11:52 +0100 Subject: [PATCH 101/111] bump-tag: Compare against current branch Mariah pointed out that this was lost in: https://github.com/SUNET/multiverse/commit/6ac9294dea377245ce6947e053da753a9a3b9ba7 And should be reinstated --- bump-tag | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bump-tag b/bump-tag index 0f858660..d14dcaa0 100755 --- a/bump-tag +++ b/bump-tag @@ -25,7 +25,8 @@ if [[ -n ${last_tag} ]]; then echo "" echo "Differences between tag ${last_tag} and what you are about to sign:" - env PAGER=cat git diff --color "${last_tag}..main" + this_branch=$(git rev-parse --abbrev-ref HEAD) + env PAGER=cat git diff --color "${last_tag}..${this_branch}" iter=1 ok= From 8a7c85dcf0f7c2f6c7fdb2373cd76e496b3ae614 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Wed, 15 Nov 2023 13:44:41 +0100 Subject: [PATCH 102/111] Added bump-tag from nunoc-ops that has multiple improvements and checks for signed commits, makes sure that important script are not tampered with and much more. --- bump-tag | 292 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 247 insertions(+), 45 deletions(-) diff --git a/bump-tag b/bump-tag index d14dcaa0..e4af1260 100755 --- a/bump-tag +++ b/bump-tag @@ -1,66 +1,268 @@ #!/bin/bash -set -e - -echo "Fetching any updates from server:" -git pull +echo "Fetching updates from $(git remote get-url origin) ..." echo "" +git pull --verify-signatures + +if [[ ${?} -ne 0 ]]; then + echo "WARNING: git pull did not exit successfully." + echo "" + echo "EXITING the script. In order to tag your changes," + echo "investigate and then run bump-tag again." + exit 1 +fi if [[ -f ./cosmos.conf ]]; then - . ./cosmos.conf + # shellcheck disable=SC1091 + source ./cosmos.conf fi -if [[ -z ${1} ]]; then - deftag=$(basename "${PWD}") + +# A tab will be used in multiple commands for git +t=$'\t' + +# Set the default tag according to the repo +# or by entering a name as the first argument. +if [[ -z "${1}" ]]; then + deftag="$(basename "${PWD}")" else - deftag="${1}" + deftag="${1}" fi -tagpfx=${tag:="${deftag}"} -last_tag=$(git tag -l "${tagpfx}-*" | sort | tail -1) -if [[ -n ${last_tag} ]]; then - echo "Verifying last tag ${last_tag}:" - (git tag -v "${last_tag}" | grep ^gpg:) || true - # again to not mask exit status of git with grep - git tag -v "${last_tag}" >/dev/null 2>&1 - echo "" +# Set the tag prefix according to: +# 1. $tag, if specified in cosmos.conf, +# 2. or $deftag, as specified above. +# shellcheck disable=SC2154 +if [[ ! -z "${tag}" ]]; then + tagpfx="${tag}" +else + tagpfx="${deftag}" +fi - echo "Differences between tag ${last_tag} and what you are about to sign:" - this_branch=$(git rev-parse --abbrev-ref HEAD) - env PAGER=cat git diff --color "${last_tag}..${this_branch}" +# Check why the tag couldn't be verified +# First argument: the tag to investigate +check_tag_sig_failure() +{ + local __tag_to_check="${1}" - iter=1 - ok= - while test -z "$ok"; do - this_tag=$(date "+${tagpfx}-%Y-%m-%d-v$(printf "%02d" ${iter})") - iter=$(( iter + 1)) - case $( ( - echo "${this_tag}" - echo "${last_tag}" - ) | sort | tail -1) in - "${last_tag}") ;; + # shellcheck disable=SC2155 + local __verify_tag_output="$(git verify-tag --raw "${__tag_to_check}" 2>&1)" - "${this_tag}") - ok=yes - ;; + if echo "${__verify_tag_output}" | grep -q "VALIDSIG"; then + + if echo "${__verify_tag_output}" | grep -q "EXPKEYSIG"; then + + echo "" + echo "WARNING: The tag was correctly signed, but the copy of" + echo "the key that you have stored on your computer has expired." + echo "Check for an updated key in:" + echo "global/overlay/etc/cosmos/keys/" + echo "" + echo "EXITING the script. In order to tag your changes," + echo "investigate and then run bump-tag again." + exit 1 + + else + + echo "" + echo "WARNING: The tag was probably correctly signed," + echo "but it still didn't pass the verification check." + echo "" + echo "EXITING the script. In order to tag your changes," + echo "investigate and then run bump-tag again." + exit 1 + + fi + + else + + echo "" + echo "WARNING: The signature of the tag could not be verified." + echo "Please make sure that you have imported the key and that" + echo "the key is signed by a trusted party." + echo "Keys used for signing in a Cosmos repo can be found at:" + echo "global/overlay/etc/cosmos/keys/" + echo "" + echo "EXITING the script. In order to tag your changes," + echo "investigate and then run bump-tag again." + exit 1 + + fi +} + +check_commit_sig_failure() +{ + local __commit_to_check="${1}" + local __file_related_to_commit="${2}" + + # shellcheck disable=SC2155 + local __verify_commit_output="$(git verify-commit --raw "${__commit_to_check}" 2>&1)" + + if echo "${__verify_commit_output}" | grep -q "VALIDSIG"; then + + if echo "${__verify_commit_output}" | grep -q "EXPKEYSIG"; then + + echo "WARNING: The commit to ${__file_related_to_commit}" + echo "was correctly signed, but the copy of the key that" + echo "you have stored on your computer has expired." + echo "Check for an updated key in:" + echo "global/overlay/etc/cosmos/keys/" + echo "" + echo "EXITING the script. In order to tag your changes," + echo "investigate and then run bump-tag again." + exit 1 + + else + + echo "WARNING: The commit to ${__file_related_to_commit}" + echo "was probably correctly signed, but it still didn't" + echo "pass the verification check." + echo "" + echo "EXITING the script. In order to tag your changes," + echo "investigate and then run bump-tag again." + exit 1 + + fi + + else + + echo "WARNING: The commit to ${__file_related_to_commit}" + echo "could not be verified. Please make sure that you have" + echo "imported the key and that the key is signed by a trusted party." + echo "" + echo "EXITING the script. In order to tag your changes," + echo "investigate and then run bump-tag again." + exit 1 + + fi +} + +# Verify the last commit of a file +# First argument: the file to verify +verify_last_commit() +{ + local __file_to_verify="${1}" + + if [[ ! -f "${__file_to_verify}" ]]; then + return 1 + fi + + if [[ ! -z "$(git status --porcelain "${__file_to_verify}")" ]]; then + echo "" + echo "INFO: local changes detected in ${__file_to_verify}," + echo "Not checking the signature of the last commit to ${__file_to_verify}." + echo "" + return 1 + fi + + # shellcheck disable=SC2155 + local __last_commit="$(git log -n 1 --pretty=format:%H -- "${__file_to_verify}")" + + if ! git verify-commit "${__last_commit}" 2> /dev/null; then + echo "" + echo "WARNING: Untrusted modification to ${__file_to_verify}:" + echo "----------------------------" + git verify-commit "$(git log -n 1 --pretty=format:%H -- "${__file_to_verify}")" + echo "----------------------------" + + check_commit_sig_failure "${__last_commit}" "${__file_to_verify}" + fi +} + +tag_list="$(git tag -l "${tagpfx}-*")" +if [[ ${?} -ne 0 ]] || [[ -z "${tag_list}" ]]; then + + echo "No tags found, verifying all commits instead." + # %H = commit hash + # %G? = show "G" for a good (valid) signature + git_log="$(git log --pretty="format:%H${t}%G?" \ + --first-parent \ + | grep -v "${t}G$")" + +else + + last_tag="$(echo "${tag_list}" | sort | tail -1)" + echo "Verifying last tag: ${last_tag} and the commits after that" + + git verify-tag "${last_tag}" + if [[ ${?} -ne 0 ]]; then + check_tag_sig_failure "${last_tag}" + fi + + tag_object="$(git verify-tag -v "${last_tag}" 2>&1 | grep ^object | cut -d' ' -f2)" + + # The commits after the last valid signed git tag that we need to check + revision_range="${tag_object}..HEAD" + + # Filter out the commits that are unsigned or untrusted + # %H = commit hash + # %G? = show "G" for a good (valid) signature + git_log="$(git log --pretty="format:%H${t}%G?" "${revision_range}" \ + --first-parent \ + | grep -v "${t}G$")" + +fi + +if [[ ! -z "${git_log}" ]]; then + echo "" + echo -e "------WARNING: unsigned or untrusted commits after the last tag------" + echo "${git_log}" + echo -e "---------------------------------------------------------------------" + echo "Quick referens on how to configure signing of commits in ~/.gitconfig:" + echo "[user]" + echo " signingkey = your-prefered-key-id" + echo "[commit]" + echo " gpgsign = true" + echo "" + echo "EXITING the script. In order to tag your changes," + echo "please make sure that you have configured signing of" + echo "your own commits and that the listed unsigned commits" + echo "have been made by a trusted party and are not malicous." + exit 1 +fi + +# Always check that the last commit of certain +# sensitive files is trusted, without taking into +# account whether the last tag was trusted or not. +verify_last_commit "./scripts/jsonyaml-no-output.py" +verify_last_commit "./bump-tag" + +# Test the syntax of each YAML-file to be tagged. +for file in $(git diff --name-only "${last_tag}..${this_branch}" | egrep "^.*\.(yaml|yml)$"); do + if [[ -f "${file}" ]]; then + ./scripts/jsonyaml-no-output.py yaml "${file}" + fi +done + +echo "Differences between tag ${last_tag} and what you are about to sign:" +# With PAGER=cat, git diff will simply dump the output to the screen. +# shellcheck disable=SC2037 +PAGER=cat git diff --color "${last_tag}..${this_branch}" + +# Iterate over the $last_tag until $this_tag is set to a later version +iter=1 +ok= +while [[ -z "${ok}" ]]; do + this_tag="$(date +"${tagpfx}-%Y-%m-%d-v$(printf "%02d" "${iter}")")" + iter="$(( iter + 1))" + + case "$( (echo "${this_tag}"; echo "${last_tag}") | sort | tail -1 )" in + "${last_tag}") + ;; + "${this_tag}") + ok=yes + ;; esac - done +done - if [ "${deftag}" != "${tagpfx}" ]; then +if [ "${deftag}" != "${tagpfx}" ]; then echo -e "Using new tag \e[94m${this_tag}\e[0m according to pattern in cosmos.conf" - else - echo -e "Using new tag \e[94m${this_tag}\e[0m" - fi - - echo -e "\e[1mONLY SIGN IF YOU APPROVE OF VERIFICATION AND DIFF ABOVE\e[0m" else - echo -e "\e[1mCOULD NOT FIND LAST TAG, ASSUMING NEW TAG\e[0m" - iter=1 - this_tag=$(date "+${tagpfx}-%Y-%m-%d-v$(printf "%02d" ${iter})") + echo -e "Using new tag \e[94m${this_tag}\e[0m" fi -# GITTAGEXTRA is for putting things like "-u 2117364A" -# shellcheck disable=SC2086 -git tag ${GITTAGEXTRA} -s "${this_tag}" -m bump. +echo -e "\e[1mONLY SIGN IF YOU APPROVE OF VERIFICATION AND DIFF ABOVE\e[0m" + +git tag $GITTAGEXTRA -m bump. -s "${this_tag}" git push git push --tags From 53c58b413e32b95bb3f46bfdec80d54ae4c03285 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Thu, 16 Nov 2023 11:56:49 +0100 Subject: [PATCH 103/111] Changed from if [[ ${?} ]] to if cmd --- bump-tag | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/bump-tag b/bump-tag index e4af1260..8708935d 100755 --- a/bump-tag +++ b/bump-tag @@ -2,9 +2,7 @@ echo "Fetching updates from $(git remote get-url origin) ..." echo "" -git pull --verify-signatures - -if [[ ${?} -ne 0 ]]; then +if ! git pull --verify-signatures; then echo "WARNING: git pull did not exit successfully." echo "" echo "EXITING the script. In order to tag your changes," @@ -183,8 +181,7 @@ else last_tag="$(echo "${tag_list}" | sort | tail -1)" echo "Verifying last tag: ${last_tag} and the commits after that" - git verify-tag "${last_tag}" - if [[ ${?} -ne 0 ]]; then + if ! git verify-tag "${last_tag}"; then check_tag_sig_failure "${last_tag}" fi From 826b8edf827838bf035ad57f6e424a304bd9bdc2 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Thu, 16 Nov 2023 11:59:33 +0100 Subject: [PATCH 104/111] Changed from [[ ! -z ... to [[ -n ... --- bump-tag | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bump-tag b/bump-tag index 8708935d..2c06d7e8 100755 --- a/bump-tag +++ b/bump-tag @@ -30,7 +30,7 @@ fi # 1. $tag, if specified in cosmos.conf, # 2. or $deftag, as specified above. # shellcheck disable=SC2154 -if [[ ! -z "${tag}" ]]; then +if [[ -n "${tag}" ]]; then tagpfx="${tag}" else tagpfx="${deftag}" @@ -144,7 +144,7 @@ verify_last_commit() return 1 fi - if [[ ! -z "$(git status --porcelain "${__file_to_verify}")" ]]; then + if [[ -n "$(git status --porcelain "${__file_to_verify}")" ]]; then echo "" echo "INFO: local changes detected in ${__file_to_verify}," echo "Not checking the signature of the last commit to ${__file_to_verify}." @@ -199,7 +199,7 @@ else fi -if [[ ! -z "${git_log}" ]]; then +if [[ -n "${git_log}" ]]; then echo "" echo -e "------WARNING: unsigned or untrusted commits after the last tag------" echo "${git_log}" From 5a47b1a3f74153c7f7a29b3f475b4613c4dc5227 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Thu, 16 Nov 2023 12:04:30 +0100 Subject: [PATCH 105/111] Readded this_branch=$(git rev-parse --abbrev-ref HEAD) since it wasn't included in change to check against the current branch instead of master --- bump-tag | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bump-tag b/bump-tag index 2c06d7e8..8a9b6e65 100755 --- a/bump-tag +++ b/bump-tag @@ -36,6 +36,9 @@ else tagpfx="${deftag}" fi +# This is the current branch that Git will diff against. +this_branch=$(git rev-parse --abbrev-ref HEAD) + # Check why the tag couldn't be verified # First argument: the tag to investigate check_tag_sig_failure() From cb9e1f867036d5b7cdcde918d3019ef19a21f2b0 Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Thu, 16 Nov 2023 12:07:10 +0100 Subject: [PATCH 106/111] Added shellcheck exceptions for misplaced warning. --- bump-tag | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bump-tag b/bump-tag index 8a9b6e65..74fc23e4 100755 --- a/bump-tag +++ b/bump-tag @@ -170,6 +170,7 @@ verify_last_commit() } tag_list="$(git tag -l "${tagpfx}-*")" +# shellcheck disable=SC2181 if [[ ${?} -ne 0 ]] || [[ -z "${tag_list}" ]]; then echo "No tags found, verifying all commits instead." @@ -262,7 +263,10 @@ fi echo -e "\e[1mONLY SIGN IF YOU APPROVE OF VERIFICATION AND DIFF ABOVE\e[0m" -git tag $GITTAGEXTRA -m bump. -s "${this_tag}" +# GITTAGEXTRA is for putting things like "-u 2117364A" +# Note that this variable cannot be quoted if left empty. +# shellcheck disable=SC2086 +git tag ${GITTAGEXTRA} -m bump. -s "${this_tag}" git push git push --tags From fd4523308f261b77e1532a35466bcaea82ea36fe Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Thu, 16 Nov 2023 12:09:02 +0100 Subject: [PATCH 107/111] Replaced 'egrep' that is now deprecated. --- bump-tag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bump-tag b/bump-tag index 74fc23e4..d69695f5 100755 --- a/bump-tag +++ b/bump-tag @@ -228,7 +228,7 @@ verify_last_commit "./scripts/jsonyaml-no-output.py" verify_last_commit "./bump-tag" # Test the syntax of each YAML-file to be tagged. -for file in $(git diff --name-only "${last_tag}..${this_branch}" | egrep "^.*\.(yaml|yml)$"); do +for file in $(git diff --name-only "${last_tag}..${this_branch}" | grep -E "^.*\.(yaml|yml)$"); do if [[ -f "${file}" ]]; then ./scripts/jsonyaml-no-output.py yaml "${file}" fi From dc1df6671cd220a03da15a53c5870dbd7f0bc07d Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Thu, 16 Nov 2023 12:11:09 +0100 Subject: [PATCH 108/111] Shellcheck needs to have the PAGER quoted in order to correctly interpret the meaning according to it's wiki. --- bump-tag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bump-tag b/bump-tag index d69695f5..a918b126 100755 --- a/bump-tag +++ b/bump-tag @@ -237,7 +237,7 @@ done echo "Differences between tag ${last_tag} and what you are about to sign:" # With PAGER=cat, git diff will simply dump the output to the screen. # shellcheck disable=SC2037 -PAGER=cat git diff --color "${last_tag}..${this_branch}" +PAGER="cat" git diff --color "${last_tag}..${this_branch}" # Iterate over the $last_tag until $this_tag is set to a later version iter=1 From 21c0cad8a026358c4708f4180389c9173a2b72ff Mon Sep 17 00:00:00 2001 From: John Van de Meulebrouck Brendgard Date: Thu, 16 Nov 2023 12:12:36 +0100 Subject: [PATCH 109/111] Consistently use [[ for if statements. --- bump-tag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bump-tag b/bump-tag index a918b126..cf2c8adb 100755 --- a/bump-tag +++ b/bump-tag @@ -255,7 +255,7 @@ while [[ -z "${ok}" ]]; do esac done -if [ "${deftag}" != "${tagpfx}" ]; then +if [[ "${deftag}" != "${tagpfx}" ]]; then echo -e "Using new tag \e[94m${this_tag}\e[0m according to pattern in cosmos.conf" else echo -e "Using new tag \e[94m${this_tag}\e[0m" From 71e112e00907125002fa61bc5782a44f51c0ad4f Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Wed, 29 Nov 2023 12:10:34 +0100 Subject: [PATCH 110/111] PREPARE/ADDHOST: allow the ues of proxyjump with ip address With this patch you can specify a ProxyJump for prepare-iaas-ubuntu, prepare-iaas-debian and addhost. Example: ./prepare-iaas-debian 89.47.191.7 hj ./addhost -b -n node1.extern.drive.test.sunet.se -p hj -- 89.47.191.7 where hj is a host defined in my .ssh/config suitable for a proxyjump to the host in question. This makes it easier to use ip addresses for these scripts which might be neccessary if dns takes a while to propagate. --- addhost | 15 ++++++++++----- prepare-iaas-debian | 8 ++++++-- prepare-iaas-ubuntu | 8 ++++++-- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/addhost b/addhost index cc1a479f..883d1728 100755 --- a/addhost +++ b/addhost @@ -13,11 +13,12 @@ function usage() { echo " can be an IP number, or something that resolves to one" } -while getopts "bhn:" this; do +while getopts "bhnp:" this; do case "${this}" in h) usage; exit 0;; b) cmd_do_bootstrap="yes" ;; n) cmd_fqdn="${OPTARG}" ; shift ;; + p) cmd_proxy="${OPTARG}" ; shift ;; *) echo "Unknown option ${this}"; echo ""; usage; exit 1;; esac done @@ -36,6 +37,10 @@ if test -z "$cmd_hostname"; then exit 1 fi +if [[ -n $cmd_proxy ]]; then + proxyjump="-o ProxyJump=${cmd_proxy}" +fi + test -f cosmos.conf && . ./cosmos.conf _remote=${remote:='ro'} @@ -57,8 +62,8 @@ fi if [ "$cmd_do_bootstrap" = "yes" ]; then cosmos_deb=$(find apt/ -maxdepth 1 -name 'cosmos_*.deb' | sort -V | tail -1) - scp "$cosmos_deb" apt/bootstrap-cosmos.sh root@"$cmd_hostname": - ssh root@"$cmd_hostname" ./bootstrap-cosmos.sh "$cmd_fqdn" "$rrepo" "$rtag" - ssh root@"$cmd_hostname" cosmos update - ssh root@"$cmd_hostname" cosmos apply + scp $proxyjump "$cosmos_deb" apt/bootstrap-cosmos.sh root@"$cmd_hostname": + ssh root@"$cmd_hostname" $proxyjump ./bootstrap-cosmos.sh "$cmd_fqdn" "$rrepo" "$rtag" + ssh root@"$cmd_hostname" $proxyjump cosmos update + ssh root@"$cmd_hostname" $proxyjump cosmos apply fi diff --git a/prepare-iaas-debian b/prepare-iaas-debian index cf36fb3b..30c395ad 100755 --- a/prepare-iaas-debian +++ b/prepare-iaas-debian @@ -1,5 +1,6 @@ #!/bin/bash ip="${1}" +ssh_proxy="${2}" if [[ -z "${ip}" ]]; then echo "Please specify a cloud image host that the script should do the following on:" @@ -9,6 +10,9 @@ if [[ -z "${ip}" ]]; then echo " #4 reboot to start using the new kernel, updated packages etc." exit 1 fi +if [[ -n "${ssh_proxy}" ]]; then + proxyjump="-o ProxyJump=${ssh_proxy}" +fi set -x @@ -21,5 +25,5 @@ script_dir=$(dirname "$0") # === # userdel: user debian is currently used by process 1082 # === -ssh "debian@${ip}" "bash -s" < "$script_dir"/iaas-enable-root.sh -ssh "root@${ip}" "bash -s" < "$script_dir"/iaas-setup.sh +ssh "debian@${ip}" ${proxyjump} "bash -s" < "$script_dir"/iaas-enable-root.sh +ssh "root@${ip}" ${proxyjump} "bash -s" < "$script_dir"/iaas-setup.sh diff --git a/prepare-iaas-ubuntu b/prepare-iaas-ubuntu index c21bf877..4a8ad391 100755 --- a/prepare-iaas-ubuntu +++ b/prepare-iaas-ubuntu @@ -1,5 +1,6 @@ #!/bin/bash ip="${1}" +ssh_proxy="${2}" if [[ -z "${ip}" ]]; then echo "Please specify a cloud image host that the script should do the following on:" @@ -10,6 +11,9 @@ if [[ -z "${ip}" ]]; then exit 1 fi +if [[ -n "${ssh_proxy}" ]]; then + proxyjump="-o ProxyJump=${ssh_proxy}" +fi set -x # Make sure we read the additional scripts from the same directory as @@ -21,5 +25,5 @@ script_dir=$(dirname "$0") # === # userdel: user ubuntu is currently used by process 44063 # === -ssh "ubuntu@${ip}" "bash -s" < "$script_dir"/iaas-enable-root.sh -ssh "root@${ip}" "bash -s" < "$script_dir"/iaas-setup.sh +ssh "ubuntu@${ip}" ${proxyjump} "bash -s" < "$script_dir"/iaas-enable-root.sh +ssh "root@${ip}" ${proxyjump} "bash -s" < "$script_dir"/iaas-setup.sh From cacb97a22c7b8c41c6b34017315e2d2d9ea673da Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Mon, 4 Dec 2023 14:24:34 +0100 Subject: [PATCH 111/111] Allow running of bumptag with out signed commits or tags By setting ALLOW_UNSIGNED_COMMITS_WITHOUT_TAGS you can bootstrap bumptag on first startup of new repo --- bump-tag | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bump-tag b/bump-tag index cf2c8adb..93522450 100755 --- a/bump-tag +++ b/bump-tag @@ -173,12 +173,15 @@ tag_list="$(git tag -l "${tagpfx}-*")" # shellcheck disable=SC2181 if [[ ${?} -ne 0 ]] || [[ -z "${tag_list}" ]]; then - echo "No tags found, verifying all commits instead." - # %H = commit hash - # %G? = show "G" for a good (valid) signature - git_log="$(git log --pretty="format:%H${t}%G?" \ - --first-parent \ - | grep -v "${t}G$")" + if [[ -z ${ALLOW_UNSIGNED_COMMITS_WITHOUT_TAGS} ]]; then + echo "No tags found, verifying all commits instead." + echo "Please set environment variable ALLOW_UNSIGNED_COMMITS_WITHOUT_TAGS if you want to disable this check." + # %H = commit hash + # %G? = show "G" for a good (valid) signature + git_log="$(git log --pretty="format:%H${t}%G?" \ + --first-parent \ + | grep -v "${t}G$")" + fi else