176 lines
7.1 KiB
Bash
176 lines
7.1 KiB
Bash
#!/bin/bash
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
set -e
|
|
[ "$DEBUG" = "false" ] || set -x
|
|
mkdir -p /etc/puppet
|
|
cp -dR /tmp/puppet-etc/* /etc/puppet
|
|
rm -Rf /etc/puppet/ssl # not in use and causes permission errors
|
|
echo "{\"step\": $STEP}" > /etc/puppet/hieradata/docker_puppet.json
|
|
TAGS=""
|
|
if [ -n "$PUPPET_TAGS" ]; then
|
|
TAGS="--tags \"$PUPPET_TAGS\""
|
|
fi
|
|
|
|
if [ ! -z ${STEP_CONFIG+x} ]; then
|
|
echo -e "${STEP_CONFIG}" | tee /etc/config.pp
|
|
fi
|
|
|
|
CHECK_MODE=""
|
|
if [ -d "/tmp/puppet-check-mode" ]; then
|
|
mkdir -p /etc/puppet/check-mode
|
|
cp -a /tmp/puppet-check-mode/* /etc/puppet/check-mode
|
|
CHECK_MODE="--hiera_config /etc/puppet/check-mode/hiera.yaml"
|
|
fi
|
|
|
|
# Create a reference timestamp to easily find all files touched by
|
|
# puppet. The sync ensures we get all the files we want due to
|
|
# different timestamp.
|
|
conf_data_path="/var/lib/config-data/${NAME}"
|
|
origin_of_time="${conf_data_path}.origin_of_time"
|
|
touch $origin_of_time
|
|
sync
|
|
|
|
export NET_HOST="${NET_HOST:-false}"
|
|
set +e
|
|
if [ "$NET_HOST" == "false" ]; then
|
|
export FACTER_hostname=$HOSTNAME
|
|
fi
|
|
# $::deployment_type in puppet-tripleo
|
|
export FACTER_deployment_type=containers
|
|
export FACTER_uuid=$(cat /sys/class/dmi/id/product_uuid | tr '[:upper:]' '[:lower:]')
|
|
echo 'Running puppet'
|
|
# FIXME(bogdando): stdout may be falling behind of the logged syslog messages
|
|
set -x
|
|
env "LANG=${LANG:-en_US.UTF-8}" /usr/bin/puppet apply --summarize \
|
|
--detailed-exitcodes \
|
|
--color=false \
|
|
--modulepath=/etc/puppet/modules:/usr/share/openstack-puppet/modules \
|
|
$TAGS \
|
|
$CHECK_MODE \
|
|
/etc/config.pp \
|
|
2>&1 | logger -s -t puppet-user
|
|
rc=${PIPESTATUS[0]}
|
|
[ "$DEBUG" = "false" ] && set +x
|
|
set -e
|
|
if [ $rc -ne 2 -a $rc -ne 0 ]; then
|
|
exit $rc
|
|
fi
|
|
|
|
verbosity=""
|
|
[ "$DEBUG" = "false" ] || verbosity="-v"
|
|
|
|
# Disables archiving
|
|
if [ -z "$NO_ARCHIVE" ]; then
|
|
archivedirs=("/etc" "/root" "/opt" "/var/www" "/var/spool/cron" "/var/lib/nova/.ssh")
|
|
rsync_srcs=""
|
|
for d in "${archivedirs[@]}"; do
|
|
if [ -d "$d" ]; then
|
|
rsync_srcs+=" $d"
|
|
fi
|
|
done
|
|
# On stack update, if a password was changed in a config file,
|
|
# some services (e.g. mysql) must change their internal state
|
|
# (e.g. password in mysql DB) when paunch restarts them; and
|
|
# they need the old password to achieve that.
|
|
# For those services, we update the config hash to notify
|
|
# paunch that a restart is needed, but we do not update the
|
|
# password file in container-puppet if the file already existed
|
|
# before and let the service regenerate it instead.
|
|
password_files="/root/.my.cnf"
|
|
|
|
exclude_files=""
|
|
for p in $password_files; do
|
|
if [ -f "$p" -a -f "${conf_data_path}$p" ]; then
|
|
exclude_files+=" --exclude=$p"
|
|
fi
|
|
done
|
|
|
|
# Exclude read-only mounted directories/files which we do not want
|
|
# to copy or delete.
|
|
ro_files="/etc/puppet/ /etc/puppetlabs/ /opt/puppetlabs/ /etc/pki/ca-trust/extracted "
|
|
ro_files+="/etc/pki/ca-trust/source/anchors /etc/pki/tls/certs/ca-bundle.crt "
|
|
ro_files+="/etc/pki/tls/certs/ca-bundle.trust.crt /etc/pki/tls/cert.pem "
|
|
ro_files+="/etc/hosts /etc/localtime /etc/hostname"
|
|
for ro in $ro_files; do
|
|
if [ -e "$ro" ]; then
|
|
exclude_files+=" --exclude=$ro"
|
|
fi
|
|
done
|
|
|
|
echo "Evaluating config files to be removed for the $NAME configuration"
|
|
TMPFILE=$(mktemp /tmp/tmp.XXXXXXXXXX)
|
|
TMPFILE2=$(mktemp /tmp/tmp.XXXXXXXXXX)
|
|
trap 'rm -rf $TMPFILE $TMPFILE2' EXIT INT HUP
|
|
rsync -av -R --dry-run --delete-after $exclude_files $rsync_srcs ${conf_data_path} |\
|
|
awk '/^deleting/ {print $2}' > $TMPFILE
|
|
|
|
echo "Rsyncing config files from ${rsync_srcs} into ${conf_data_path}"
|
|
rsync -a $verbosity -R --delay-updates --delete-after $exclude_files $rsync_srcs ${conf_data_path}
|
|
|
|
# Also make a copy of files modified during puppet run
|
|
echo "Gathering files modified after $(stat -c '%y' $origin_of_time)"
|
|
|
|
# Purge obsoleted contents to maintain a fresh and filtered mirror
|
|
puppet_generated_path=/var/lib/config-data/puppet-generated/${NAME}
|
|
mkdir -p ${puppet_generated_path}
|
|
echo "Ensuring the removed config files are also purged in ${puppet_generated_path}:"
|
|
cat $TMPFILE | sort
|
|
cat $TMPFILE | xargs -n1 -r -I{} \
|
|
bash -c "rm -rf ${puppet_generated_path}/{}"
|
|
exec 5>&1
|
|
exec 1>$TMPFILE2
|
|
find $rsync_srcs -newer $origin_of_time -not -path '/etc/puppet*' -print0
|
|
exec 1>&5
|
|
echo "Files modified during puppet run:"
|
|
cat $TMPFILE2 | xargs -0 printf "%s\n" | sort -h
|
|
echo "Rsyncing the modified files into ${puppet_generated_path}"
|
|
rsync -a $verbosity -R -0 --delay-updates --delete-after $exclude_files \
|
|
--files-from=$TMPFILE2 / ${puppet_generated_path}
|
|
|
|
# Cleanup any special files that might have been copied into place
|
|
# previously because fixes for LP#1860607 did not cleanup and required
|
|
# manual intervention if a container hit this. We can safely remove these
|
|
# files because they should be bind mounted into containers
|
|
for ro in $ro_files; do
|
|
if [ -e "${puppet_generated_path}/${ro}" ]; then
|
|
rm -rf "${puppet_generated_path}/${ro}"
|
|
fi
|
|
done
|
|
|
|
# Write a checksum of the config-data dir, this is used as a
|
|
# salt to trigger container restart when the config changes
|
|
# note: while being excluded from the output, password files
|
|
# are still included in checksum computation
|
|
additional_checksum_files=""
|
|
excluded_original_passwords=""
|
|
for p in $password_files; do
|
|
if [ -f "$p" ]; then
|
|
additional_checksum_files+=" $p"
|
|
excluded_original_passwords+=" --exclude=/var/lib/config-data/*${p}"
|
|
fi
|
|
done
|
|
# We need to exclude the swift rings and backups as those change over time
|
|
# and containers do not need to restart if they change
|
|
EXCLUDE=--exclude='*/etc/swift/backups/*'\ --exclude='*/etc/swift/*.ring.gz'\ --exclude='*/etc/swift/*.builder'\ --exclude='*/etc/libvirt/passwd.db'\ ${excluded_original_passwords}
|
|
|
|
# We need to repipe the tar command through 'tar xO' to force text
|
|
# output because otherwise the sed command cannot work. The sed is
|
|
# needed because puppet puts timestamps as comments in cron and
|
|
# parsedfile resources, hence triggering a change at every redeploy
|
|
tar -c --mtime='1970-01-01' $EXCLUDE -f - ${conf_data_path} $additional_checksum_files | tar xO | \
|
|
sed '/^#.*HEADER.*/d' | md5sum | awk '{print $1}' > ${conf_data_path}.md5sum
|
|
tar -c --mtime='1970-01-01' $EXCLUDE -f - ${puppet_generated_path} $additional_checksum_files --mtime='1970-01-01' | tar xO \
|
|
| sed '/^#.*HEADER.*/d' | md5sum | awk '{print $1}' > ${puppet_generated_path}.md5sum
|
|
fi
|