From 74f14d76c64da480b0991e62b94dc62b5bf7ab9d Mon Sep 17 00:00:00 2001 From: Nathan Brewer Date: Thu, 20 Apr 2017 10:26:30 -0700 Subject: [PATCH 01/13] Initial Commit --- .../Jenkins-Chef_Solo_RightLink_10_6_0.yml | 126 +++++ jenkins/RL10_Jenkins_Install_Master.sh | 122 +++++ jenkins/RL10_Jenkins_Install_Slave.sh | 290 +++++++++++ jenkins/RL10_Linux_Enable_Managed_Login.sh | 323 ++++++++++++ jenkins/RL10_Linux_Enable_Monitoring.sh | 472 ++++++++++++++++++ jenkins/RL10_Linux_Setup_Alerts.sh | 239 +++++++++ jenkins/RL10_Linux_Setup_Automatic_Upgrade.sh | 119 +++++ jenkins/RL10_Linux_Setup_Hostname.sh | 181 +++++++ jenkins/RL10_Linux_Shutdown_Reason.sh | 73 +++ jenkins/RL10_Linux_Upgrade.sh | 155 ++++++ ...RL5_6_10_Setup_Custom_Logrotate_Configs.sh | 75 +++ jenkins/Update_R53_A_Record.sh | 65 +++ jenkins/attachments/chef | 8 + jenkins/attachments/libnss_rightscale.tgz | Bin 0 -> 18799 bytes .../attachments/rightscale_login_policy.te | 18 + jenkins/attachments/rs-ssh-keys.sh | 41 ++ jenkins/attachments/rsc_jenkins-201704183.tar | Bin 0 -> 256000 bytes 17 files changed, 2307 insertions(+) create mode 100644 jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml create mode 100755 jenkins/RL10_Jenkins_Install_Master.sh create mode 100755 jenkins/RL10_Jenkins_Install_Slave.sh create mode 100755 jenkins/RL10_Linux_Enable_Managed_Login.sh create mode 100755 jenkins/RL10_Linux_Enable_Monitoring.sh create mode 100755 jenkins/RL10_Linux_Setup_Alerts.sh create mode 100755 jenkins/RL10_Linux_Setup_Automatic_Upgrade.sh create mode 100755 jenkins/RL10_Linux_Setup_Hostname.sh create mode 100755 jenkins/RL10_Linux_Shutdown_Reason.sh create mode 100755 jenkins/RL10_Linux_Upgrade.sh create mode 100755 jenkins/RL5_6_10_Setup_Custom_Logrotate_Configs.sh create mode 100755 jenkins/Update_R53_A_Record.sh create mode 100644 jenkins/attachments/chef create mode 100644 jenkins/attachments/libnss_rightscale.tgz create mode 100644 jenkins/attachments/rightscale_login_policy.te create mode 100644 jenkins/attachments/rs-ssh-keys.sh create mode 100644 jenkins/attachments/rsc_jenkins-201704183.tar diff --git a/jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml b/jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml new file mode 100644 index 0000000..614188f --- /dev/null +++ b/jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml @@ -0,0 +1,126 @@ +Name: Jenkins - Chef Solo (RightLink 10.6.0) +Description: "Chef Client ServerTemplate for RightLink10. RightLink10 is a new agent + to connect servers to the RightScale platform that is very lightweight and simple + to install.\n_It is not a plug-in upgrade from the older RightLink v6 series._\nSee + [http://docs.rightscale.com/rl/about.html](http://docs.rightscale.com/rl/about.html) + for details.\n\nThis base ST runs a script to update the packaging system and enable + automatic security updates, and a collectd install script to enable RightScale monitoring. + \n\nThe base ST can run on most any Linux distro that supports cloud-init. It is + recommended to use the standard distro images in various clouds.\n\n__Requirements__\n\n* + Chef Server or Hosted Chef\n\n__Tested Linux distros:__\n\n* Ubuntu 14.04 x86_64\n\n__Documenation__\n\n* + [Overview](http://docs.rightscale.com/st/rl10/chef-client/overview.html)\n\n\n__Tested + compute clouds:__\n\n* AWS\n" +Inputs: + COLLECTD_SERVER: env:RS_TSS + RS_INSTANCE_UUID: env:RS_INSTANCE_UUID +RightScripts: + Boot: + - RL10_Linux_Setup_Hostname.sh + - RL10_Linux_Enable_Managed_Login.sh + - RL10_Linux_Enable_Monitoring.sh + - RL10_Linux_Setup_Alerts.sh + - RL10_Linux_Setup_Automatic_Upgrade.sh + - RL5_6_10_Setup_Custom_Logrotate_Configs.sh + Decommission: + - RL10_Linux_Shutdown_Reason.sh + Operational: + - RL10_Jenkins_Install_Master.sh + - RL10_Jenkins_Install_Slave.sh + - RL10_Linux_Setup_Automatic_Upgrade.sh + - RL10_Linux_Upgrade.sh + - Update_R53_A_Record.sh +MultiCloudImages: +- Name: Ubuntu_14.04_x64 + Revision: 70 + Publisher: RightScale +- Name: Ubuntu_12.04_x64 + Revision: 66 + Publisher: RightScale +- Name: Ubuntu_12.04_x64_KVM + Revision: 31 + Publisher: RightScale +- Name: Ubuntu_14.04_x64_KVM + Revision: 31 + Publisher: RightScale +- Name: Ubuntu_16.04_x64 + Revision: 5 + Publisher: RightScale +- Name: Ubuntu_16.04_x64_KVM + Revision: 3 + Publisher: RightScale +- Name: CentOS_6.x_x64 + Revision: 25 + Publisher: RightScale +- Name: CentOS_6.x_x64_KVM + Revision: 30 + Publisher: RightScale +- Name: CentOS_7.x_x64 + Revision: 33 + Publisher: RightScale +- Name: CentOS_7.x_x64_KVM + Revision: 30 + Publisher: RightScale +- Name: RHEL_6.x_x64_KVM + Revision: 9 + Publisher: RightScale +- Name: RHEL_7.x_x64_KVM + Revision: 9 + Publisher: RightScale +- Name: RHEL_6.x_x64 + Revision: 13 + Publisher: RightScale +- Name: RHEL_7.x_x64 + Revision: 11 + Publisher: RightScale +Alerts: +- Name: rs instance terminated + Description: Raise an alert if the instance has been terminated abnormally, i.e. + not through the RightScale interface or by an elasticity daemon resizing server + arrays. + Clause: If RS/server.state == terminated for 1 minutes Then escalate critical +- Name: rs instance stranded + Description: Raise an alert if the instance enters the stranded state. + Clause: If RS/server-failure.state == stranded for 1 minutes Then escalate warning +- Name: rs instance not responding + Description: Raise an alert if the instance fails to send monitoring information + for 5 minutes. + Clause: If cpu-0/cpu-idle.value == NaN for 5 minutes Then escalate critical +- Name: rs cpu busy + Description: Raise an alert if the idle time is too low. + Clause: If cpu-0/cpu-idle.value < 15 for 3 minutes Then escalate warning +- Name: rs cpu overloaded + Description: Raise an alert when the cpu idle time is too low. + Clause: If cpu-0/cpu-idle.value < 3 for 5 minutes Then escalate critical +- Name: rs cpu I/O wait + Description: Raise an alert if disk io is too high. + Clause: If cpu-0/cpu-wait.value > 40 for 15 minutes Then escalate warning +- Name: rs low space in root partition + Description: Raise an alert if the available space in the root partition is too + low. This alert may be modified on an instance to match the metric name df/df-root.free + instead if the instance is running collectd 4. See the RL10 Linux Setup Alerts + RightScript (rll/setup-alerts.sh) for more details. + Clause: If df-root/df_complex-free.value < 1073741824 for 5 minutes Then escalate + critical +- Name: rs high network tx activity + Description: Raise an alert if the amount of network data transmitted is too high. + This alert may be modified or cloned on an instance to match the actual network + interfaces that are present. See the RL10 Linux Setup Alerts RightScript (rll/setup-alerts.sh) + for more details. + Clause: If interface-eth0/if_octets.tx > 10000000 for 10 minutes Then escalate critical +- Name: rs high network rx activity + Description: Raise an alert if the amount of network data received is too high. + This alert may be modified or cloned on an instance to match the actual network + interfaces that are present. See the RL10 Linux Setup Alerts RightScript (rll/setup-alerts.sh) + for more details. + Clause: If interface-eth0/if_octets.rx > 50000000 for 30 minutes Then escalate critical +- Name: rs low swap space + Description: Raise alert if the free swap space is too low. This alert may be removed + from an instance if swap is not enabled. See the RL10 Linux Setup Alerts RightScript + (rll/setup-alerts.sh) for more details. + Clause: If swap/swap-free.value < 104857600 for 5 minutes Then escalate critical +- Name: rs memory low + Description: Raise an alert if free memory is too low. + Clause: If memory/memory-free.value < 1000000 for 1 minutes Then escalate critical +- Name: rs out of memory + Description: Raise an alert when the server is out of free memory. + Clause: If memory/memory-free.value == 0 for 1 minutes Then escalate critical diff --git a/jenkins/RL10_Jenkins_Install_Master.sh b/jenkins/RL10_Jenkins_Install_Master.sh new file mode 100755 index 0000000..57f771e --- /dev/null +++ b/jenkins/RL10_Jenkins_Install_Master.sh @@ -0,0 +1,122 @@ +#! /usr/bin/sudo /bin/bash +# --- +# RightScript Name: RL10 Jenkins Install Master +# Description: Install and configure Jenkins master server +# Inputs: +# LOG_LEVEL: +# Category: CHEF +# Description: The log level for the chef install +# Input Type: single +# Required: true +# Advanced: true +# Possible Values: +# - text:info +# - text:warn +# - text:fatal +# - text:debug +# Default: text:info +# COOKBOOK_VERSION: +# Category: JENKINS +# Description: 'The jenkins cookbook version to install from. This allows for multiple versions +# of the same cookbook in the attachments. (e.g. If attachments is jenkins-201704111.tar the version is 201704111.)' +# Input Type: single +# Required: true +# Advanced: true +# Default: text:201704183 +# SWARM_PLUGIN_VERSION: +# Category: JENKINS +# Description: 'The swarm plugin version to use.' +# Input Type: single +# Required: true +# Advanced: true +# Default: text:3.4 +# Attachments: +# - rsc_jenkins-201704183.tar +# ... + +set -x +set -e + +# https://github.com/berkshelf/berkshelf-api/issues/112 +export LC_CTYPE=en_US.UTF-8 + +if [ ! -e /usr/bin/chef-client ]; then + curl -L https://www.opscode.com/chef/install.sh | sudo bash +fi + +chef_dir="/home/rightscale/.chef" + +# if [ -e $chef_dir/cookbooks ]; then +# echo "Jenkins already installed. Exiting." +# exit 0 +# fi + +rm -rf $chef_dir +mkdir -p $chef_dir/chef-install +chmod -R 0777 $chef_dir/chef-install + +mkdir -p $chef_dir/cookbooks +chown -R 0777 $chef_dir/cookbooks + +#install packages when on ubuntu +if which apt-get >/dev/null 2>&1; then + apt-get -y update + apt-get install -y build-essential git #ruby2.0 ruby2.0-dev +fi + +#install packages for centos +if which yum >/dev/null 2>&1; then + yum groupinstall -y 'Development Tools' + yum install -y libxml2 libxml2-devel libxslt libxslt-devel git +fi + +#install berkshelf +/opt/chef/embedded/bin/gem install berkshelf -v '4.3.5' --no-ri --no-rdoc + +#checkout the chef server cookbook and install dependent cookbooks using berkshelf +cd $chef_dir + +# Download cookbooks from RS Attachments + +if [ -f $RS_ATTACH_DIR/rsc_jenkins-$COOKBOOK_VERSION.tar ]; then + tar -xvf $RS_ATTACH_DIR/rsc_jenkins-$COOKBOOK_VERSION.tar +fi + +/opt/chef/embedded/bin/berks vendor $chef_dir/cookbooks + +cd $HOME + +if [ -e $chef_dir/chef.json ]; then + rm -f $chef_dir/chef.json +fi + +cat < $chef_dir/chef.json +{ + "name": "${HOSTNAME}", + "normal": { + + "tags": [ + ] + }, + "rightscale":{ + "instance_uuid":"$instance_uuid", + "instance_id":"$instance_id" + }, + "rsc_jenkins":{ + "swarm" : { + "version" : "$SWARM_PLUGIN_VERSION" + } + }, + "run_list": ["recipe[rsc_jenkins::master]","recipe[rsc_jenkins::swarm-plugin]"] +} +EOF + +cat < $chef_dir/solo.rb +cookbook_path "$chef_dir/cookbooks" +data_bag_path "$chef_dir/data_bags" +EOF + +#cp -f /tmp/environment /etc/environment +/sbin/mkhomedir_helper rightlink + +chef-solo -l $LOG_LEVEL -L /var/log/chef.log -j $chef_dir/chef.json -c $chef_dir/solo.rb diff --git a/jenkins/RL10_Jenkins_Install_Slave.sh b/jenkins/RL10_Jenkins_Install_Slave.sh new file mode 100755 index 0000000..072ff0a --- /dev/null +++ b/jenkins/RL10_Jenkins_Install_Slave.sh @@ -0,0 +1,290 @@ +#! /usr/bin/sudo /bin/bash +# --- +# RightScript Name: RL10 Jenkins Install Slave +# Description: Install and configure Jenkins master server +# Inputs: +# LOG_LEVEL: +# Category: CHEF +# Description: The log level for the chef install +# Input Type: single +# Required: true +# Advanced: true +# Possible Values: +# - text:info +# - text:warn +# - text:fatal +# - text:debug +# Default: text:info +# COOKBOOK_VERSION: +# Category: JENKINS +# Description: 'The jenkins cookbook version to install from. This allows for multiple versions +# of the same cookbook in the attachments. (e.g. If attachments is jenkins-201704111.tar the version is 201704111.)' +# Input Type: single +# Required: true +# Advanced: true +# Default: text:201704183 +# NAME: +# Category: JENKINS +# Description: 'The name of the jenkins slave server.' +# Input Type: single +# Required: true +# Advanced: false +# MASTER_IP: +# Category: JENKINS +# Description: 'The fqdn or IP address of the master.' +# Input Type: single +# Required: true +# Advanced: false +# SWARM_PLUGIN_VERSION: +# Category: JENKINS +# Description: 'The version of the swam plugin to install. https://wiki.jenkins-ci.org/display/JENKINS/Swarm+Plugin' +# Input Type: single +# Required: true +# Advanced: true +# Default: text:3.4 +# DESCRIPTION: +# Category: JENKINS +# Description: 'Description of slave instances.' +# Input Type: single +# Required: false +# Advanced: false +# AUTO_DISCOVERY_ADDRESS: +# Category: JENKINS +# Description: 'Use this address for udp-based auto-discovery' +# Input Type: single +# Required: false +# Advanced: true +# CANDIDATE_TAG: +# Category: JENKINS +# Description: 'Show swarm candidate with tag only' +# Input Type: single +# Required: false +# Advanced: true +# Default: text:false +# Possible Values: ["text:true", "text:false"] +# DELETE_EXISTING: +# Category: JENKINS +# Description: 'Deletes any existing slave with the same name.' +# Input Type: single +# Required: false +# Advanced: true +# Default: text:true +# Possible Values: ["text:true", "text:false"] +# DISABLE_UNIQUE_ID: +# Category: JENKINS +# Description: 'Disables clients unique ID.' +# Input Type: single +# Required: false +# Advanced: true +# Default: text:false +# Possible Values: ["text:true", "text:false"] +# DISABLE_SSL_VERIFICATION: +# Category: JENKINS +# Description: 'Disables SSL verification. Must be set to true if HTTP is being used.' +# Input Type: single +# Required: false +# Advanced: true +# Default: text:true +# Possible Values: ["text:true", "text:false"] +# EXECUTORS: +# Category: JENKINS +# Description: 'Number of executors.' +# Input Type: single +# Required: false +# Advanced: true +# Default: text:2 +# LABELS: +# Category: JENKINS +# Description: 'Whitespace-separated list of labels to be assigned for this slave.' +# Input Type: single +# Required: false +# Advanced: true +# MASTER_PORT: +# Category: JENKINS +# Description: 'The port the Jenkins master is listening on.' +# Input Type: single +# Required: true +# Advanced: true +# Default: text:8080 +# MASTER_PROTOCOL: +# Category: JENKINS +# Description: 'The http(s) protocol the Jenkins master is listening on.' +# Input Type: single +# Required: true +# Advanced: true +# Default: text:http +# Possible Values: ["text:http", "text:https"] +# MODE: +# Category: JENKINS +# Description: 'The mode controlling how Jenkins allocates jobs to slaves. Can be either "normal" (utilize this slave as much as possible) or "exclusive" (leave this machine for tied jobs only) Default: normal.' +# Input Type: single +# Required: false +# Advanced: true +# Possible Values: ["text:normal", "text:exclusive"] +# NO_RETRY_AFTER_CONNECTED: +# Category: JENKINS +# Description: 'Do not retry if a successful connection gets closed.' +# Input Type: single +# Required: false +# Advanced: true +# Default: text:false +# Possible Values: ["text:true", "text:false"] +# JENKINS_PASSWORD: +# Category: JENKINS +# Description: 'The Jenkins user password.' +# Input Type: single +# Required: false +# Advanced: true +# RETRY: +# Category: JENKINS +# Description: 'Number of retrys before giving up.' +# Input Type: single +# Required: false +# Advanced: true +# JENKINS_USERNAME: +# Category: JENKINS +# Description: 'The Jenkins user name.' +# Input Type: single +# Required: false +# Advanced: true +# RETRY_BACK_OFF_STRATEGY: +# Category: JENKINS +# Description: 'The mode controlling retry wait time.' +# Input Type: single +# Required: false +# Advanced: true +# Possible Values: ["text:linear", "text:exponential", "text:none"] +# RETRY_INTERVAL: +# Category: JENKINS +# Description: 'Time to wait before retry in seconds.' +# Input Type: single +# Required: false +# Advanced: true +# SSL_FINGER_PRINTS: +# Category: JENKINS +# Description: 'Whitespace-separated list of accepted certificate fingerprints (SHA-256/Hex), otherwise system truststore will be used.' +# Input Type: single +# Required: false +# Advanced: true +# MAX_RETRY_INTERVAL: +# Category: JENKINS +# Description: 'Max time to wait before retry in seconds.' +# Input Type: single +# Required: false +# Advanced: true +# Attachments: +# - rsc_jenkins-201704183.tar +# ... + +# Make Name URL Safe +# This should probably be done in the Jenkins cookbook +NAME=`echo "$NAME" | sed "s/ /_/g" | sed "s/[&$+,\/:;=?@#{}<>|%^]//g" | sed "s/[\[\]]//g"` + +set -x +set -e + +# https://github.com/berkshelf/berkshelf-api/issues/112 +export LC_CTYPE=en_US.UTF-8 + +if [ ! -e /usr/bin/chef-client ]; then + curl -L https://www.opscode.com/chef/install.sh | sudo bash +fi + +chef_dir="/home/rightscale/.chef" + +# if [ -e $chef_dir/cookbooks ]; then +# echo "Jenkins already installed. Exiting." +# exit 0 +# fi + +rm -rf $chef_dir +mkdir -p $chef_dir/chef-install +chmod -R 0777 $chef_dir/chef-install + +mkdir -p $chef_dir/cookbooks +chown -R 0777 $chef_dir/cookbooks + +#install packages when on ubuntu +if which apt-get >/dev/null 2>&1; then + apt-get -y update + apt-get install -y build-essential git #ruby2.0 ruby2.0-dev +fi + +#install packages for centos +if which yum >/dev/null 2>&1; then + yum groupinstall -y 'Development Tools' + yum install -y libxml2 libxml2-devel libxslt libxslt-devel git +fi + +#install berkshelf +/opt/chef/embedded/bin/gem install berkshelf -v '4.3.5' --no-ri --no-rdoc + +#checkout the chef server cookbook and install dependent cookbooks using berkshelf +cd $chef_dir + +# # Download cookbooks from RS Attachments + +if [ -f $RS_ATTACH_DIR/rsc_jenkins-$COOKBOOK_VERSION.tar ]; then + tar -xvf $RS_ATTACH_DIR/rsc_jenkins-$COOKBOOK_VERSION.tar +fi + +/opt/chef/embedded/bin/berks vendor $chef_dir/cookbooks + +cd $HOME + +if [ -e $chef_dir/chef.json ]; then + rm -f $chef_dir/chef.json +fi + +cat < $chef_dir/chef.json +{ + "name": "${HOSTNAME}", + "normal": { + + "tags": [ + ] + }, + "rightscale":{ + "instance_uuid":"$instance_uuid", + "instance_id":"$instance_id" + }, + "rsc_jenkins":{ + "swarm" : { + "version": "$SWARM_PLUGIN_VERSION" + }, + "slave": { + "name": "$NAME", + "description": "$DESCRIPTION", + "master": "$MASTER_IP", + "auto-discovery-address": "$AUTO_DISCOVERY_ADDRESS", + "candidate-tag": $CANDIDATE_TAG, + "delete-existing-clients": $DELETE_EXISTING, + "disable-clients-unique-id": $DISABLE_UNIQUE_ID, + "disable-ssl-verification": $DISABLE_SSL_VERIFICATION, + "executors": "$EXECUTORS", + "labels": "$LABELS", + "master_port": "$MASTER_PORT", + "master_protocol": "$MASTER_PROTOCOL", + "mode": "$MODE", + "no-retry-after-connected": $NO_RETRY_AFTER_CONNECTED, + "password": "$JENKINS_PASSWORD", + "retry": "$RETRY", + "retry-back-off-strategy": "$RETRY_BACK_OFF_STRATEGY", + "retry-interval": "$RETRY_INTERVAL", + "ssl-finger-prints": "$SSL_FINGER_PRINTS", + "username": "$JENKINS_USERNAME", + "maxRetryInterval": "$MAX_RETRY_INTERVAL" + } + }, + "run_list": ["recipe[rsc_jenkins::slave]"] +} +EOF + +cat < $chef_dir/solo.rb +cookbook_path "$chef_dir/cookbooks" +EOF + +#cp -f /tmp/environment /etc/environment +/sbin/mkhomedir_helper rightlink + +chef-solo -l $LOG_LEVEL -L /var/log/chef.log -j $chef_dir/chef.json -c $chef_dir/solo.rb diff --git a/jenkins/RL10_Linux_Enable_Managed_Login.sh b/jenkins/RL10_Linux_Enable_Managed_Login.sh new file mode 100755 index 0000000..79792f1 --- /dev/null +++ b/jenkins/RL10_Linux_Enable_Managed_Login.sh @@ -0,0 +1,323 @@ +#!/bin/bash + +# --- +# RightScript Name: RL10 Linux Enable Managed Login +# Description: | +# Enable does install of RightScale NSS plugin, and update of PAM and SSH configuration to +# allow SSH connectivity to RightScale accounts. Disable undoes enablement. +# Inputs: +# MANAGED_LOGIN: +# Category: RightScale +# Description: To enable or disable managed login. Default is 'enable'. +# Input Type: single +# Required: true +# Advanced: true +# Default: text:auto +# Possible Values: +# - text:auto +# - text:enable +# - text:disable +# Attachments: +# - rs-ssh-keys.sh +# - rightscale_login_policy.te +# - libnss_rightscale.tgz +# ... + +set -e + +# Run passed-in command with retries if errors occur. +# +# $@: full line command +# +function retry_command() { + # Setting config variables for this function + retries=5 + wait_time=10 + + while [ $retries -gt 0 ]; do + # Reset this variable before every iteration to be checked if changed + issue_running_command=false + $@ || { issue_running_command=true; } + if [ "$issue_running_command" = true ]; then + (( retries-- )) + echo "Error occurred - will retry shortly" + sleep $wait_time + else + # Break out of loop since command was successful. + break + fi + done + + # Check if issue running command still existed after all retries + if [ "$issue_running_command" = true ]; then + echo "ERROR: Unable to run: '$@'" + return 1 + fi +} + +# Read/source os-release to obtain variable values determining OS +if [[ -e /etc/os-release ]]; then + source /etc/os-release +else + # CentOS/RHEL 6 does not use os-release, so use redhat-release + if [[ -e /etc/redhat-release ]]; then + # Assumed format example: CentOS release 6.7 (Final) + ID=$(cut -d" " -f1 /etc/redhat-release) + VERSION_ID=$(cut -d" " -f3 /etc/redhat-release) + else + echo "ERROR: /etc/os-release or /etc/redhat-release is required but does not exist" + exit 1 + fi +fi +ID="${ID,,}" # convert to lowercase + +# Determine location of rsc +[[ -e /usr/local/bin/rsc ]] && rsc=/usr/local/bin/rsc || rsc=/opt/bin/rsc + +# Determine lib_dir and bin_dir location +if [[ "$ID" == "coreos" ]]; then + lib_dir="/opt/lib" + bin_dir="/opt/bin" +else + lib_dir="/usr/local/lib" + bin_dir="/usr/local/bin" +fi + +if ! $rsc rl10 actions 2>/dev/null | grep --ignore-case --quiet /rll/login/control; then + echo "This script must be run on a RightLink 10.5 or newer instance" + exit 1 +fi + +if [[ "$MANAGED_LOGIN" == "auto" ]]; then + if [[ "$ID" == "coreos" ]]; then + echo "Managed login is not supported on CoreOS. Not setting up managed login." + managed_login="disable" + else + managed_login="enable" + fi +else + managed_login=$MANAGED_LOGIN +fi + +case "$managed_login" in +enable) + if [[ "$ID" == "coreos" ]]; then + echo "Managed login is not supported on CoreOS. MANAGED_LOGIN must be set to 'disabled' or 'auto'." + exit 1 + fi + + echo "Enabling managed login" + + # Ubuntu 12.04 has a version of OpenSSH that does not allow AuthorizedKeysCommand. Instead use AuthorizedKeysFile. + if [[ "$ID" == "ubuntu" && "$VERSION_ID" == "12.04" ]]; then + ssh_config_entry="AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 /var/lib/rightlink_keys/%u" + rll_login_control="compat" + if sudo cut --delimiter=# --fields=1 /etc/ssh/sshd_config | grep --invert-match "${ssh_config_entry}" | grep --quiet "AuthorizedKeysFile\b"; then + echo "AuthorizedKeysFile already in use. This is required to continue - exiting without configuring managed login" + exit 1 + elif sudo cut --delimiter=# --fields=1 /etc/ssh/sshd_config | grep --quiet "${ssh_config_entry}"; then + echo "AuthorizedKeysFile already setup" + ssh_previously_configured="true" + fi + else + # sshd does not have a version flag, but it does give a version on its error message for an invalid POSIX flag + sshd_version=`sshd -V 2>&1 | grep "^OpenSSH" | cut --delimiter=' ' --fields=1 | cut --delimiter='_' --fields=2` + ssh_config_entry="AuthorizedKeysCommand ${bin_dir}/rs-ssh-keys.sh" + rll_login_control="on" + if sudo cut --delimiter=# --fields=1 /etc/ssh/sshd_config | grep --invert-match "${ssh_config_entry}" | grep --quiet "AuthorizedKeysCommand\b"; then + echo "AuthorizedKeysCommand already in use. This is required to continue - exiting without configuring managed login" + exit 1 + elif sudo cut --delimiter=# --fields=1 /etc/ssh/sshd_config | grep --quiet "${ssh_config_entry}"; then + echo "AuthorizedKeysCommand already setup" + ssh_previously_configured="true" + fi + # OpenSSH version 6.2 and higher uses AuthorizedKeysCommand and requires AuthorizedKeysCommandUser + if [[ "$(printf "$sshd_version\n6.2" | sort --version-sort | tail --lines=1)" == "$sshd_version" ]]; then + ssh_config_entry+="\nAuthorizedKeysCommandUser nobody" + fi + fi + + if [[ "$ssh_previously_configured" != "true" ]]; then + # Generate SSH staging config and test that the config is valid. If valid, just copy the staging config later. + sshd_staging_config=$(mktemp /tmp/sshd_config.XXXXXXXXXX) + sudo cp -a /etc/ssh/sshd_config $sshd_staging_config + sudo bash -c "echo -e '\n${ssh_config_entry}' >> $sshd_staging_config" + # Test staging sshd_config file + if ! `sudo sshd -t -f $sshd_staging_config`; then + echo "sshd_config changes are invalid - exiting without configuring managed login" + exit 1 + fi + fi + + # Check that pam config for sshd exists + if [ ! -e /etc/pam.d/sshd ]; then + echo "Unable to determine location of required PAM sshd configuration - exiting without configuring managed login" + exit 1 + fi + + # Verify /var/lib/rightlink directory was created during install of RL10. Create if missing. + # It may be missing due to upgrade. + if [ ! -d /var/lib/rightlink ]; then + echo "Expected /var/lib/rightlink directory - creating" + sudo install --directory --group=rightlink --owner=rightlink --mode=0755 /var/lib/rightlink + fi + + # Create /var/lib/rightlink_keys directory created if set to 'compat' + if [[ "$rll_login_control" == "compat" ]]; then + sudo install --directory --group=root --owner=root --mode=0755 /var/lib/rightlink_keys + fi + + # Install $bin_dir/rs-ssh-keys.sh + echo "Installing ${bin_dir}/rs-ssh-keys.sh" + attachments=${RS_ATTACH_DIR:-attachments} + sudo install --target-directory=${bin_dir} --group=root --owner=root --mode=0755 ${attachments}/rs-ssh-keys.sh + + # Copy staging sshd_config file + if [[ "$ssh_previously_configured" != "true" ]]; then + sudo mv $sshd_staging_config /etc/ssh/sshd_config + # Determine if service name is ssh or sshd + case "$ID" in + ubuntu|debian) + ssh_service_name='ssh' + ;; + *) + ssh_service_name='sshd' + ;; + esac + sudo service ${ssh_service_name} restart + fi + + # Create /etc/sudoers.d/90-rightscale-sudo-users + if [ -e /etc/sudoers.d/90-rightscale-sudo-users ]; then + echo "Sudoers file already exists" + else + echo "Creating sudoers file" + sudo bash -c "umask 0337 && printf '# Members of the rightscale_sudo group may gain root privileges\n%%rightscale_sudo ALL=(ALL) SETENV:NOPASSWD:ALL\n' > /etc/sudoers.d/90-rightscale-sudo-users" + fi + + # Update pam config to create homedir on login + if cut --delimiter=# --fields=1 /etc/pam.d/sshd | grep --quiet pam_mkhomedir; then + echo "PAM config /etc/pam.d/sshd already contains pam_mkhomedir" + else + echo "Adding pam_mkhomedir to /etc/pam.d/sshd" + sudo bash -c "printf '# Added by RightScale Managed Login script\nsession required pam_mkhomedir.so skel=/etc/skel/ umask=0022\n' >> /etc/pam.d/sshd" + fi + + # Update nsswitch.conf + if cut --delimiter=# --fields=1 /etc/nsswitch.conf | grep --quiet rightscale; then + echo "/etc/nsswitch.conf already configured" + else + echo "Configuring /etc/nsswitch.conf" + sudo sed -i '/^\(passwd\|group\|shadow\)/ s/$/ rightscale/' /etc/nsswitch.conf + fi + + # Install NSS plugin library. This has been designed to overwrite existing library. + sudo mkdir -p /etc/ld.so.conf.d ${lib_dir} + sudo tar --no-same-owner -xzf ${attachments}/libnss_rightscale.tgz -C ${lib_dir} + sudo bash -c "echo ${lib_dir} > /etc/ld.so.conf.d/rightscale.conf" + sudo ldconfig + + # Configure selinux to allow sshd and pam to read the login policy file at + # /var/lib/rightlink/login_policy. This policy adds the following rules, as + # well as make the user's homedir on the fly. + if which sestatus >/dev/null 2>&1; then + if sudo sestatus | grep enabled >/dev/null 2>&1; then + # install checkmodule if it is not installed + if ! which checkmodule >/dev/null 2>&1; then + case "$ID" in + ubuntu|debian) + retry_command sudo apt-get install -y checkpolicy + ;; + centos|fedora|rhel) + retry_command sudo yum install -y checkpolicy + ;; + esac + fi + + # install semodule_package if it is not installed + if ! which semodule_package >/dev/null 2>&1; then + case "$ID" in + ubuntu|debian) + retry_command sudo apt-get install -y policycoreutils + ;; + centos|fedora|rhel) + retry_command sudo yum install -y policycoreutils-python + ;; + esac + fi + + policy_file="${attachments}/rightscale_login_policy.te" + installed_version=$(sudo semodule -l | grep rightscale_login_policy | awk '{print $2}' | sed 's/\.//') + desired_version=$(grep module $policy_file | awk '{print $3}' | sed 's/[\.;]//g') + if [[ "$desired_version" == "$installed_version" ]]; then + echo "rightscale_login_policy selinux policy already installed, skipping re-installation." + else + echo "Installing selinux policy to support reading of login policy file and creation of homedir" + checkmodule -M -m -o rightscale_login_policy.mod $policy_file + semodule_package -m rightscale_login_policy.mod -o rightscale_login_policy.pp + sudo semodule -i rightscale_login_policy.pp + fi + fi +fi + + # Send enable action to RightLink + $rsc --retry=5 --timeout=10 rl10 update /rll/login/control "enable_login=${rll_login_control}" + + # Adding rs_login:state=user tag + $rsc --retry=5 --timeout=60 --rl10 cm15 multi_add /api/tags/multi_add resource_hrefs[]=$RS_SELF_HREF tags[]=rs_login:state=user + ;; +disable) + if [[ "$ID" == "coreos" ]]; then + exit 0 + fi + + echo "Disabling managed login" + + # Remove rs_login:state=user tag + $rsc --retry=5 --timeout=60 --rl10 cm15 multi_delete /api/tags/multi_delete resource_hrefs[]=$RS_SELF_HREF tags[]=rs_login:state=user + + # Send disable action to RightLink + $rsc --retry=5 --timeout=10 rl10 update /rll/login/control "enable_login=off" + + # Remove NSS plugin library files + sudo rm -frv $lib_dir/libnss_rightscale.* + sudo rm -frv /etc/ld.so.conf.d/rightscale.conf + sudo ldconfig + + # Remove rightscale NSS plugin from /etc/nsswitch.conf + sudo sed -i '/^\(passwd\|group\|shadow\)/ s/\s\?rightscale\s*/ /; s/\s*$//' /etc/nsswitch.conf + + # Remove pam_mkhomedir line from /etc/pam.d/sshd + sudo sed -i '/^# Added by RightScale Managed Login script$/ {N; /^#.*session required pam_mkhomedir.so skel=\/etc\/skel\/ umask=0022$/d}' /etc/pam.d/sshd + + # Remove sudoers file + sudo rm -frv /etc/sudoers.d/90-rightscale-sudo-users + + # Remove AuthorizedKeysCommand and AuthorizedKeysCommandUser from sshd_config + sudo sed -i '/^AuthorizedKeysCommand \/usr\/local\/bin\/rs-ssh-keys.sh$/d' /etc/ssh/sshd_config + sudo sed -i '/^AuthorizedKeysCommandUser nobody$/d' /etc/ssh/sshd_config + sudo sed -i '/^AuthorizedKeysFile .ssh\/authorized_keys .ssh\/authorized_keys2 \/var\/lib\/rightlink_keys\/%u$/d' /etc/ssh/sshd_config + + # Remove rs-ssh-keys.sh + sudo rm -frv $bin_dir/rs-ssh-keys.sh + + # Remove /var/lib/rightlink folder + sudo rm -frv /var/lib/rightlink/ + + # Remove /var/lib/rightlink_keys folder + sudo rm -frv /var/lib/rightlink_keys/ + + # Remove rightscale managed login selinux policy + if which sestatus >/dev/null 2>&1; then + if sudo sestatus | grep enabled >/dev/null 2>&1; then + if sudo semodule -l | grep rightscale_login_policy >/dev/null 2>&1; then + sudo semodule -r rightscale_login_policy + fi + fi + fi + ;; +*) + echo "Unknown action: $managed_login" + exit 1 + ;; +esac diff --git a/jenkins/RL10_Linux_Enable_Monitoring.sh b/jenkins/RL10_Linux_Enable_Monitoring.sh new file mode 100755 index 0000000..d3d161b --- /dev/null +++ b/jenkins/RL10_Linux_Enable_Monitoring.sh @@ -0,0 +1,472 @@ +#! /bin/bash -e + +# --- +# RightScript Name: RL10 Linux Enable Monitoring +# Description: | +# Chose to either enable built-in RightLink monitoring or install and setup collectd with basic set of plugins. +# Both methods work with RightScale TSS (Time Series Storage), a backend system for aggregating and +# displaying monitoring data. Using collectd will sent monitoring data to the RightLink process on the localhost +# as HTTP using the write_http plugin, which then forwards that data to the TSS servers over HTTPS with authentication. +# +# ## Known Limitations: +# Choosing to use use collectd on very small instance types (less than 1GB memory) may result in a failure +# to install "collectd_tcp_network_connect" because of a lack of memory. +# This can be worked around by adding a 1GB or larger swap file to your server prior to running this script. +# Inputs: +# RS_INSTANCE_UUID: +# Category: RightScale +# Description: If using collectd, the monitoring ID for this server. +# Input Type: single +# Required: true +# Advanced: true +# Default: env:RS_INSTANCE_UUID +# COLLECTD_SERVER: +# Category: RightScale +# Description: If using collectd, the FQDN or IP address of the remote collectd +# server. +# Input Type: single +# Required: true +# Advanced: true +# Default: env:RS_TSS +# MONITORING_METHOD: +# Category: RightScale +# Description: | +# Determine the method of monitoring to use, either RightLink monitoring or collectd. Setting to +# 'auto' will use code to select method. +# Input Type: single +# Required: true +# Advanced: true +# Default: text:auto +# Possible Values: +# - text:auto +# - text:collectd +# - text:rightlink +# Attachments: [] +# ... +# + +# Check if a file needs to be written. First checks if the target file exists and if so checks if the checksums of the +# target file and the temporary file match. +# +# $1: the target file path to be checked +# $2: the temporary file path with new contents to check against +# +function run_check_write_needed() { + sudo [ ! -f $1 ] || [[ `run_checksum $2` != `run_checksum $1` ]] +} + +# Get the SHA256 checksum of a file. +# +# $1: the file path to get the checksum from +# +function run_checksum() { + sudo sha256sum $1 | cut -d ' ' -f 1 +} + +# Add a temporary file to the list of temporary files to clean up on exit. +# +# $@: one or more file paths to add to the list +# +function add_mktemp_file() { + mktemp_files=("$@" "${mktemp_files[@]}") +} + +# Configure a collectd plugin. +# +# $1: the name of the collectd plugin to configure +# $@: zero or more configuration options to set +# +function configure_collectd_plugin() { + local collectd_plugin=$1 + # Remove $1 from $@ + shift + local collectd_plugin_conf="$collectd_conf_plugins_dir/${collectd_plugin}.conf" + # Create a temporary file for the collectd plugin configration + local collectd_plugin_conf_tmp=`sudo mktemp "${collectd_plugin_conf}.XXXXXXXXXX"` + add_mktemp_file $collectd_plugin_conf_tmp + + sudo dd of="$collectd_plugin_conf_tmp" 2>/dev/null </dev/null < +EOF + + for option in "$@"; do + sudo bash -c "echo ' $option' >> $collectd_plugin_conf_tmp" + done + sudo bash -c "echo '' >> $collectd_plugin_conf_tmp" + fi + + # Overwrite and backup the collectd plugin configration if it has changed + if run_check_write_needed $collectd_plugin_conf $collectd_plugin_conf_tmp; then + sudo chmod 0644 $collectd_plugin_conf_tmp + sudo [ -f $collectd_plugin_conf ] && sudo cp --archive $collectd_plugin_conf "${collectd_plugin_conf}.`date -u +%Y%m%d%H%M%S`" + sudo mv --force $collectd_plugin_conf_tmp $collectd_plugin_conf + collectd_service_notify=1 + fi + + echo "collectd plugin $collectd_plugin configured" +} + +# Run passed-in command with retries if errors occur. +# +# $@: full line command +# +function retry_command() { + # Setting config variables for this function + retries=5 + wait_time=10 + + while [ $retries -gt 0 ]; do + # Reset this variable before every iteration to be checked if changed + issue_running_command=false + $@ || { issue_running_command=true; } + if [ "$issue_running_command" = true ]; then + (( retries-- )) + echo "Error occurred - will retry shortly" + sleep $wait_time + else + # Break out of loop since command was successful. + break + fi + done + + # Check if issue running command still existed after all retries + if [ "$issue_running_command" = true ]; then + echo "ERROR: Unable to run: '$@'" + return 1 + fi +} + +# Ensure rsc is in the path +export PATH="/usr/local/bin:/opt/bin:$PATH" + +# Determine what mode to use if MONITORING_METHOD is set to 'auto' +if [[ "$MONITORING_METHOD" == "auto" ]]; then + # Currently, the only criteria to automatically use RightLink monitoring is if OS is CoreOS + if grep -iq "id=coreos" /etc/os-release 2> /dev/null; then + monitoring_method="rightlink" + else + monitoring_method="collectd" + fi +else + monitoring_method=$MONITORING_METHOD +fi + +# Determine which network interfaces exist excluding lo so we can configure collectd +interfaces=(`ip -o link | awk '{ sub(/:$/, "", $2); if ($2 != "lo") { print $2; } }'`) + +# Determine if swap is enabled +if [[ $(sudo swapon -s | wc -l) -gt 1 ]]; then + swap=1 +else + swap=0 +fi + +# Determine if using RightLink monitoring or collectd +if [[ "$monitoring_method" == "rightlink" ]]; then + # Enable built-in monitoring + echo "Using RightLink monitoring" + rsc --retry=5 --timeout=10 rl10 update /rll/tss/control enable_monitoring=all +else + # Initialize variables + if [[ ! "$COLLECTD_SERVER" =~ tss ]]; then + echo "ERROR: This script will only run on a TSS enabled account. Contact RightScale Support to enable." + exit 1 + fi + echo "Using collectd for monitoring" + + # TSS is compatible with both collectd 4 and 5 while the previous monitoring backend + # only supported collectd 4. We forward ported collectd 4 to newer OSes b/c of this. + # If we installed a custom forward port of collectd4 previously, remove it now to + # replace it with OS standard collectd. + if which apt-get >/dev/null 2>&1; then + if [[ -e /etc/apt/preferences.d/rightscale-collectd-pin-1001 ]]; then + sudo rm /etc/apt/preferences.d/rightscale-collectd-pin-1001 + fi + rs_version="$(apt-cache showpkg collectd-core | grep rightscale | head -n 1 | awk '{print $1}')" + if [[ -n "$rs_version" ]]; then + installed_version=$(dpkg -l | grep '^ii' | grep collectd-core | awk '{print $3}') + if [[ "$installed_version" == "$rs_version" ]]; then + echo "Removing collectd 4 package" + retry_command sudo apt-get purge -y collectd collectd-core + fi + fi + elif yum list collectd 2>&1 | grep '@rightscale-epel' >/dev/null 2>&1; then + if grep collectd-4 /etc/yum/pluginconf.d/versionlock.list >/dev/null 2>&1; then + sudo sed -i '/collectd/d' /etc/yum/pluginconf.d/versionlock.list + fi + echo "Removing collectd 4 package" + retry_command sudo yum remove -y "collectd*" + fi + + # Collectd package is located in the EPEL repository. Install if its not already + # installed. + if [[ -e /etc/redhat-release ]]; then + if [[ `cat /etc/redhat-release` =~ ^([^0-9]+)\ ([0-9])\. ]]; then + distro="${BASH_REMATCH[1]}" + ver="${BASH_REMATCH[2]}" + else + echo "Could not parse distro and version from /etc/redhat-release" + exit 1 + fi + + case "$ver" in + 6) + if ! yum list installed "epel-release-6*"; then + echo "Installing EPEL repository" + retry_command sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm + if [[ "$distro" =~ CentOS ]]; then + # versions of CentOS 6.x have trouble with https... + sudo sed -i 's/https/http/' /etc/yum.repos.d/epel.repo + fi + fi + ;; + 7) + if ! yum list installed "epel-release-7*"; then + echo "Installing EPEL repository" + retry_command sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm + fi + ;; + esac + fi + + + # Declare a list for temporary files to clean up on exit and set the command to delete them if they still exist when the + # script exits + declare -a mktemp_files + trap 'sudo rm --force "${mktemp_files[@]}"' EXIT + + collectd_base_dir=/var/lib/collectd + collectd_types_db=/usr/share/collectd/types.db + collectd_interval=20 + collectd_read_threads=5 + collectd_server_port=3011 + collectd_service=collectd + collectd_service_notify=0 + + if [[ -d /etc/apt ]]; then + collectd_conf_dir=/etc/collectd + collectd_conf_plugins_dir="$collectd_conf_dir/plugins" + collectd_plugin_dir=/usr/lib/collectd + elif [[ -d /etc/yum.repos.d ]]; then + collectd_conf_dir=/etc + collectd_conf_plugins_dir="$collectd_conf_dir/collectd.d" + collectd_plugin_dir=/usr/lib64/collectd + else + echo "unsupported distribution!" + exit 1 + fi + + collectd_conf="$collectd_conf_dir/collectd.conf" + collectd_collection_conf="$collectd_conf_dir/collection.conf" + collectd_thresholds_conf="$collectd_conf_dir/thresholds.conf" + + # Install platform specific collectd packages + if [[ -d /etc/apt ]]; then + # Resync the package index with sources + retry_command sudo apt-get update -y + retry_command sudo apt-get install -y curl collectd-core + elif [[ -d /etc/yum.repos.d ]]; then + # Workaround for broken collectd + if yum info collectd | grep -E '5.6.1|5.6.0'; then + if rpm -qi collectd | grep -E '5.6.1|5.6.0'; then + retry_command sudo yum remove -y collectd + fi + echo "Collectd v5.6.0 or v5.6.1 detected. Collectd write_http plugin is temporarily broken for CentOS/RHEL operating systems." + echo "See: https://github.com/collectd/collectd/issues/1996" + echo "Falling back to using RightLink monitoring" + rsc --retry=5 --timeout=10 rl10 update /rll/tss/control enable_monitoring=all + exit 0 + fi + + # keep these lines separate, yum doesn't fail for missing packages when grouped together + retry_command sudo yum install -y curl + retry_command sudo yum install -y collectd + fi + + # For TSS, collectd connects to the rightlink process, which runs with a random + # high port for localhost (127.0.0.1). Without this permission relaxed, we'll get + # permission denied connecting to that local ip + if sestatus 2>/dev/null | grep "SELinux status" | grep enabled; then + # Existence check - on CentOS 6 this variable doesn't exist and isn't needed + if getsebool collectd_tcp_network_connect >/dev/null 2>&1; then + echo "Setting SELinux variable collectd_tcp_network_connect to on" + sudo setsebool -P collectd_tcp_network_connect 1 + fi + fi + + sudo mkdir --mode=0755 --parents $collectd_conf_plugins_dir $collectd_base_dir $collectd_plugin_dir + + # Create a temporary file for the collectd configuration + collectd_conf_tmp=`sudo mktemp "${collectd_conf}.XXXXXXXXXX"` + add_mktemp_file $collectd_conf_tmp + + sudo dd of="$collectd_conf_tmp" 2>/dev/null </dev/null </dev/null < +# +# WarningMin 0.00 +# WarningMax 1000.00 +# FailureMin 0 +# FailureMax 1200.00 +# Invert false +# Persist false +# Instance "some_instance" +# +# +# +# Instance "eth0" +# +# DataSource "rx" +# FailureMax 10000000 +# +# +# +# +# +# Instance "idle" +# FailureMin 10 +# +# +# +# +# Instance "cached" +# WarningMin 100000000 +# +# +# +# +EOF + + # Overwrite and backup the collectd thresholds configuration if it has changed + if run_check_write_needed $collectd_thresholds_conf $collectd_thresholds_conf_tmp; then + sudo chmod 0644 $collectd_thresholds_conf_tmp + [[ -f $collectd_thresholds_conf ]] && sudo cp --archive $collectd_thresholds_conf "${collectd_thresholds_conf}.`date -u +%Y%m%d%H%M%S`" + sudo mv --force $collectd_thresholds_conf_tmp $collectd_thresholds_conf + collectd_service_notify=1 + fi + + configure_collectd_plugin syslog + + # Configure interface monitoring for all qualifying interfaces + declare -a interface_configs + for interface in "${interfaces[@]}"; do + interface_configs[${#interface_configs[@]}]="Interface \"$interface\"" + done + + configure_collectd_plugin interface \ + "${interface_configs[@]}" + + configure_collectd_plugin cpu + configure_collectd_plugin df \ + 'ReportReserved false' \ + 'FSType "proc"' \ + 'FSType "sysfs"' \ + 'FSType "fusectl"' \ + 'FSType "debugfs"' \ + 'FSType "securityfs"' \ + 'FSType "devtmpfs"' \ + 'FSType "devpts"' \ + 'FSType "tmpfs"' \ + 'IgnoreSelected true' + configure_collectd_plugin disk + configure_collectd_plugin memory + + if [[ $swap -eq 1 ]]; then + configure_collectd_plugin swap + else + echo "swapfile not setup, skipping collectd swap plugin" + fi + + # Populate RS_RLL_PORT + source /var/run/rightlink/secret + rsc --retry=5 --timeout=10 rl10 update /rll/tss/control enable_monitoring=util + collectd_ver=5 + if [[ "$(collectd -h)" =~ "collectd 4" ]]; then + collectd_ver=4 + fi + configure_collectd_plugin write_http \ + "URL \"http://127.0.0.1:$RS_RLL_PORT/rll/tss/collectdv$collectd_ver\"" + configure_collectd_plugin load + configure_collectd_plugin processes + configure_collectd_plugin users + + + # Make sure the collectd service is enabled + if [[ -d /etc/yum.repos.d ]]; then + sudo chkconfig $collectd_service on + fi + + if collectd -T 2>&1 | grep 'Parse error' >/dev/null 2>&1; then + echo "ERROR: collectd config contains syntax errors:" + collectd -T + exit 1 + fi + + # Start the collectd service if it is not running or restart it if it needs to be restarted + if ! sudo service $collectd_service status; then + sudo service $collectd_service start + elif [[ $collectd_service_notify -eq 1 ]]; then + sudo service $collectd_service restart + fi +fi diff --git a/jenkins/RL10_Linux_Setup_Alerts.sh b/jenkins/RL10_Linux_Setup_Alerts.sh new file mode 100755 index 0000000..4cc6c78 --- /dev/null +++ b/jenkins/RL10_Linux_Setup_Alerts.sh @@ -0,0 +1,239 @@ +#!/bin/bash +# --- +# RightScript Name: RL10 Linux Setup Alerts +# Description: | +# Set up the RightScale Alerts on the instance to match the metrics that it is actually reporting with either built-in +# RightLink monitoring or collectd. The RightScale Alerts on this ServerTemplate are set to match the metrics reported +# by the built-in RightLink monitoring and collectd 5, but there are a few metrics which have names which vary based +# on the system they are running and there are also some metrics which have different names with collectd 4 which is +# used on older Linux distribution versions (such as Ubuntu 12.04 and CentOS 6). +# +# The alerts that need to be set up by this script are: +# +# * **rs low space in root partition**: If a Linux system is running collectd 4, the metric used for this alert will +# be set to `df/df-root.free` rather than `df-root/df_complex-free.value`. +# * **rs high network tx activity** and **rs high network rx activity**: On newer Linux distribution versions (such as +# CoreOS and Ubuntu 16.04) the network interface name is not necessarily `eth0` and there may be more network +# interfaces on the system, so this script will update and add the alerts to match the network interfaces on the +# system. +# * **rs low swap space**: If no swap is set up on a Linux system, no swap metrics will be sent. If you enable swap on +# the system at a later point, this script can be rerun to re-enable the alert. +# Inputs: +# MONITORING_METHOD: +# Category: RightScale +# Description: | +# Determine the method of monitoring to use, either RightLink monitoring or collectd. Setting to +# 'auto' will use code to select method. +# Input Type: single +# Required: true +# Advanced: true +# Default: text:auto +# Possible Values: +# - text:auto +# - text:collectd +# - text:rightlink +# Attachments: [] +# ... + +set -e + +# Create an alert spec on the instance based on a template alert spec from the ServerTemplate with optional parameter +# overrides. +# +# $1: the alert spec template name +# $2: the instance name to append to the template name which is used to name the new alert spec +# $@: the rest of the arguments are parameter name and override value pairs for the new alert spec +# +function create_alert_spec() { + local template_name="$1" + local name="$template_name $2" + shift 2 # remove the first two arguments from $@ + echo -n "creating alert spec '$name' from '${template_name}': " + if [[ $# -ne 0 ]]; then + echo -n 'overriding ' + local -i index=0 + for override in "$@"; do + if [[ $(((index += 1) % 2)) -eq 1 ]]; then + echo -n "$override=" + else + echo -n "'$override' " + fi + done + echo -n '... ' + fi + + # check in the alert specs to see if the one we want to create is already created + if rsc json --x1 "object:has(.name:val(\"$name\"))" <<<"$alert_specs" 1>/dev/null 2>&1; then + echo 'already exists' + return + fi + + # create an associative array of the parameters with our new name and all of the other parameters from the template + # alert spec + local -A parameters=([name]="$name") + for parameter in condition description duration escalation_name file threshold variable vote_tag vote_type; do + value=`rsc json --x1 "object:has(.name:val(\"$template_name\")).$parameter" <<<"$alert_specs" 2>/dev/null || true` + if [[ -n "$value" ]]; then + parameters[$parameter]="$value" + fi + done + + # iterate through the rest of the arguments to override any parameters + while [[ $# -gt 0 ]]; do + local parameter="$1" + local value="$2" + parameters[$parameter]="$value" + shift 2 # remove these two arguments from $@ + done + + # transform the associative array of parameters into an array of arguments for rsc + local -a arguments + for parameter in "${!parameters[@]}"; do + arguments[${#arguments[@]}]="alert_spec[$parameter]=${parameters[$parameter]}" + done + + # use rsc to create the new alert spec with the parameters as arguments + rsc --rl10 cm15 create "$RS_SELF_HREF/alert_specs" "${arguments[@]}" + echo 'created' +} + +# Destroy an alert if the matching alert spec is defined on the ServerTemplate or destroy an alert spec if it is defined +# on the instance. No action will be taken if the alert or alert spec has already been destroyed or does not otherwise +# exist. +# +# $1: the name of the alert spec to destroy the alert for or to just destroy +# +function destroy_alert_or_alert_spec() { + local name="$1" + echo -n "destroying alert or alert spec '$name' from instance: ... " + + # check if the alert or alert spec has already been destroyed + if ! alert_for_alert_spec_exists "$name"; then + echo 'already destroyed' + return + fi + + # destroy the alert if the alert spec is inherited from the ServerTemplate or delete the alert spec otherwise + if [[ $subject_href =~ ^/api/server_templates/[^/]+$ ]]; then + alert_href=`rsc json --xj "object:has(.href:val(\"$alert_spec_href\")) ~ object" <<<"$alerts" | rsc json --x1 'object:has(.rel:val("self")).href'` + rsc --rl10 cm15 destroy "$alert_href" + else + rsc --rl10 cm15 destroy "$alert_spec_href" + fi + + echo 'destroyed' +} + +# Check if an alert for an alert spec exists on the instance. +# +# $1: the name of the alert spec to check for +# +# Output variables: +# +# alert_spec_href: the HREF of the named alert spec +# subject_href: the HREF of the subject of the named alert spec +# +function alert_for_alert_spec_exists() { + local name="$1" + + # get the alert spec and subject HREFs for the named alert spec + alert_spec_href=`rsc json --x1 "object:has(.name:val(\"$name\")) object:has(.rel:val(\"self\")).href" <<<"$alert_specs" 2>/dev/null` + subject_href=`rsc json --x1 "object:has(.name:val(\"$name\")) object:has(.rel:val(\"subject\")).href" <<<"$alert_specs" 2>/dev/null` + + # check if the alert spec HREF was found + if [[ -n $alert_spec_href ]]; then + if [[ $subject_href =~ ^/api/server_templates/[^/]+$ ]]; then + # the subject of the alert spec is a ServerTemplate so the alert spec is inherited + # check if there is an alert for the alert spec + if rsc json --x1 "object:has(.href:val(\"$alert_spec_href\"))" <<<"$alerts" 1>/dev/null 2>&1; then + # an alert for the alert spec exists + return 0 + else + # there is no alert for the alert spec + return 1 + fi + else + # the alert spec is not inherited from the ServerTemplate and it exists so it definitely exists + return 0 + fi + else + # there was no alert spec HREF found so the named alert spec does not exist + return 1 + fi +} + +# Ensure rsc is in the path +export PATH="/usr/local/bin:/opt/bin:$PATH" + +# Determine what mode to use if MONITORING_METHOD is set to 'auto' +if [[ "$MONITORING_METHOD" == "auto" ]]; then + # Currently, the only criteria to automatically use RightLink monitoring is if OS is CoreOS + if grep -iq "id=coreos" /etc/os-release 2> /dev/null; then + monitoring_method="rightlink" + else + monitoring_method="collectd" + fi +else + monitoring_method=$MONITORING_METHOD +fi + +# Determine which network interfaces exist excluding lo so we can update alert specs +interfaces=(`ip -o link | awk '{ sub(/:$/, "", $2); if ($2 != "lo") { print $2; } }'`) + +# Determine if swap is enabled +if [[ $(sudo swapon -s | wc -l) -gt 1 ]]; then + swap=1 +else + swap=0 +fi + +# get all of the alert specs and alerts defined on the instance; these variables are used with rsc json by the above +# functions instead of making individual API calls to query this data +alert_specs=`rsc --rl10 cm15 index "$RS_SELF_HREF/alert_specs" with_inherited=true` +[[ -z "$alert_specs" ]] && alert_specs='{}' +alerts=`rsc --rl10 cm15 index "$RS_SELF_HREF/alerts"` +[[ -z "$alerts" ]] && alerts='{}' + +if [[ $swap -eq 0 ]]; then + # if swap is not enabled, remove the swap alert + destroy_alert_or_alert_spec 'rs low swap space' + destroy_alert_or_alert_spec 'rs low swap space recreated' +else + # if swap was previously disabled, recreate the alert now that it is enabled + if ! alert_for_alert_spec_exists 'rs low swap space' && ! alert_for_alert_spec_exists 'rs low swap space recreated'; then + create_alert_spec 'rs low swap space' recreated + fi +fi + +disable_eth0=1 # by default remove the original network alert specs +reenable_eth0=0 # by default do not create new network alert specs for eth0 +interface_file='interface-eth0/if_octets' # this is the format for the network metric for collectd 5 and built-in + +if [[ $monitoring_method == collectd && "$(collectd -h)" =~ "collectd 4" ]]; then + # change the root partition alert to use the collectd4 metric + destroy_alert_or_alert_spec 'rs low space in root partition' + create_alert_spec 'rs low space in root partition' 'collectd4' file df/df-root variable free + + reenable_eth0=1 # since the metric for interfaces is different on collectd 4, the alert specs needs to be redefined + interface_file='interface/if_octets-eth0' # this is the format for the network metric for collectd 4 +fi + +for interface in "${interfaces[@]}"; do + # if the interface is eth0 and the network does not need to be redefined, do not create a new alert spec + if [[ "$interface" == eth0 && $reenable_eth0 -eq 0 ]]; then + echo -e "keeping 'rs high network tx activity'\nkeeping 'rs high network rx activity'" + disable_eth0=0 # since the eth0 interface exists do not remove the original network alerts + continue + fi + + # add network alert specs for this network interface by replacing eth0 in the network metric format with the actual + # interface name + create_alert_spec 'rs high network tx activity' "$interface" file "${interface_file/eth0/$interface}" + create_alert_spec 'rs high network rx activity' "$interface" file "${interface_file/eth0/$interface}" +done + +# if there is no eth0 interface or the network alerts needed to be redefined for collectd 4, remove the original alerts +if [[ disable_eth0 -eq 1 ]]; then + destroy_alert_or_alert_spec 'rs high network tx activity' + destroy_alert_or_alert_spec 'rs high network rx activity' +fi diff --git a/jenkins/RL10_Linux_Setup_Automatic_Upgrade.sh b/jenkins/RL10_Linux_Setup_Automatic_Upgrade.sh new file mode 100755 index 0000000..b0c69cb --- /dev/null +++ b/jenkins/RL10_Linux_Setup_Automatic_Upgrade.sh @@ -0,0 +1,119 @@ +#! /bin/bash -e + +# --- +# RightScript Name: RL10 Linux Setup Automatic Upgrade +# Description: Subscribes to receive updates to the RightLink agent automatically. Creates +# a cron job that performs a daily check to see if an upgrade to RightLink is available +# and upgrades if there is. +# Inputs: +# ENABLE_AUTO_UPGRADE: +# Category: RightScale +# Description: Enables or disables automatic upgrade of RightLink10. +# Input Type: single +# Required: false +# Advanced: true +# Default: text:true +# Possible Values: +# - text:true +# - text:false +# UPGRADES_FILE_LOCATION: +# Category: RightScale +# Description: External location of 'upgrades' file +# Input Type: single +# Required: false +# Advanced: true +# Default: text:https://rightlink.rightscale.com/rightlink/upgrades +# Attachments: [] +# ... +# + +# Determine directory location of rightlink / rsc +[[ -e /usr/local/bin/rsc ]] && bin_dir=/usr/local/bin || bin_dir=/opt/bin +rsc=${bin_dir}/rsc + +# Will compare current version of rightlink 'running' with latest version provided from 'upgrades' +# file. If they differ, will update to latest version. Note that latest version can be an older version +# if a downgrade is best as found in the $UPGRADES_FILE_LOCATION +UPGRADES_FILE_LOCATION=${UPGRADES_FILE_LOCATION:-"https://rightlink.rightscale.com/rightlink/upgrades"} + +# Add entry in /etc/cron.d/ to check and execute an upgrade for rightlink daily. +cron_file='/etc/cron.d/rightlink-upgrade' +exec_file="${bin_dir}/rightlink_check_upgrade" +# Add entry in /etc/systemd/system if system doesn't support cron +service_file='/etc/systemd/system/rightlink-upgrade.service' +timer_file='/etc/systemd/system/rightlink-upgrade.timer' + +# Grab toggle option to enable +if [[ "$ENABLE_AUTO_UPGRADE" == "false" ]]; then + if [[ -e $exec_file ]]; then + sudo rm -f ${timer_file} ${cron_file} ${exec_file} ${service_file} + echo "Automatic upgrade disabled." + else + echo "Automatic upgrade never enabled - no action done" + fi +else + # If cron file already exists, will recreate it and update cron config with new random times. + scheduled_hour=$(( $RANDOM % 24 )) + scheduled_minute=$(( $RANDOM % 60 )) + + # Generate executable script to run by cron + sudo dd of="${exec_file}" 2>/dev/null </dev/null) =~ CoreOS ]]; then + # Generate service file to be executed by systemd timers + sudo dd of="${service_file}" 2>/dev/null </dev/null < ${cron_file}" + + # Set perms regardless of umask since the file could be overwritten with existing perms. + sudo chmod 0600 ${cron_file} + echo "Configured cron file at ${cron_file} to run daily." + fi + + echo "Subscribed to receive upgrades from ${UPGRADES_FILE_LOCATION}." + echo "Automatic upgrade enabled." +fi diff --git a/jenkins/RL10_Linux_Setup_Hostname.sh b/jenkins/RL10_Linux_Setup_Hostname.sh new file mode 100755 index 0000000..9d9d372 --- /dev/null +++ b/jenkins/RL10_Linux_Setup_Hostname.sh @@ -0,0 +1,181 @@ +#! /bin/bash -e + +# --- +# RightScript Name: RL10 Linux Setup Hostname +# Description: | +# Changes the hostname of the server. +# +# ## Known Limitations: +# On AzureRM, the Azure Linux Agent (waagent) may change the hostname if it has not finished provisioning the server after boot. +# Inputs: +# SERVER_HOSTNAME: +# Category: RightScale +# Description: The server's hostname is set to the longest valid prefix or suffix +# of this variable. E.g. 'my.example.com V2', 'NEW my.example.com', and 'database.io +# my.example.com' all set the hostname to 'my.example.com'. Set to an empty string +# to avoid any change to the hostname. +# Input Type: single +# Required: false +# Advanced: true +# Default: blank +# Attachments: [] +# ... +# + +# The server's hostname is set to the longest valid prefix or suffix of +# this SERVER_HOSTNAME variable eg 'my.example.com V2', 'NEW my.example.com', and +# 'database.io my.example.com' all set the hostname to 'my.example.com'. +# If SERVER_HOSTNAME is empty, will maintain current hostname. + +# Run passed-in command with retries if errors occur. +# +# $@: full line command +# +function retry_command() { + # Setting config variables for this function + retries=5 + wait_time=10 + + while [ $retries -gt 0 ]; do + # Reset this variable before every iteration to be checked if changed + issue_running_command=false + $@ || { issue_running_command=true; } + if [ "$issue_running_command" = true ]; then + (( retries-- )) + echo "Error occurred - will retry shortly" + sleep $wait_time + else + # Break out of loop since command was successful. + break + fi + done + + # Check if issue running command still existed after all retries + if [ "$issue_running_command" = true ]; then + echo "ERROR: Unable to run: '$@'" + return 1 + fi +} + +# Ensure rsc is in the path +export PATH="/usr/local/bin:/opt/bin:$PATH" + +# Give warning about the possibility of waagent on AzureRM changing the hostname again after this script +current_cloud_href=$(rsc --retry=5 --timeout=60 --rl10 cm15 index_instance_session /api/sessions/instance --x1 ':has(.rel:val("cloud")).href' 2>/dev/null || true) +cloud_type=$(rsc --retry=5 --timeout=60 --rl10 cm15 --x1='.cloud_type' show $current_cloud_href 2>/dev/null || true) +if [[ $cloud_type == "azure_v2" ]]; then + echo "WARNING: waagent on AzureRM may change the hostname after this script is completed!" + echo "See http://docs.rightscale.com/clouds/azure_resource_manager/reference/limitations.html#azure-linux-agent for more details" +fi + +if [[ -n "$SERVER_HOSTNAME" ]]; then + prefix= + suffix= + + re='^[-A-Za-z0-9_][-A-Za-z0-9_.]*[-A-Za-z0-9_]( #[0-9]+){0,1}' + if [[ "$SERVER_HOSTNAME" =~ $re ]]; then + prefix=${BASH_REMATCH[0]} + echo "prefix set to ${prefix}" + fi + + re='[-A-Za-z0-9_][-A-Za-z0-9._]*[-A-Za-z0-9_]( #[0-9]+){0,1}$' + if [[ "$SERVER_HOSTNAME" =~ $re ]]; then + suffix=${BASH_REMATCH[0]} + echo "suffix set to ${suffix}" + fi + + if (( ${#prefix} >= ${#suffix} && ${#prefix} > 1 )); then + echo "Setting hostname to prefix '$prefix'" + hostname="$prefix" + elif (( ${#suffix} > 1 )); then + echo "Setting hostname to suffix '$suffix'" + hostname="$suffix" + fi + + # + # Check for a numeric suffix (like in a server array) + # example: array_name #1 + # and convert into: array_name-1 + # + if [ $( echo $hostname | grep "#" -c ) -gt 0 ]; then + numeric_suffix=$( echo $hostname | cut -d'#' -f2 ) + hostname=$( echo $hostname | cut -d'#' -f1 ) + echo "Find array numeric suffix '$numeric_suffix'" + + sname=$(echo $hostname | cut -d'.' -f 1) + dname=${hostname#"$sname"} + hostname="$sname-$numeric_suffix$dname" + fi + + # Set the hostname and make it persist across reboots, etc. + # If we are on a system with hostnamectl, it will take care of all that, but if not there are several ways that the + # hostname may be stored. + if type -P hostnamectl >/dev/null; then + # even if hostnamectl is available, dbus might not be available so we install it + if ! type -P dbus-daemon >/dev/null; then + # Read/source os-release to obtain variable values determining OS + if [[ -e /etc/os-release ]]; then + source /etc/os-release + else + # CentOS/RHEL 6 does not use os-release, so use redhat-release + if [[ -e /etc/redhat-release ]]; then + # Assumed format example: CentOS release 6.7 (Final) + ID=$(cut -d" " -f1 /etc/redhat-release) + VERSION_ID=$(cut -d" " -f3 /etc/redhat-release) + else + echo "ERROR: /etc/os-release or /etc/redhat-release is required but does not exist" + exit 1 + fi + fi + + case "${ID,,}" in + ubuntu|debian) + retry_command sudo apt-get update + retry_command sudo apt-get install -y dbus + ;; + centos|fedora|rhel) + retry_command sudo yum install -y dbus + sudo chkconfig dbus on + sudo service dbus start + ;; + esac + fi + + # CentOS 7, CoreOS, and Ubuntu 14+ all use hostnamectl! + sudo hostnamectl set-hostname "$hostname" + else + if [[ -f /etc/sysconfig/network ]]; then + # CentOS 6 (and probably RHEL 6 as well) uses the /etc/sysconfig/network file to store the hostname + if grep --quiet '^HOSTNAME=' /etc/sysconfig/network; then + sudo sed --expression="s/^HOSTNAME=.*$/HOSTNAME=$hostname/" --in-place /etc/sysconfig/network + else + echo "HOSTNAME=$hostname" | sudo tee -a /etc/sysconfig/network + fi + else + # Ubuntu 12 uses /etc/hostname to store the hostname + echo "$hostname" | sudo tee /etc/hostname + fi + sudo hostname "$hostname" + fi + + # At least on CentOS 7, cloud-init can sometimes also try to manage the hostname, so configure cloud-init to not + # change the hostname + preserve_hostname='preserve_hostname: true' + if [[ -d /etc/cloud/cloud.cfg.d ]]; then + echo "$preserve_hostname" | sudo tee /etc/cloud/cloud.cfg.d/99_preserve_hostname.cfg + elif [[ -f /etc/cloud/cloud.cfg ]] && ! grep --quiet "$preserve_hostname" /etc/cloud/cloud.cfg; then + echo "$preserve_hostname" | sudo tee -a /etc/cloud/cloud.cfg + fi +fi + +# This works around spurious warnings generated by sudo if the hostname can't resolve. +# /etc/sudoers is designed to be able to be distributed among multiple servers. +# Each permission in the /etc/sudoers has a host portion. Sudo does a hostname +# lookup to enforce the host portion, and will throw a warning if it can't +# resolve the hostname in some way. + +hostname=$(hostname) +if ! grep "$hostname" /etc/hosts >/dev/null 2>&1; then + echo "Adding $hostname to /etc/hosts" + echo "127.0.0.1 $hostname" | sudo tee -a /etc/hosts +fi diff --git a/jenkins/RL10_Linux_Shutdown_Reason.sh b/jenkins/RL10_Linux_Shutdown_Reason.sh new file mode 100755 index 0000000..04b4679 --- /dev/null +++ b/jenkins/RL10_Linux_Shutdown_Reason.sh @@ -0,0 +1,73 @@ +#! /bin/bash + +# --- +# RightScript Name: RL10 Linux Shutdown Reason +# Description: Print out the reason for shutdown. +# Inputs: {} +# Attachments: [] +# ... +# + +# We pull the runlevel or equivalent from the init system and call it +# os_decom_reason. os_decom_reason possible values are: +# shutdown = system is halting, powering off, or going into single user mode +# reboot = system is rebooting +# service_restart = service was restarted +# +# We pull the reason RightScale thinks the instance is going down and put it in +# rs_decom_reason. Note that this variable will only be populated if we issue a +# stop/terminate/reboot from either the RightScale dashboard or the API. It will +# be empty if we shutdown or rebooted at the command line, or if a shutdown/reboot +# was issued on the cloud provider's console. Note we can't tell if a terminate +# was issued on a cloud provider's console, as we just know the system is going +# down. rs_decom_reason possible values are: +# stop = instance is being stopped/shutdown but disk persists +# terminate = instance is being destroyed/deleted +# reboot = instance is being rebooted +# +# DECOM_REASON synthesizes the two values. We export this value as an environment +# parameter so subsequent scripts in the decommission bundle may have use it. The +# following values are possible: +# stop +# terminate +# reboot +# service_restart + +# Determine location of rsc +[[ -e /usr/local/bin/rsc ]] && rsc=/usr/local/bin/rsc || rsc=/opt/bin/rsc + +echo "Decommissioning. Calculating reason for decommission: " + +rs_decom_reason="$($rsc --retry=5 --timeout=10 rl10 show /rll/proc/shutdown_kind)" +os_decom_reason=service_restart # Our default +if [[ `systemctl 2>/dev/null` =~ -\.mount ]] || [[ "$(readlink /sbin/init)" =~ systemd ]]; then + # Systemd doesn't use runlevels, so we can't rely on that + jobs="$(systemctl list-jobs)" + echo "$jobs" | egrep -q 'reboot.target.*start' && os_decom_reason=reboot + echo "$jobs" | egrep -q 'halt.target.*start' && os_decom_reason=shutdown + echo "$jobs" | egrep -q 'poweroff.target.*start' && os_decom_reason=shutdown +else + # upstart, sysvinit, or unknown system. The current runlevel should tell us what's up + [[ `runlevel | cut -d ' ' -f 2` == "6" ]] && os_decom_reason=reboot + [[ `runlevel | cut -d ' ' -f 2` =~ 0|1|S ]] && os_decom_reason=shutdown +fi + +case "$os_decom_reason" in +reboot|service_restart) + decom_reason=$os_decom_reason + ;; +shutdown) + if [[ "$rs_decom_reason" == "terminate" ]]; then + decom_reason=terminate + else + decom_reason=stop + fi + ;; +esac + +echo " OS decommission reason is: $os_decom_reason" +echo " RightScale decommission reason is: $rs_decom_reason" +echo " Combined DECOM_REASON is: $decom_reason" +echo "" +echo "exporting DECOM_REASON=$decom_reason into the environment for subsequent scripts" +$rsc --retry=5 --timeout=10 rl10 update /rll/env/DECOM_REASON payload=$decom_reason diff --git a/jenkins/RL10_Linux_Upgrade.sh b/jenkins/RL10_Linux_Upgrade.sh new file mode 100755 index 0000000..e0c934f --- /dev/null +++ b/jenkins/RL10_Linux_Upgrade.sh @@ -0,0 +1,155 @@ +#! /bin/bash -e + +# --- +# RightScript Name: RL10 Linux Upgrade +# Description: Check whether a RightLink upgrade is available and perform the upgrade. +# Inputs: +# UPGRADE_VERSION: +# Category: RightScale +# Description: The new version of RightLink to upgrade to. +# Input Type: single +# Required: true +# Advanced: true +# Default: blank +# Attachments: [] +# ... +# + +# Determine directory location of rightlink / rsc +[[ -e /usr/local/bin/rightlink ]] && bin_dir=/usr/local/bin || bin_dir=/opt/bin + +# Determine if the version of rsc supports retry. The upgrades script can be called +# as an any script and RL may have an older rsc bundled with it. +rsc=${bin_dir}/rsc +[[ $(${bin_dir}/rsc --help | grep retry) ]] && rsc="$rsc --retry=5 --timeout=10" + +upgrade_rightlink() { + sleep 1 + # Use 'logger' here instead of 'echo' since stdout from this is not sent to + # audit entries as RightLink is down for a short time during the upgrade process. + + res=$(${bin_dir}/rsc rl10 upgrade /rll/upgrade exec=${bin_dir}/rightlink-new 2>/dev/null || true) + if [[ "$res" =~ successful ]]; then + # Delete the old version if it exists from the last upgrade. + sudo rm -rf ${bin_dir}/rightlink-old + # Keep the old version in case of issues, ie we need to manually revert back. + sudo mv ${bin_dir}/rightlink ${bin_dir}/rightlink-old + sudo cp ${bin_dir}/rightlink-new ${bin_dir}/rightlink + logger -t rightlink "rightlink updated" + else + logger -t rightlink "Error: ${res}" + exit 1 + fi + + # Check updated version in production by connecting to local proxy + # The update takes a few seconds so retries are done. + for retry_counter in {1..5}; do + new_installed_version=$($rsc rl10 show /rll/proc/version 2>/dev/null || true) + if [[ "$new_installed_version" == "$UPGRADE_VERSION" ]]; then + logger -t rightlink "New version active - ${new_installed_version}" + break + else + logger -t rightlink "Waiting for new version to become active." + sleep 5 + fi + done + if [[ "$new_installed_version" != "$UPGRADE_VERSION" ]]; then + logger -t rightlink "New version does not appear to be desired version: ${new_installed_version}" + exit 1 + fi + + # Report to audit entry that RightLink was upgraded. + for retry_counter in {1..5}; do + instance_href=$($rsc --rl10 --x1 ':has(.rel:val("self")).href' cm15 index_instance_session /api/sessions/instance || true) + if [[ -n "$instance_href" ]]; then + logger -t rightlink "Instance href found: ${instance_href}" + break + else + logger -t rightlink "Instance href not found, retrying" + sleep 5 + fi + done + + if [[ -n "$instance_href" ]]; then + audit_entry_href=$($rsc --rl10 --xh 'location' cm15 create /api/audit_entries "audit_entry[auditee_href]=${instance_href}" \ + "audit_entry[detail]=RightLink updated to '${new_installed_version}'" "audit_entry[summary]=RightLink updated" 2>/dev/null) + if [[ -n "$audit_entry_href" ]]; then + logger -t rightlink "audit entry created at ${audit_entry_href}" + else + logger -t rightlink "failed to create audit entry" + fi + else + logger -t rightlink "unable to obtain instance href for audit entries" + fi + + # Update RSC after RightLink has successfully updated. + if [[ -x ${bin_dir}/rsc ]]; then + sudo mv ${bin_dir}/rsc ${bin_dir}/rsc-old + fi + sudo mv /tmp/rightlink/rsc ${bin_dir}/rsc + # If new RSC is correctly installed then remove the old version + if [[ -x ${bin_dir}/rsc ]]; then + sudo rm -rf ${bin_dir}/rsc-old + else + logger -t rightlink "failed to update to new version of RSC" + sudo mv ${bin_dir}/rsc-old ${bin_dir}/rsc + fi + exit 0 +} + +# Determine current version of rightlink +current_version=$($rsc rl10 show /rll/proc/version) + +if [[ -z "$current_version" ]]; then + echo "Can't determine current version of RightLink" + exit 1 +fi + +if [[ -z "$UPGRADE_VERSION" ]]; then + echo "No upgrade version supplied" + exit 1 +fi + +if [[ "$UPGRADE_VERSION" == "$current_version" ]]; then + echo "RightLink is already up-to-date (current=${current_version})" + exit 0 +fi + +echo "RightLink updating:" +echo " from current=${current_version}" +echo " to desired=${UPGRADE_VERSION}" + +echo "downloading RightLink version '${UPGRADE_VERSION}'" + +# Download new version +cd /tmp +sudo rm -rf rightlink rightlink.tgz +curl --silent --show-error --retry 3 --output rightlink.tgz https://rightlink.rightscale.com/rll/${UPGRADE_VERSION}/rightlink.tgz +tar zxf rightlink.tgz || (cat rightlink.tgz; exit 1) + +# Check downloaded version +sudo mv rightlink/rightlink ${bin_dir}/rightlink-new +echo "checking new version" +new=`${bin_dir}/rightlink-new --version | awk '{print $2}'` +if [[ "$new" == "$UPGRADE_VERSION" ]]; then + echo "new version looks right: ${new}" + + # We pre-run the self-check now so we can fail fast. + . <(sudo sed '/^export/!s/^/export /' /var/lib/rightscale-identity) + self_check_output=$(${bin_dir}/rightlink-new --selfcheck 2>&1) + if [[ "$self_check_output" =~ "Self-check succeeded" ]]; then + echo "new version passed connectivity check" + else + echo "initial self-check failed:" + echo "$self_check_output" + exit 1 + fi + + echo "restarting RightLink to pick up new version" + # Fork a new task since this main process is started + # by RightLink and we are restarting it. + upgrade_rightlink & +else + echo "Updated version does not appear to be desired version: ${new}" + exit 1 +fi diff --git a/jenkins/RL5_6_10_Setup_Custom_Logrotate_Configs.sh b/jenkins/RL5_6_10_Setup_Custom_Logrotate_Configs.sh new file mode 100755 index 0000000..c091364 --- /dev/null +++ b/jenkins/RL5_6_10_Setup_Custom_Logrotate_Configs.sh @@ -0,0 +1,75 @@ +#!/bin/bash -ex +# --- +# RightScript Name: RL5/6/10 Setup Custom Logrotate Configs +# Inputs: +# CONFIGS: +# Category: Logging +# Description: Space separated list of configurations to download from attachments. +# Input Type: single +# Required: true +# Advanced: false +# Default: text:chef +# Attachments: +# - chef +# ... +# RL5/6/10 Setup Custom Logrotate Configs +# This script will copy the custom logrotate configs [attached to this RightScript] and change logrotate to run hourly versus daily. It's currently designed for Ubuntu 12, but shouldn't require much modification for newer versions of Ubuntu or even CentOS as logrotate hasn't changed much recently. +# +# Written by: Bryan Karaffa [bryan.karaffa@rightscale.com] + + +# Operational Code +# This is where you put the steps for install for each version of RightLink. + +# RL5 and RL6 share the same limitation. Use the same code for both versions. +do_RL56 () { + echo "Executed do_RL56()" + # List Contents of attachments + ls -al $RS_ATTACH_DIR/ + # Copy attachments containing custom logrotate configs + for f in $CONFIGS; do + cp -rf $RS_ATTACH_DIR/$f /etc/logrotate.d/ + done + # Set Logrotate to run hourly versus daily + if [ ! -f /etc/cron.hourly/logrotate ]; then cp -rf /etc/cron.daily/logrotate /etc/cron.hourly/logrotate; chmod +x /etc/cron.hourly/logrotate; fi + # List Current Logrotate Config Files + ls -al /etc/logrotate.d/ +} + +do_RL10 () { + echo "Executed do_RL10()" + # List Contents of attachments + ls -al $RS_ATTACH_DIR/ + # Copy attachments containing custom logrotate configs + for f in $CONFIGS; do + sudo cp -rf $RS_ATTACH_DIR/$f /etc/logrotate.d/ + done +# Cleanup the RightScript that may accidently get copied + if [ -f /etc/logrotate.d/__script-0 ]; then sudo rm -f /etc/logrotate.d/__script-0; fi + # Set Logrotate to run hourly versus daily + if [ ! -f /etc/cron.hourly/logrotate ]; then sudo cp -rf /etc/cron.daily/logrotate /etc/cron.hourly/logrotate; sudo chmod +x /etc/cron.hourly/logrotate; fi + # List Current Logrotate Config Files + ls -al /etc/logrotate.d/ +} + + + +# Get the RightLink Version +if [ -f /etc/rightscale.d/rightscale-release ]; then + + if grep -q '6.*.*' /etc/rightscale.d/rightscale-release; then rightlink_version=6; + elif grep -q '5.*.*' /etc/rightscale.d/rightscale-release; then rightlink_version=5; + fi +elif [ -f /var/lib/rightscale-identity ]; then rightlink_version=10; +else + echo "RightLink version could not be identified or is older than version 5." + exit 1 +fi +echo "This instance is running RightLink Version $rightlink_version" + +# Run the function associated with the version of RightLink that is installed. +case $rightlink_version in + 5) do_RL56;; + 6) do_RL56;; + 10) do_RL10;; +esac diff --git a/jenkins/Update_R53_A_Record.sh b/jenkins/Update_R53_A_Record.sh new file mode 100755 index 0000000..f72def8 --- /dev/null +++ b/jenkins/Update_R53_A_Record.sh @@ -0,0 +1,65 @@ +#! /usr/bin/sudo /bin/bash +# --- +# RightScript Name: Update R53 A Record +# Description: Updates an R53 A record +# Inputs: +# R53_HOSTED_ZONE_ID: +# Category: R53 +# Description: Hosted Zone ID +# Input Type: single +# Required: true +# Advanced: false +# R53_TTL: +# Category: R53 +# Description: A record TTL +# Input Type: single +# Required: true +# Advanced: true +# Default: text:60 +# FQDN: +# Category: R53 +# Description: FQDN of the instance. (e.g. myserver.example.tld) +# Input Type: single +# Required: true +# Advanced: false +# IPADDRESS: +# Category: R53 +# Description: IP Address of the instance. +# Input Type: single +# Required: true +# Advanced: true +# Default: env:PRIVATE_IP +# Attachments: [] +# ... +echo "Installing awscli" +apt-get install -y awscli + +cat << EOF > /tmp/r53.json +{ + "Comment": "optional comment about the changes in this change batch request", + "Changes": [ + { + "Action": "UPSERT", + "ResourceRecordSet": { + "Name": "$FQDN", + "Type": "A", + "TTL": $R53_TTL, + "ResourceRecords": [ + { + "Value": "$IPADDRESS" + } + ] + } + } + ] +} +EOF + +aws route53 --region us-west-2 change-resource-record-sets --hosted-zone-id $R53_HOSTED_ZONE_ID --change-batch file:///tmp/r53.json +if [ $? -eq 0 ]; then + echo "$FQDN A record set to $IPADDRESS" +else + echo "Error setting $FQDN" + exit 1 +fi +rm -rf /tmp/r53.json diff --git a/jenkins/attachments/chef b/jenkins/attachments/chef new file mode 100644 index 0000000..4ffa342 --- /dev/null +++ b/jenkins/attachments/chef @@ -0,0 +1,8 @@ +/var/log/chef.log { + rotate 14 + daily + size 256M + compress + missingok + notifempty +} diff --git a/jenkins/attachments/libnss_rightscale.tgz b/jenkins/attachments/libnss_rightscale.tgz new file mode 100644 index 0000000000000000000000000000000000000000..fdf5d5c45923ed0a8ac2cde1f8ed6520d65cd243 GIT binary patch literal 18799 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 MAM|dYTmbL@0J;sy6#xJL literal 0 HcmV?d00001 diff --git a/jenkins/attachments/rightscale_login_policy.te b/jenkins/attachments/rightscale_login_policy.te new file mode 100644 index 0000000..66e4021 --- /dev/null +++ b/jenkins/attachments/rightscale_login_policy.te @@ -0,0 +1,18 @@ +module rightscale_login_policy 1.0; + +require { + type sshd_t; + type var_lib_t; + type chkpwd_t; + type unconfined_t; + type oddjob_mkhomedir_exec_t; + class file { open read entrypoint ioctl getattr }; +} + +#============= sshd_t ============== +allow sshd_t var_lib_t:file { ioctl open read getattr }; +allow chkpwd_t var_lib_t:file { ioctl open read getattr }; + + +#============= unconfined_t ============== +allow unconfined_t oddjob_mkhomedir_exec_t:file entrypoint; diff --git a/jenkins/attachments/rs-ssh-keys.sh b/jenkins/attachments/rs-ssh-keys.sh new file mode 100644 index 0000000..2b1cf53 --- /dev/null +++ b/jenkins/attachments/rs-ssh-keys.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# +# rs-ssh-keys.sh - tool to obtain users' ssh public keys from the RightScale policy file. +# + +set -e + +# Check that username is provided +if [ $# -eq 0 ]; then + logger -i -p auth.warn -t rs-ssh-keys.sh "username was not provided and is required" + exit 1 +fi +username=$1 + +# Grab username info from policy file and exit if it does not exist +policy_username_entry=`grep -E "^$username:|^[0-9a-z_\-]*:$username:" /var/lib/rightlink/login_policy` || true +if [[ "$policy_username_entry" == "" ]]; then + # Not in policy file + exit 0 +fi +read preferred_name unique_name policy_uid <<< $(echo $policy_username_entry | cut -d: -f1,2,4 --output-delimiter=' ') + +# Grab username info from system +system_username_entry=`getent passwd ${username}` || true +if [[ "$system_username_entry" == "" ]]; then + # At this point, user from policy file should be returned. If nothing or error is returned, exit 1 with no keys. + logger -i -p auth.warn -t rs-ssh-keys.sh "issue searching for username: ${username}" + exit 1 +fi +read system_uid <<< $(echo $system_username_entry | cut -d: -f3 --output-delimiter=' ') + +# Determine if the entry found has matching system UID. +# If there is another user from another NSS plugin, this is not our user, so return no keys. +if [[ "$system_uid" == "$policy_uid" ]]; then + # User is from policy file so get and set keys + logger -i -p auth.info -t rs-ssh-keys.sh "username '${username}' matches entry in login policy - sending keys" + echo $policy_username_entry | cut -d: -f7- | tr : "\n" +else + logger -i -p auth.warn -t rs-ssh-keys.sh "username '${username}' matches another NSS method - not using login policy keys" +fi diff --git a/jenkins/attachments/rsc_jenkins-201704183.tar b/jenkins/attachments/rsc_jenkins-201704183.tar new file mode 100644 index 0000000000000000000000000000000000000000..ec059ff06224fbb5ae72925ba3c99b18167319a5 GIT binary patch literal 256000 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 IFHM2}07*uu`~Uy| literal 0 HcmV?d00001 From 5581394308642091bf0b3d20b68db830fce05843 Mon Sep 17 00:00:00 2001 From: Stefhen Hovland Date: Thu, 27 Apr 2017 15:37:21 -0400 Subject: [PATCH 02/13] Add Storage Toolbox support --- .../Jenkins-Chef_Solo_RightLink_10_6_0.yml | 5 + jenkins/RL10_Jenkins_Install_Master.sh | 2 +- jenkins/RL10_Jenkins_Install_Slave.sh | 2 +- jenkins/Storage_Toolbox_Backup-chef.sh | 162 ++++++++++++++ jenkins/Storage_Toolbox_Decommission-chef.sh | 92 ++++++++ jenkins/Storage_Toolbox_Schedule-chef.sh | 125 +++++++++++ jenkins/Storage_Toolbox_Stripe-chef.sh | 205 ++++++++++++++++++ jenkins/Storage_Toolbox_Volume-chef.sh | 197 +++++++++++++++++ ...69f08f87743e072eba619a3fba6a9c9dd6bc89.tar | Bin 0 -> 112640 bytes 9 files changed, 788 insertions(+), 2 deletions(-) create mode 100755 jenkins/Storage_Toolbox_Backup-chef.sh create mode 100755 jenkins/Storage_Toolbox_Decommission-chef.sh create mode 100755 jenkins/Storage_Toolbox_Schedule-chef.sh create mode 100755 jenkins/Storage_Toolbox_Stripe-chef.sh create mode 100755 jenkins/Storage_Toolbox_Volume-chef.sh create mode 100644 jenkins/attachments/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar diff --git a/jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml b/jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml index 614188f..199d012 100644 --- a/jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml +++ b/jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml @@ -23,12 +23,17 @@ RightScripts: - RL5_6_10_Setup_Custom_Logrotate_Configs.sh Decommission: - RL10_Linux_Shutdown_Reason.sh + - Storage_Toolbox_Decommission-chef.sh Operational: - RL10_Jenkins_Install_Master.sh - RL10_Jenkins_Install_Slave.sh - RL10_Linux_Setup_Automatic_Upgrade.sh - RL10_Linux_Upgrade.sh - Update_R53_A_Record.sh + - Storage_Toolbox_Volume-chef.sh + - Storage_Toolbox_Schedule-chef.sh + - Storage_Toolbox_Backup-chef.sh + - Storage_Toolbox_Stripe-chef.sh MultiCloudImages: - Name: Ubuntu_14.04_x64 Revision: 70 diff --git a/jenkins/RL10_Jenkins_Install_Master.sh b/jenkins/RL10_Jenkins_Install_Master.sh index 57f771e..5c50a1a 100755 --- a/jenkins/RL10_Jenkins_Install_Master.sh +++ b/jenkins/RL10_Jenkins_Install_Master.sh @@ -41,7 +41,7 @@ set -e export LC_CTYPE=en_US.UTF-8 if [ ! -e /usr/bin/chef-client ]; then - curl -L https://www.opscode.com/chef/install.sh | sudo bash + curl -L https://www.opscode.com/chef/install.sh | sudo bash -s -- -v 12.19.36 fi chef_dir="/home/rightscale/.chef" diff --git a/jenkins/RL10_Jenkins_Install_Slave.sh b/jenkins/RL10_Jenkins_Install_Slave.sh index 072ff0a..345fdb7 100755 --- a/jenkins/RL10_Jenkins_Install_Slave.sh +++ b/jenkins/RL10_Jenkins_Install_Slave.sh @@ -187,7 +187,7 @@ set -e export LC_CTYPE=en_US.UTF-8 if [ ! -e /usr/bin/chef-client ]; then - curl -L https://www.opscode.com/chef/install.sh | sudo bash + curl -L https://www.opscode.com/chef/install.sh | sudo bash -s -- -v 12.19.36 fi chef_dir="/home/rightscale/.chef" diff --git a/jenkins/Storage_Toolbox_Backup-chef.sh b/jenkins/Storage_Toolbox_Backup-chef.sh new file mode 100755 index 0000000..77ed5ae --- /dev/null +++ b/jenkins/Storage_Toolbox_Backup-chef.sh @@ -0,0 +1,162 @@ +#! /usr/bin/sudo /bin/bash +# --- +# RightScript Name: Storage Toolbox Backup - chef +# Description: Create a backup of all volumes attached to the server +# Inputs: +# BACKUP_KEEP_DAILIES: +# Category: Storage +# Description: 'Number of daily backups to keep. Example: 14' +# Input Type: single +# Required: false +# Advanced: false +# Default: text:14 +# BACKUP_KEEP_LAST: +# Category: Storage +# Description: "Number of snapshots to keep. Example: 60\r\n" +# Input Type: single +# Required: false +# Advanced: false +# Default: text:60 +# BACKUP_KEEP_MONTHLIES: +# Category: Storage +# Description: 'Number of monthly backups to keep. Example: 12' +# Input Type: single +# Required: false +# Advanced: false +# Default: text:12 +# BACKUP_KEEP_WEEKLIES: +# Category: Storage +# Description: 'Number of weekly backups to keep. Example: 6' +# Input Type: single +# Required: false +# Advanced: false +# Default: text:14 +# BACKUP_KEEP_YEARLIES: +# Category: Storage +# Description: "Number of yearly backups to keep. Example: 2\r\n" +# Input Type: single +# Required: false +# Advanced: false +# Default: text:2 +# STOR_BACKUP_LINEAGE: +# Category: Storage +# Input Type: single +# Required: true +# Advanced: false +# DEVICE_MOUNT_POINT: +# Category: Storage +# Description: 'The mount point to mount the device on. Example: /mnt/storage' +# Input Type: single +# Required: true +# Advanced: false +# Default: text:/mnt/storage +# DEVICE_NICKNAME: +# Category: Storage +# Description: 'Nickname for the device. rs-storage::volume uses this for the filesystem +# label, which is restricted to 12 characters. If longer than 12 characters, the +# filesystem label will be set to the first 12 characters. Example: data_storage' +# Input Type: single +# Required: true +# Advanced: false +# Attachments: +# - rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar +# ... + +set -x +set -e + +# https://github.com/berkshelf/berkshelf-api/issues/112 +export LC_CTYPE=en_US.UTF-8 + +if [ ! -e /usr/bin/chef-client ]; then + curl -L https://www.opscode.com/chef/install.sh | sudo bash -s -- -v 12.19.36 +fi + +HOME=/home/rightscale +export PATH=${PATH}:/usr/local/sbin:/usr/local/bin + +/sbin/mkhomedir_helper rightlink + +export chef_dir=$HOME/.chef + +rm -rf $chef_dir +mkdir -p $chef_dir/chef-install +chmod -R 0777 $chef_dir/chef-install + +mkdir -p $chef_dir/cookbooks +chown -R 0777 $chef_dir/cookbooks + +#install packages when on ubuntu +if which apt-get >/dev/null 2>&1; then + apt-get -y update + apt-get install -y build-essential git #ruby2.0 ruby2.0-dev +fi + +#install packages for centos +if which yum >/dev/null 2>&1; then + yum groupinstall -y 'Development Tools' + yum install -y libxml2 libxml2-devel libxslt libxslt-devel git +fi + +#install berkshelf +/opt/chef/embedded/bin/gem install berkshelf -v '4.3.5' --no-ri --no-rdoc + +#checkout the chef server cookbook and install dependent cookbooks using berkshelf +cd $chef_dir + +# Download cookbooks from RS Attachments + +if [ -f $RS_ATTACH_DIR/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar ]; then + tar -xvf $RS_ATTACH_DIR/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar +fi + +/opt/chef/embedded/bin/berks vendor $chef_dir/cookbooks + +#get instance data to pass to chef server +instance_data=$(/usr/local/bin/rsc --rl10 cm15 index_instance_session /api/sessions/instance) +instance_uuid=$(echo $instance_data | /usr/local/bin/rsc --x1 '.monitoring_id' json) +instance_id=$(echo $instance_data | /usr/local/bin/rsc --x1 '.resource_uid' json) + +if [ -e $chef_dir/chef.json ]; then + rm -f $chef_dir/chef.json +fi +# add the rightscale env variables to the chef runtime attributes +# http://docs.rightscale.com/cm/ref/environment_inputs.html +cat < $chef_dir/chef.json +{ + "name": "${HOSTNAME}", + "normal": { + "tags": [] + }, + + "rightscale": { + "instance_uuid":"$instance_uuid", + "instance_id":"$instance_id" + }, + "rs-storage": { + "device": { + "mount_point":"$DEVICE_MOUNT_POINT", + "nickname":"$DEVICE_NICKNAME" + }, + "backup":{ + "lineage":"$STOR_BACKUP_LINEAGE", + "keep":{ + "dailies":"$BACKUP_KEEP_DAILIES", + "keep_last":"$BACKUP_KEEP_LAST", + "monthlies":"$BACKUP_KEEP_MONTHLIES", + "weeklies":"$BACKUP_KEEP_WEEKLIES", + "yearlies":"$BACKUP_KEEP_YEARLIES" + } + } + }, + + "run_list": ["recipe[rs-storage::backup]"] +} +EOF + +cat < $chef_dir/solo.rb +cookbook_path "$chef_dir/cookbooks" +data_bag_path "$chef_dir/data_bags" +EOF + +chef-solo -l info -L /var/log/chef.log -j $chef_dir/chef.json -c $chef_dir/solo.rb diff --git a/jenkins/Storage_Toolbox_Decommission-chef.sh b/jenkins/Storage_Toolbox_Decommission-chef.sh new file mode 100755 index 0000000..1f68b3a --- /dev/null +++ b/jenkins/Storage_Toolbox_Decommission-chef.sh @@ -0,0 +1,92 @@ +#! /usr/bin/sudo /bin/bash +# --- +# RightScript Name: Storage Toolbox Decommission - chef +# Inputs: +# DEVICE_COUNT: +# Category: Storage +# Description: "The number of devices to create and use in the Logical Volume. If +# this value is set to more than 1, it will create the specified number of devices +# and create an LVM on the devices.\r\n" +# Input Type: single +# Required: true +# Advanced: false +# DEVICE_DESTROY_ON_DECOMMISSION: +# Category: Storage +# Description: If set to true, the devices will be destroyed on decommission. +# Input Type: single +# Required: true +# Advanced: false +# Default: text:false +# Possible Values: +# - text:true +# - text:false +# DEVICE_MOUNT_POINT: +# Category: Storage +# Description: 'The mount point to mount the device on. Example: /mnt/storage' +# Input Type: single +# Required: true +# Advanced: false +# Default: text:/mnt/storage +# DEVICE_NICKNAME: +# Category: Storage +# Description: 'Nickname for the device. rs-storage::volume uses this for the filesystem +# label, which is restricted to 12 characters. If longer than 12 characters, the +# filesystem label will be set to the first 12 characters. Example: data_storage' +# Input Type: single +# Required: true +# Advanced: false +# Default: text:data_storage +# Attachments: +# - rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar +# ... + +set -e + +HOME=/home/rightscale + +sudo /sbin/mkhomedir_helper rightlink + +export chef_dir=$HOME/.chef +mkdir -p $chef_dir + +if [ -e $chef_dir/chef.json ]; then + rm -f $chef_dir/chef.json +fi + +#get instance data to pass to chef server +instance_data=$(/usr/local/bin/rsc --rl10 cm15 index_instance_session /api/sessions/instance) +instance_uuid=$(echo $instance_data | /usr/local/bin/rsc --x1 '.monitoring_id' json) +instance_id=$(echo $instance_data | /usr/local/bin/rsc --x1 '.resource_uid' json) + +if [ -e $chef_dir/chef.json ]; then + rm -f $chef_dir/chef.json +fi +# add the rightscale env variables to the chef runtime attributes +# http://docs.rightscale.com/cm/ref/environment_inputs.html +cat < $chef_dir/chef.json +{ + "name": "${HOSTNAME}", + "normal": { + "tags": [] + }, + + "rightscale": { + "instance_uuid":"$instance_uuid", + "instance_id":"$instance_id", + "decom_reason":"${DECOM_REASON}" + }, + + "rs-storage": { + "device":{ + "count":"$DEVICE_COUNT", + "destroy_on_decommission":"$DEVICE_DESTROY_ON_DECOMMISSION", + "mount_point":"$DEVICE_MOUNT_POINT", + "nickname":"$DEVICE_NICKNAME" + } + }, + + "run_list": ["recipe[rs-storage::decommission]"] +} +EOF + +chef-solo -l info -L /var/log/chef.log -j $chef_dir/chef.json -c $chef_dir/solo.rb diff --git a/jenkins/Storage_Toolbox_Schedule-chef.sh b/jenkins/Storage_Toolbox_Schedule-chef.sh new file mode 100755 index 0000000..6a7746a --- /dev/null +++ b/jenkins/Storage_Toolbox_Schedule-chef.sh @@ -0,0 +1,125 @@ +#! /usr/bin/sudo /bin/bash +# --- +# RightScript Name: Storage Toolbox Schedule - chef +# Description: 'Enable/disable periodic backups ' +# Inputs: +# SCHEDULE_ENABLE: +# Category: Storage +# Description: Enable or disable periodic backup schedule +# Input Type: single +# Required: false +# Advanced: false +# Possible Values: +# - text:true +# - text:false +# SCHEDULE_HOUR: +# Category: Storage +# Description: 'The hour to schedule the backup on. This value should abide by crontab +# syntax. Use ''*'' for taking'' + '' backups every hour. Example: 23' +# Input Type: single +# Required: true +# Advanced: false +# Default: text:23 +# SCHEDULE_MINUTE: +# Category: Storage +# Description: 'The minute to schedule the backup on. This value should abide by +# crontab syntax. Example: 30' +# Input Type: single +# Required: true +# Advanced: false +# Default: text:15 +# Attachments: +# - rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar +# ... + +set -x +set -e + +# https://github.com/berkshelf/berkshelf-api/issues/112 +export LC_CTYPE=en_US.UTF-8 + +if [ ! -e /usr/bin/chef-client ]; then + curl -L https://www.opscode.com/chef/install.sh | sudo bash -s -- -v 12.19.36 +fi + +HOME=/home/rightscale +export PATH=${PATH}:/usr/local/sbin:/usr/local/bin + +/sbin/mkhomedir_helper rightlink + +export chef_dir=$HOME/.chef + +rm -rf $chef_dir +mkdir -p $chef_dir/chef-install +chmod -R 0777 $chef_dir/chef-install + +mkdir -p $chef_dir/cookbooks +chown -R 0777 $chef_dir/cookbooks + +#install packages when on ubuntu +if which apt-get >/dev/null 2>&1; then + apt-get -y update + apt-get install -y build-essential git #ruby2.0 ruby2.0-dev +fi + +#install packages for centos +if which yum >/dev/null 2>&1; then + yum groupinstall -y 'Development Tools' + yum install -y libxml2 libxml2-devel libxslt libxslt-devel git +fi + +#install berkshelf +/opt/chef/embedded/bin/gem install berkshelf -v '4.3.5' --no-ri --no-rdoc + +#checkout the chef server cookbook and install dependent cookbooks using berkshelf +cd $chef_dir + +# Download cookbooks from RS Attachments + +if [ -f $RS_ATTACH_DIR/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar ]; then + tar -xvf $RS_ATTACH_DIR/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar +fi + +/opt/chef/embedded/bin/berks vendor $chef_dir/cookbooks + +#get instance data to pass to chef server +instance_data=$(/usr/local/bin/rsc --rl10 cm15 index_instance_session /api/sessions/instance) +instance_uuid=$(echo $instance_data | /usr/local/bin/rsc --x1 '.monitoring_id' json) +instance_id=$(echo $instance_data | /usr/local/bin/rsc --x1 '.resource_uid' json) + +if [ -e $chef_dir/chef.json ]; then + rm -f $chef_dir/chef.json +fi + +# add the rightscale env variables to the chef runtime attributes +# http://docs.rightscale.com/cm/ref/environment_inputs.html +cat < $chef_dir/chef.json +{ + "name": "${HOSTNAME}", + "normal": { + "tags": [] + }, + + "rightscale": { + "instance_uuid":"$instance_uuid", + "instance_id":"$instance_id" + }, + + "rs-storage": { + "schedule":{ + "enable":"$SCHEDULE_ENABLE", + "hour":$SCHEDULE_HOUR, + "minute":$SCHEDULE_MINUTE + } + }, + + "run_list": ["recipe[rs-storage::schedule]"] +} +EOF + +cat < $chef_dir/solo.rb +cookbook_path "$chef_dir/cookbooks" +data_bag_path "$chef_dir/data_bags" +EOF + +chef-solo -l info -L /var/log/chef.log -j $chef_dir/chef.json -c $chef_dir/solo.rb diff --git a/jenkins/Storage_Toolbox_Stripe-chef.sh b/jenkins/Storage_Toolbox_Stripe-chef.sh new file mode 100755 index 0000000..2b3d55e --- /dev/null +++ b/jenkins/Storage_Toolbox_Stripe-chef.sh @@ -0,0 +1,205 @@ +#! /usr/bin/sudo /bin/bash +# --- +# RightScript Name: Storage Toolbox Stripe - chef +# Description: Creates volumes, attaches them to the server, and sets up a striped LVM +# Inputs: +# DEVICE_IOPS: +# Category: Storage +# Description: 'IO Operations Per Second to use for the device. Currently this value +# is only used on AWS clouds. Example: 100' +# Input Type: single +# Required: false +# Advanced: false +# DEVICE_MOUNT_POINT: +# Category: Storage +# Description: 'The mount point to mount the device on. Example: /mnt/storage' +# Input Type: single +# Required: true +# Advanced: false +# Default: text:/mnt/storage +# DEVICE_VOLUME_SIZE: +# Category: Storage +# Description: 'Size of the volume or logical volume to create (in GB). Example: +# 10' +# Input Type: single +# Required: true +# Advanced: false +# DEVICE_VOLUME_TYPE: +# Category: Storage +# Description: 'Volume Type to use for creating volumes. Example: gp2' +# Input Type: single +# Required: false +# Advanced: false +# STOR_RESTORE_LINEAGE: +# Category: Storage +# Description: 'The lineage name to restore backups. Example: staging' +# Input Type: single +# Required: false +# Advanced: false +# STOR_RESTORE_TIMESTAMP: +# Category: Storage +# Description: 'The timestamp (in seconds since UNIX epoch) to select a backup to +# restore from. The backup selected will have been created on or before this timestamp. +# Example: 1391473172' +# Input Type: single +# Required: false +# Advanced: false +# DEVICE_FILESYSTEM: +# Category: Storage +# Description: 'The filesystem to be used on the device. Defaults are based on OS +# and determined in attributes/defaults.rb. Example: ext4' +# Input Type: single +# Required: false +# Advanced: false +# Default: text:ext4 +# DEVICE_COUNT: +# Category: Storage +# Description: "The number of devices to create and use in the Logical Volume. If +# this value is set to more than 1, it will create the specified number of devices +# and create an LVM on the devices.\r\n" +# Input Type: single +# Required: true +# Advanced: false +# Default: text:2 +# DEVICE_NICKNAME: +# Category: Storage +# Description: 'Nickname for the device. rs-storage::volume uses this for the filesystem +# label, which is restricted to 12 characters. If longer than 12 characters, the +# filesystem label will be set to the first 12 characters. Example: data_storage' +# Input Type: single +# Required: true +# Advanced: false +# Default: text:data_storage +# Attachments: +# - rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar +# ... + +set -x +set -e + +HOME=/home/rightscale +export PATH=${PATH}:/usr/local/sbin:/usr/local/bin + +# https://github.com/berkshelf/berkshelf-api/issues/112 +export LC_CTYPE=en_US.UTF-8 + +if [ ! -e /usr/bin/chef-client ]; then + curl -L https://www.opscode.com/chef/install.sh | sudo bash -s -- -v 12.19.36 +fi + +sudo /sbin/mkhomedir_helper rightlink + +export chef_dir=$HOME/.chef +mkdir -p $chef_dir + +rm -rf $chef_dir +mkdir -p $chef_dir/chef-install +chmod -R 0777 $chef_dir/chef-install + +mkdir -p $chef_dir/cookbooks +chown -R 0777 $chef_dir/cookbooks + +#install packages when on ubuntu +if which apt-get >/dev/null 2>&1; then + apt-get -y update + apt-get install -y build-essential git #ruby2.0 ruby2.0-dev +fi + +#install packages for centos +if which yum >/dev/null 2>&1; then + yum groupinstall -y 'Development Tools' + yum install -y libxml2 libxml2-devel libxslt libxslt-devel git +fi + + +#install berkshelf +/opt/chef/embedded/bin/gem install berkshelf -v '4.3.5' --no-ri --no-rdoc + +#checkout the chef server cookbook and install dependent cookbooks using berkshelf +cd $chef_dir + +# Download cookbooks from RS Attachments +if [ -f $RS_ATTACH_DIR/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar ]; then + tar -xvf $RS_ATTACH_DIR/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar +fi + +/opt/chef/embedded/bin/berks vendor $chef_dir/cookbooks + +#get instance data to pass to chef server +instance_data=$(/usr/local/bin/rsc --rl10 cm15 index_instance_session /api/sessions/instance) +instance_uuid=$(echo $instance_data | /usr/local/bin/rsc --x1 '.monitoring_id' json) +instance_id=$(echo $instance_data | /usr/local/bin/rsc --x1 '.resource_uid' json) + +device_iops='' +if [ -n "$DEVICE_IOPS" ];then + device_iops="\"iops\":\"$DEVICE_IOPS\"," +fi + +device_filesystem='' +if [ -n "$DEVICE_FILESYSTEM" ];then + device_filesystem="\"filesystem\":\"$DEVICE_FILESYSTEM\"," +fi +device_volume_type='' +if [ -n "$DEVICE_VOLUME_TYPE" ];then + device_volume_type="\"volume_type\":\"$DEVICE_VOLUME_TYPE\"" +fi + +restore_lineage='' +if [ -n "$STOR_RESTORE_LINEAGE" ];then + restore_lineage="\"lineage\":\"$STOR_RESTORE_LINEAGE\"$comma" +fi + +restore_timestamp='' +comma="" +if [ -n "$STOR_RESTORE_TIMESTAMP" ];then + comma="," + restore_timestamp="\"timestamp\":\"$STOR_RESTORE_TIMESTAMP\"" +fi + +if [ -e $chef_dir/chef.json ]; then + rm -f $chef_dir/chef.json +fi +# add the rightscale env variables to the chef runtime attributes +# http://docs.rightscale.com/cm/ref/environment_inputs.html +cat < $chef_dir/chef.json +{ + "name": "${HOSTNAME}", + "normal": { + "tags": [] + }, + + "rightscale": { + "instance_uuid":"$instance_uuid", + "instance_id":"$instance_id" + }, + "apt":{"compile_time_update":true}, + "build-essential":{"compile_time":true}, + "rs-storage": { + "device":{ + "count":"$DEVICE_COUNT", + $device_filesystem + $device_iops + $device_volume_type + "mount_point":"$DEVICE_MOUNT_POINT", + "nickname":"$DEVICE_NICKNAME", + "volume_size":"$DEVICE_VOLUME_SIZE" + + }, + "restore":{ + $restore_lineage$comma + $restore_timestamp + } + + }, + + "run_list": ["recipe[apt]","recipe[build-essential]", + "recipe[rs-storage::default]","recipe[rs-storage::stripe]"] +} +EOF + +cat < $chef_dir/solo.rb +cookbook_path "$chef_dir/cookbooks" +data_bag_path "$chef_dir/data_bags" +EOF + +chef-solo -l info -L /var/log/chef.log -j $chef_dir/chef.json -c $chef_dir/solo.rb diff --git a/jenkins/Storage_Toolbox_Volume-chef.sh b/jenkins/Storage_Toolbox_Volume-chef.sh new file mode 100755 index 0000000..c5610c1 --- /dev/null +++ b/jenkins/Storage_Toolbox_Volume-chef.sh @@ -0,0 +1,197 @@ +#! /usr/bin/sudo /bin/bash +# --- +# RightScript Name: Storage Toolbox Volume - chef +# Description: 'Creates a volume and attaches it to the server ' +# Inputs: +# DEVICE_IOPS: +# Category: Storage +# Description: 'IO Operations Per Second to use for the device. Currently this value +# is only used on AWS clouds. Example: 100' +# Input Type: single +# Required: false +# Advanced: false +# DEVICE_MOUNT_POINT: +# Category: Storage +# Description: 'The mount point to mount the device on. Example: /mnt/storage' +# Input Type: single +# Required: true +# Advanced: false +# Default: text:/mnt/storage +# DEVICE_NICKNAME: +# Category: Storage +# Description: 'Nickname for the device. rs-storage::volume uses this for the filesystem +# label, which is restricted to 12 characters. If longer than 12 characters, the +# filesystem label will be set to the first 12 characters. Example: data_storage' +# Input Type: single +# Required: true +# Advanced: false +# DEVICE_VOLUME_SIZE: +# Category: Storage +# Description: "Size of the volume or logical volume to create (in GB). Example: +# 10\r\n" +# Input Type: single +# Required: true +# Advanced: false +# DEVICE_VOLUME_TYPE: +# Category: Storage +# Description: "Volume Type to use for creating volumes. Example: gp2\r\n" +# Input Type: single +# Required: false +# Advanced: false +# STOR_RESTORE_LINEAGE: +# Category: Storage +# Description: 'The lineage name to restore backups. Example: staging' +# Input Type: single +# Required: false +# Advanced: false +# STOR_RESTORE_TIMESTAMP: +# Category: Storage +# Description: 'The timestamp (in seconds since UNIX epoch) to select a backup to +# restore from. The backup selected will have been created on or before this timestamp. +# Example: 1391473172' +# Input Type: single +# Required: false +# Advanced: false +# DEVICE_FILESYSTEM: +# Category: Storage +# Description: 'The filesystem to be used on the device. Defaults are based on OS +# and determined in attributes/defaults.rb. Example: ext4' +# Input Type: single +# Required: false +# Advanced: false +# Default: text:ext4 +# Attachments: +# - rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar +# ... + +set -x +set -e + +# https://github.com/berkshelf/berkshelf-api/issues/112 +export LC_CTYPE=en_US.UTF-8 + +if [ ! -e /usr/bin/chef-client ]; then + curl -L https://www.opscode.com/chef/install.sh | sudo bash -s -- -v 12.19.36 +fi + +HOME=/home/rightscale +export PATH=${PATH}:/usr/local/sbin:/usr/local/bin + +/sbin/mkhomedir_helper rightlink + +export chef_dir=$HOME/.chef + +rm -rf $chef_dir +mkdir -p $chef_dir/chef-install +chmod -R 0777 $chef_dir/chef-install + +mkdir -p $chef_dir/cookbooks +chown -R 0777 $chef_dir/cookbooks + +#install packages when on ubuntu +if which apt-get >/dev/null 2>&1; then + apt-get -y update + apt-get install -y build-essential git #ruby2.0 ruby2.0-dev +fi + +#install packages for centos +if which yum >/dev/null 2>&1; then + yum groupinstall -y 'Development Tools' + yum install -y libxml2 libxml2-devel libxslt libxslt-devel git +fi + +#install berkshelf +/opt/chef/embedded/bin/gem install berkshelf -v '4.3.5' --no-ri --no-rdoc + +#checkout the chef server cookbook and install dependent cookbooks using berkshelf +cd $chef_dir + +# Download cookbooks from RS Attachments + +if [ -f $RS_ATTACH_DIR/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar ]; then + tar -xvf $RS_ATTACH_DIR/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar +fi + +/opt/chef/embedded/bin/berks vendor $chef_dir/cookbooks + +# get instance data to pass to chef server +instance_data=$(/usr/local/bin/rsc --rl10 cm15 index_instance_session /api/sessions/instance) +instance_uuid=$(echo $instance_data | /usr/local/bin/rsc --x1 '.monitoring_id' json) +instance_id=$(echo $instance_data | /usr/local/bin/rsc --x1 '.resource_uid' json) + +device_iops='' +if [ -n "$DEVICE_IOPS" ];then + device_iops="\"iops\":\"$DEVICE_IOPS\"," +fi + +device_volume_type='' +if [ -n "$DEVICE_VOLUME_TYPE" ];then + device_volume_type="\"volume_type\":\"$DEVICE_VOLUME_TYPE\"," +fi + +device_filesystem='' +if [ -n "$DEVICE_FILESYSTEM" ];then + device_filesystem="\"filesystem\":\"$DEVICE_FILESYSTEM\"," +fi + +restore_lineage='' +if [ -n "$STOR_RESTORE_LINEAGE" ];then + restore_lineage="\"lineage\":\"$STOR_RESTORE_LINEAGE\"$comma" +fi + +restore_timestamp='' +comma="" +if [ -n "$STOR_RESTORE_TIMESTAMP" ];then + comma="," + restore_timestamp="\"timestamp\":\"$STOR_RESTORE_TIMESTAMP\"" +fi + +if [ -e $chef_dir/chef.json ]; then + rm -f $chef_dir/chef.json +fi +# add the rightscale env variables to the chef runtime attributes +# http://docs.rightscale.com/cm/ref/environment_inputs.html +cat < $chef_dir/chef.json +{ + "name": "${HOSTNAME}", + "normal": { + "tags": [] + }, + + "apt":{"compile_time_update":true}, + "build-essential":{"compile_time":true}, + + "rightscale": { + "instance_uuid":"$instance_uuid", + "instance_id":"$instance_id" + }, + + "rs-storage": { + "device":{ + $device_filesystem + $device_iops + "mount_point":"$DEVICE_MOUNT_POINT", + "nickname":"$DEVICE_NICKNAME", + $device_volume_type + "volume_size":"$DEVICE_VOLUME_SIZE" + }, + "restore":{ + $restore_lineage$comma + $restore_timestamp + } + + }, + + "run_list": ["recipe[apt]","recipe[build-essential]", + "recipe[rs-storage::default]","recipe[rs-storage::volume]"] +} +EOF + +cat < $chef_dir/solo.rb +cookbook_path "$chef_dir/cookbooks" +data_bag_path "$chef_dir/data_bags" +EOF + +/sbin/mkhomedir_helper rightlink + +chef-solo -l info -L /var/log/chef.log -j $chef_dir/chef.json -c $chef_dir/solo.rb diff --git a/jenkins/attachments/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar b/jenkins/attachments/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar new file mode 100644 index 0000000000000000000000000000000000000000..1f5e1e855aa7294bfaa6ca251d6437cc6f1c5d34 GIT binary patch literal 112640 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 F|36?f5TXD8 literal 0 HcmV?d00001 From c444e2aedb045ac31c2c24bd7171320cdd2c2c47 Mon Sep 17 00:00:00 2001 From: Stefhen Hovland Date: Tue, 2 May 2017 13:05:07 -0400 Subject: [PATCH 03/13] Updated jenkins.tar. Removed Berksfile.lock and other non cookbook items --- jenkins/attachments/rsc_jenkins-201704183.tar | Bin 256000 -> 30720 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/jenkins/attachments/rsc_jenkins-201704183.tar b/jenkins/attachments/rsc_jenkins-201704183.tar index ec059ff06224fbb5ae72925ba3c99b18167319a5..4820ac8ed7cef4c78c9de3ff57df1d96ba54d893 100644 GIT binary patch delta 1399 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 IFHM2}07*uu`~Uy| From 029cde0305a1795ce2440286b8fece9b9bf85d62 Mon Sep 17 00:00:00 2001 From: Stefhen Hovland Date: Fri, 5 May 2017 10:53:52 -0400 Subject: [PATCH 04/13] Remove combined ST and use master/slave templates --- .../Jenkins-Chef_Solo_RightLink_10_6_0.yml | 131 ------------------ 1 file changed, 131 deletions(-) delete mode 100644 jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml diff --git a/jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml b/jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml deleted file mode 100644 index 199d012..0000000 --- a/jenkins/Jenkins-Chef_Solo_RightLink_10_6_0.yml +++ /dev/null @@ -1,131 +0,0 @@ -Name: Jenkins - Chef Solo (RightLink 10.6.0) -Description: "Chef Client ServerTemplate for RightLink10. RightLink10 is a new agent - to connect servers to the RightScale platform that is very lightweight and simple - to install.\n_It is not a plug-in upgrade from the older RightLink v6 series._\nSee - [http://docs.rightscale.com/rl/about.html](http://docs.rightscale.com/rl/about.html) - for details.\n\nThis base ST runs a script to update the packaging system and enable - automatic security updates, and a collectd install script to enable RightScale monitoring. - \n\nThe base ST can run on most any Linux distro that supports cloud-init. It is - recommended to use the standard distro images in various clouds.\n\n__Requirements__\n\n* - Chef Server or Hosted Chef\n\n__Tested Linux distros:__\n\n* Ubuntu 14.04 x86_64\n\n__Documenation__\n\n* - [Overview](http://docs.rightscale.com/st/rl10/chef-client/overview.html)\n\n\n__Tested - compute clouds:__\n\n* AWS\n" -Inputs: - COLLECTD_SERVER: env:RS_TSS - RS_INSTANCE_UUID: env:RS_INSTANCE_UUID -RightScripts: - Boot: - - RL10_Linux_Setup_Hostname.sh - - RL10_Linux_Enable_Managed_Login.sh - - RL10_Linux_Enable_Monitoring.sh - - RL10_Linux_Setup_Alerts.sh - - RL10_Linux_Setup_Automatic_Upgrade.sh - - RL5_6_10_Setup_Custom_Logrotate_Configs.sh - Decommission: - - RL10_Linux_Shutdown_Reason.sh - - Storage_Toolbox_Decommission-chef.sh - Operational: - - RL10_Jenkins_Install_Master.sh - - RL10_Jenkins_Install_Slave.sh - - RL10_Linux_Setup_Automatic_Upgrade.sh - - RL10_Linux_Upgrade.sh - - Update_R53_A_Record.sh - - Storage_Toolbox_Volume-chef.sh - - Storage_Toolbox_Schedule-chef.sh - - Storage_Toolbox_Backup-chef.sh - - Storage_Toolbox_Stripe-chef.sh -MultiCloudImages: -- Name: Ubuntu_14.04_x64 - Revision: 70 - Publisher: RightScale -- Name: Ubuntu_12.04_x64 - Revision: 66 - Publisher: RightScale -- Name: Ubuntu_12.04_x64_KVM - Revision: 31 - Publisher: RightScale -- Name: Ubuntu_14.04_x64_KVM - Revision: 31 - Publisher: RightScale -- Name: Ubuntu_16.04_x64 - Revision: 5 - Publisher: RightScale -- Name: Ubuntu_16.04_x64_KVM - Revision: 3 - Publisher: RightScale -- Name: CentOS_6.x_x64 - Revision: 25 - Publisher: RightScale -- Name: CentOS_6.x_x64_KVM - Revision: 30 - Publisher: RightScale -- Name: CentOS_7.x_x64 - Revision: 33 - Publisher: RightScale -- Name: CentOS_7.x_x64_KVM - Revision: 30 - Publisher: RightScale -- Name: RHEL_6.x_x64_KVM - Revision: 9 - Publisher: RightScale -- Name: RHEL_7.x_x64_KVM - Revision: 9 - Publisher: RightScale -- Name: RHEL_6.x_x64 - Revision: 13 - Publisher: RightScale -- Name: RHEL_7.x_x64 - Revision: 11 - Publisher: RightScale -Alerts: -- Name: rs instance terminated - Description: Raise an alert if the instance has been terminated abnormally, i.e. - not through the RightScale interface or by an elasticity daemon resizing server - arrays. - Clause: If RS/server.state == terminated for 1 minutes Then escalate critical -- Name: rs instance stranded - Description: Raise an alert if the instance enters the stranded state. - Clause: If RS/server-failure.state == stranded for 1 minutes Then escalate warning -- Name: rs instance not responding - Description: Raise an alert if the instance fails to send monitoring information - for 5 minutes. - Clause: If cpu-0/cpu-idle.value == NaN for 5 minutes Then escalate critical -- Name: rs cpu busy - Description: Raise an alert if the idle time is too low. - Clause: If cpu-0/cpu-idle.value < 15 for 3 minutes Then escalate warning -- Name: rs cpu overloaded - Description: Raise an alert when the cpu idle time is too low. - Clause: If cpu-0/cpu-idle.value < 3 for 5 minutes Then escalate critical -- Name: rs cpu I/O wait - Description: Raise an alert if disk io is too high. - Clause: If cpu-0/cpu-wait.value > 40 for 15 minutes Then escalate warning -- Name: rs low space in root partition - Description: Raise an alert if the available space in the root partition is too - low. This alert may be modified on an instance to match the metric name df/df-root.free - instead if the instance is running collectd 4. See the RL10 Linux Setup Alerts - RightScript (rll/setup-alerts.sh) for more details. - Clause: If df-root/df_complex-free.value < 1073741824 for 5 minutes Then escalate - critical -- Name: rs high network tx activity - Description: Raise an alert if the amount of network data transmitted is too high. - This alert may be modified or cloned on an instance to match the actual network - interfaces that are present. See the RL10 Linux Setup Alerts RightScript (rll/setup-alerts.sh) - for more details. - Clause: If interface-eth0/if_octets.tx > 10000000 for 10 minutes Then escalate critical -- Name: rs high network rx activity - Description: Raise an alert if the amount of network data received is too high. - This alert may be modified or cloned on an instance to match the actual network - interfaces that are present. See the RL10 Linux Setup Alerts RightScript (rll/setup-alerts.sh) - for more details. - Clause: If interface-eth0/if_octets.rx > 50000000 for 30 minutes Then escalate critical -- Name: rs low swap space - Description: Raise alert if the free swap space is too low. This alert may be removed - from an instance if swap is not enabled. See the RL10 Linux Setup Alerts RightScript - (rll/setup-alerts.sh) for more details. - Clause: If swap/swap-free.value < 104857600 for 5 minutes Then escalate critical -- Name: rs memory low - Description: Raise an alert if free memory is too low. - Clause: If memory/memory-free.value < 1000000 for 1 minutes Then escalate critical -- Name: rs out of memory - Description: Raise an alert when the server is out of free memory. - Clause: If memory/memory-free.value == 0 for 1 minutes Then escalate critical From 0665ae943a9c96b46e5d8baccc30a98924c47b29 Mon Sep 17 00:00:00 2001 From: Stefhen Hovland Date: Fri, 5 May 2017 12:17:41 -0400 Subject: [PATCH 05/13] Add Jenkins master/slave STs --- jenkins/Jenkins-Master.yml | 128 +++++++++++++++++++++++++++++++++++++ jenkins/Jenkins-Slave.yml | 128 +++++++++++++++++++++++++++++++++++++ 2 files changed, 256 insertions(+) create mode 100644 jenkins/Jenkins-Master.yml create mode 100644 jenkins/Jenkins-Slave.yml diff --git a/jenkins/Jenkins-Master.yml b/jenkins/Jenkins-Master.yml new file mode 100644 index 0000000..280decd --- /dev/null +++ b/jenkins/Jenkins-Master.yml @@ -0,0 +1,128 @@ +Name: Jenkins Master - Chef Solo (RightLink 10.6.0) +Description: "Chef Client ServerTemplate for RightLink10. RightLink10 is a new agent + to connect servers to the RightScale platform that is very lightweight and simple + to install.\n_It is not a plug-in upgrade from the older RightLink v6 series._\nSee + [http://docs.rightscale.com/rl/about.html](http://docs.rightscale.com/rl/about.html) + for details.\n\nThis base ST runs a script to update the packaging system and enable + automatic security updates, and a collectd install script to enable RightScale monitoring. + \n\nThe base ST can run on most any Linux distro that supports cloud-init. It is + recommended to use the standard distro images in various clouds.\n\n__Requirements__\n\n* + Chef Server or Hosted Chef\n\n__Tested Linux distros:__\n\n* Ubuntu 14.04 x86_64\n\n__Documenation__\n\n* + [Overview](http://docs.rightscale.com/st/rl10/chef-client/overview.html)\n\n\n__Tested + compute clouds:__\n\n* AWS\n" +Inputs: + COLLECTD_SERVER: env:RS_TSS + RS_INSTANCE_UUID: env:RS_INSTANCE_UUID +RightScripts: + Boot: + - RL10_Linux_Setup_Hostname.sh + - RL10_Linux_Enable_Managed_Login.sh + - RL10_Linux_Enable_Monitoring.sh + - RL10_Linux_Setup_Alerts.sh + - RL10_Linux_Setup_Automatic_Upgrade.sh + - RL5_6_10_Setup_Custom_Logrotate_Configs.sh + - Storage_Toolbox_Stripe-chef.sh + - RL10_Jenkins_Install_Master.sh + Decommission: + - RL10_Linux_Shutdown_Reason.sh + - Storage_Toolbox_Decommission-chef.sh + Operational: + - RL10_Linux_Setup_Automatic_Upgrade.sh + - RL10_Linux_Upgrade.sh + - Storage_Toolbox_Schedule-chef.sh + - Storage_Toolbox_Backup-chef.sh +MultiCloudImages: +- Name: Ubuntu_14.04_x64 + Revision: 70 + Publisher: RightScale +- Name: Ubuntu_12.04_x64 + Revision: 66 + Publisher: RightScale +- Name: Ubuntu_12.04_x64_KVM + Revision: 31 + Publisher: RightScale +- Name: Ubuntu_14.04_x64_KVM + Revision: 31 + Publisher: RightScale +- Name: Ubuntu_16.04_x64 + Revision: 5 + Publisher: RightScale +- Name: Ubuntu_16.04_x64_KVM + Revision: 3 + Publisher: RightScale +- Name: CentOS_6.x_x64 + Revision: 25 + Publisher: RightScale +- Name: CentOS_6.x_x64_KVM + Revision: 30 + Publisher: RightScale +- Name: CentOS_7.x_x64 + Revision: 33 + Publisher: RightScale +- Name: CentOS_7.x_x64_KVM + Revision: 30 + Publisher: RightScale +- Name: RHEL_6.x_x64_KVM + Revision: 9 + Publisher: RightScale +- Name: RHEL_7.x_x64_KVM + Revision: 9 + Publisher: RightScale +- Name: RHEL_6.x_x64 + Revision: 13 + Publisher: RightScale +- Name: RHEL_7.x_x64 + Revision: 11 + Publisher: RightScale +Alerts: +- Name: rs instance terminated + Description: Raise an alert if the instance has been terminated abnormally, i.e. + not through the RightScale interface or by an elasticity daemon resizing server + arrays. + Clause: If RS/server.state == terminated for 1 minutes Then escalate critical +- Name: rs instance stranded + Description: Raise an alert if the instance enters the stranded state. + Clause: If RS/server-failure.state == stranded for 1 minutes Then escalate warning +- Name: rs instance not responding + Description: Raise an alert if the instance fails to send monitoring information + for 5 minutes. + Clause: If cpu-0/cpu-idle.value == NaN for 5 minutes Then escalate critical +- Name: rs cpu busy + Description: Raise an alert if the idle time is too low. + Clause: If cpu-0/cpu-idle.value < 15 for 3 minutes Then escalate warning +- Name: rs cpu overloaded + Description: Raise an alert when the cpu idle time is too low. + Clause: If cpu-0/cpu-idle.value < 3 for 5 minutes Then escalate critical +- Name: rs cpu I/O wait + Description: Raise an alert if disk io is too high. + Clause: If cpu-0/cpu-wait.value > 40 for 15 minutes Then escalate warning +- Name: rs low space in root partition + Description: Raise an alert if the available space in the root partition is too + low. This alert may be modified on an instance to match the metric name df/df-root.free + instead if the instance is running collectd 4. See the RL10 Linux Setup Alerts + RightScript (rll/setup-alerts.sh) for more details. + Clause: If df-root/df_complex-free.value < 1073741824 for 5 minutes Then escalate + critical +- Name: rs high network tx activity + Description: Raise an alert if the amount of network data transmitted is too high. + This alert may be modified or cloned on an instance to match the actual network + interfaces that are present. See the RL10 Linux Setup Alerts RightScript (rll/setup-alerts.sh) + for more details. + Clause: If interface-eth0/if_octets.tx > 10000000 for 10 minutes Then escalate critical +- Name: rs high network rx activity + Description: Raise an alert if the amount of network data received is too high. + This alert may be modified or cloned on an instance to match the actual network + interfaces that are present. See the RL10 Linux Setup Alerts RightScript (rll/setup-alerts.sh) + for more details. + Clause: If interface-eth0/if_octets.rx > 50000000 for 30 minutes Then escalate critical +- Name: rs low swap space + Description: Raise alert if the free swap space is too low. This alert may be removed + from an instance if swap is not enabled. See the RL10 Linux Setup Alerts RightScript + (rll/setup-alerts.sh) for more details. + Clause: If swap/swap-free.value < 104857600 for 5 minutes Then escalate critical +- Name: rs memory low + Description: Raise an alert if free memory is too low. + Clause: If memory/memory-free.value < 1000000 for 1 minutes Then escalate critical +- Name: rs out of memory + Description: Raise an alert when the server is out of free memory. + Clause: If memory/memory-free.value == 0 for 1 minutes Then escalate critical diff --git a/jenkins/Jenkins-Slave.yml b/jenkins/Jenkins-Slave.yml new file mode 100644 index 0000000..a9412ac --- /dev/null +++ b/jenkins/Jenkins-Slave.yml @@ -0,0 +1,128 @@ +Name: Jenkins - Chef Solo (RightLink 10.6.0) +Description: "Chef Client ServerTemplate for RightLink10. RightLink10 is a new agent + to connect servers to the RightScale platform that is very lightweight and simple + to install.\n_It is not a plug-in upgrade from the older RightLink v6 series._\nSee + [http://docs.rightscale.com/rl/about.html](http://docs.rightscale.com/rl/about.html) + for details.\n\nThis base ST runs a script to update the packaging system and enable + automatic security updates, and a collectd install script to enable RightScale monitoring. + \n\nThe base ST can run on most any Linux distro that supports cloud-init. It is + recommended to use the standard distro images in various clouds.\n\n__Requirements__\n\n* + Chef Server or Hosted Chef\n\n__Tested Linux distros:__\n\n* Ubuntu 14.04 x86_64\n\n__Documenation__\n\n* + [Overview](http://docs.rightscale.com/st/rl10/chef-client/overview.html)\n\n\n__Tested + compute clouds:__\n\n* AWS\n" +Inputs: + COLLECTD_SERVER: env:RS_TSS + RS_INSTANCE_UUID: env:RS_INSTANCE_UUID +RightScripts: + Boot: + - RL10_Linux_Setup_Hostname.sh + - RL10_Linux_Enable_Managed_Login.sh + - RL10_Linux_Enable_Monitoring.sh + - RL10_Linux_Setup_Alerts.sh + - RL10_Linux_Setup_Automatic_Upgrade.sh + - RL5_6_10_Setup_Custom_Logrotate_Configs.sh + - Storage_Toolbox_Stripe-chef.sh + - RL10_Jenkins_Install_Slave.sh + Decommission: + - RL10_Linux_Shutdown_Reason.sh + - Storage_Toolbox_Decommission-chef.sh + Operational: + - RL10_Linux_Setup_Automatic_Upgrade.sh + - RL10_Linux_Upgrade.sh + - Storage_Toolbox_Schedule-chef.sh + - Storage_Toolbox_Backup-chef.sh +MultiCloudImages: +- Name: Ubuntu_14.04_x64 + Revision: 70 + Publisher: RightScale +- Name: Ubuntu_12.04_x64 + Revision: 66 + Publisher: RightScale +- Name: Ubuntu_12.04_x64_KVM + Revision: 31 + Publisher: RightScale +- Name: Ubuntu_14.04_x64_KVM + Revision: 31 + Publisher: RightScale +- Name: Ubuntu_16.04_x64 + Revision: 5 + Publisher: RightScale +- Name: Ubuntu_16.04_x64_KVM + Revision: 3 + Publisher: RightScale +- Name: CentOS_6.x_x64 + Revision: 25 + Publisher: RightScale +- Name: CentOS_6.x_x64_KVM + Revision: 30 + Publisher: RightScale +- Name: CentOS_7.x_x64 + Revision: 33 + Publisher: RightScale +- Name: CentOS_7.x_x64_KVM + Revision: 30 + Publisher: RightScale +- Name: RHEL_6.x_x64_KVM + Revision: 9 + Publisher: RightScale +- Name: RHEL_7.x_x64_KVM + Revision: 9 + Publisher: RightScale +- Name: RHEL_6.x_x64 + Revision: 13 + Publisher: RightScale +- Name: RHEL_7.x_x64 + Revision: 11 + Publisher: RightScale +Alerts: +- Name: rs instance terminated + Description: Raise an alert if the instance has been terminated abnormally, i.e. + not through the RightScale interface or by an elasticity daemon resizing server + arrays. + Clause: If RS/server.state == terminated for 1 minutes Then escalate critical +- Name: rs instance stranded + Description: Raise an alert if the instance enters the stranded state. + Clause: If RS/server-failure.state == stranded for 1 minutes Then escalate warning +- Name: rs instance not responding + Description: Raise an alert if the instance fails to send monitoring information + for 5 minutes. + Clause: If cpu-0/cpu-idle.value == NaN for 5 minutes Then escalate critical +- Name: rs cpu busy + Description: Raise an alert if the idle time is too low. + Clause: If cpu-0/cpu-idle.value < 15 for 3 minutes Then escalate warning +- Name: rs cpu overloaded + Description: Raise an alert when the cpu idle time is too low. + Clause: If cpu-0/cpu-idle.value < 3 for 5 minutes Then escalate critical +- Name: rs cpu I/O wait + Description: Raise an alert if disk io is too high. + Clause: If cpu-0/cpu-wait.value > 40 for 15 minutes Then escalate warning +- Name: rs low space in root partition + Description: Raise an alert if the available space in the root partition is too + low. This alert may be modified on an instance to match the metric name df/df-root.free + instead if the instance is running collectd 4. See the RL10 Linux Setup Alerts + RightScript (rll/setup-alerts.sh) for more details. + Clause: If df-root/df_complex-free.value < 1073741824 for 5 minutes Then escalate + critical +- Name: rs high network tx activity + Description: Raise an alert if the amount of network data transmitted is too high. + This alert may be modified or cloned on an instance to match the actual network + interfaces that are present. See the RL10 Linux Setup Alerts RightScript (rll/setup-alerts.sh) + for more details. + Clause: If interface-eth0/if_octets.tx > 10000000 for 10 minutes Then escalate critical +- Name: rs high network rx activity + Description: Raise an alert if the amount of network data received is too high. + This alert may be modified or cloned on an instance to match the actual network + interfaces that are present. See the RL10 Linux Setup Alerts RightScript (rll/setup-alerts.sh) + for more details. + Clause: If interface-eth0/if_octets.rx > 50000000 for 30 minutes Then escalate critical +- Name: rs low swap space + Description: Raise alert if the free swap space is too low. This alert may be removed + from an instance if swap is not enabled. See the RL10 Linux Setup Alerts RightScript + (rll/setup-alerts.sh) for more details. + Clause: If swap/swap-free.value < 104857600 for 5 minutes Then escalate critical +- Name: rs memory low + Description: Raise an alert if free memory is too low. + Clause: If memory/memory-free.value < 1000000 for 1 minutes Then escalate critical +- Name: rs out of memory + Description: Raise an alert when the server is out of free memory. + Clause: If memory/memory-free.value == 0 for 1 minutes Then escalate critical From b720af4d2a697379bbe693478cf2f3754ce1971e Mon Sep 17 00:00:00 2001 From: Stefhen Hovland Date: Mon, 8 May 2017 18:09:42 -0400 Subject: [PATCH 06/13] Initial CAT import --- jenkins/jenkins.cat.rb | 129 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 jenkins/jenkins.cat.rb diff --git a/jenkins/jenkins.cat.rb b/jenkins/jenkins.cat.rb new file mode 100644 index 0000000..053ee56 --- /dev/null +++ b/jenkins/jenkins.cat.rb @@ -0,0 +1,129 @@ +name "Jenkins Master and Slaves" +rs_ca_ver 20161221 +short_description "Jenkins Master and Slave cluster" + +parameter "param_slave_count" do + label "Jenkins Slave Count" + type "string" + operations [ "operation_set_slave_count", "launch" ] +end + +resource "server_1", type: "server" do + name "jenkins-master" + cloud "EC2 us-east-1" + instance_type "t2.large" + ssh_key_href "/api/clouds/1/ssh_keys/13FIKG64LL5SG" + subnet_hrefs "/api/clouds/1/subnets/C2II06OI99TMO" + security_group_hrefs [ "/api/clouds/1/security_groups/ATG27T4SM9AOL" ] + server_template find("stefhen-jenkins-master") +end + +resource "server_array_1", type: "server_array" do + name "jenkins-slaves" + cloud "EC2 us-east-1" + instance_type "t2.large" + ssh_key_href "/api/clouds/1/ssh_keys/13FIKG64LL5SG" + subnet_hrefs "/api/clouds/1/subnets/C2II06OI99TMO" + security_group_hrefs [ "/api/clouds/1/security_groups/ATG27T4SM9AOL" ] + server_template find("stefhen-jenkins-slave") + state "enabled" + array_type "alert" + elasticity_params do { + "bounds" => { + "min_count" => $param_slave_count, + "max_count" => 20 + }, + "pacing" => { + "resize_calm_time" => 5, + "resize_down_by" => 1, + "resize_up_by" => 1 + }, + "alert_specific_params" => { + "decision_threshold" => 51, + "voters_tag_predicate" => "jenkins-slave" + } + } end +end + +operation "launch" do + description "Launch the application" + definition "generated_launch" + output_mappings do { + $output_jenkins_master_ip => join(["http://", @server_1.public_ip_address, ":8080/"]) + } end +end + +operation "stop" do + description "Bring the array size to 0" + definition "disable_and_shrink_array" +end + +operation "start" do + description "Enable array" + definition "enable_array" +end + +operation "operation_set_slave_count" do + description "Sets the number of slaves to the provided parameter" + definition "set_slave_count" +end + +operation "operation_launch_slave" do + description "Manually adds one Jenkins slave" + definition "launch_slave" +end + +output "output_jenkins_master_ip" do + label "Jenkins" + description "Jenkins Master IP Address" + +end + +define wait_for_array_to_reach_size(@array, $size) do + sub task_name: "wait for array to reach size", timeout: 2h do + sleep_until(size(@array.current_instances()) == $size) + end +end + +parameter "param_vol_size" do + label "Jenkins Data Volume Size" + type "string" + operations "launch" +end + +define generated_launch(@server_1, @server_array_1, $param_slave_count, $param_vol_size) return @server_1 do + $inp = { + "DESCRIPTION": "text:Jenkins Slaves", + "MASTER_IP": "env:jenkins-master:PRIVATE_IP", + "NAME": "text:jenkins-slaves", + "STOR_BACKUP_LINEAGE": "text:jenkins_backup", + "DEVICE_VOLUME_SIZE": "text:" + $param_vol_size + } + + @@deployment.multi_update_inputs(inputs: $inp) + + concurrent do + provision(@server_1) + provision(@server_array_1) + end +end + +define disable_and_shrink_array(@server_array_1) return @server_array_1 do + @server_array_1.update(server_array: { state: "disabled" }) + @server_array_1.multi_terminate() + call wait_for_array_to_reach_size(@server_array_1, 0) +end + +define enable_array(@server_array_1) return @server_array_1 do + $desired_size = @server_array_1.elasticity_params["bounds"]["min_count"] + @server_array_1.update(server_array: { state: "enabled" }) + call wait_for_array_to_reach_size(@server_array_1, $desired_size) +end + +define set_slave_count(@server_array_1, $param_slave_count) do + @server_array_1.update(server_array: { elasticity_params: { bounds: { min_count: $param_slave_count } } } ) +end + +define launch_slave(@server_array_1) do + @server_array_1.launch() +end From e6de384681097770636beb1f00706750aa9fa6d7 Mon Sep 17 00:00:00 2001 From: Stefhen Hovland Date: Tue, 9 May 2017 11:52:42 -0400 Subject: [PATCH 07/13] Rename Jenkins Slave --- jenkins/Jenkins-Slave.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins/Jenkins-Slave.yml b/jenkins/Jenkins-Slave.yml index a9412ac..65e39bb 100644 --- a/jenkins/Jenkins-Slave.yml +++ b/jenkins/Jenkins-Slave.yml @@ -1,4 +1,4 @@ -Name: Jenkins - Chef Solo (RightLink 10.6.0) +Name: Jenkins Slave - Chef Solo (RightLink 10.6.0) Description: "Chef Client ServerTemplate for RightLink10. RightLink10 is a new agent to connect servers to the RightScale platform that is very lightweight and simple to install.\n_It is not a plug-in upgrade from the older RightLink v6 series._\nSee From 09d0602c7467facc0f55f0568df1ea977ee83c37 Mon Sep 17 00:00:00 2001 From: Stefhen Hovland Date: Tue, 9 May 2017 13:18:07 -0400 Subject: [PATCH 08/13] Use /var/lib/jenkins as default storage mountpoint --- jenkins/Storage_Toolbox_Backup-chef.sh | 4 ++-- jenkins/Storage_Toolbox_Decommission-chef.sh | 4 ++-- jenkins/Storage_Toolbox_Stripe-chef.sh | 4 ++-- jenkins/Storage_Toolbox_Volume-chef.sh | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jenkins/Storage_Toolbox_Backup-chef.sh b/jenkins/Storage_Toolbox_Backup-chef.sh index 77ed5ae..6b55d19 100755 --- a/jenkins/Storage_Toolbox_Backup-chef.sh +++ b/jenkins/Storage_Toolbox_Backup-chef.sh @@ -45,11 +45,11 @@ # Advanced: false # DEVICE_MOUNT_POINT: # Category: Storage -# Description: 'The mount point to mount the device on. Example: /mnt/storage' +# Description: 'The mount point to mount the device on. Example: /var/lib/jenkins' # Input Type: single # Required: true # Advanced: false -# Default: text:/mnt/storage +# Default: text:/var/lib/jenkins # DEVICE_NICKNAME: # Category: Storage # Description: 'Nickname for the device. rs-storage::volume uses this for the filesystem diff --git a/jenkins/Storage_Toolbox_Decommission-chef.sh b/jenkins/Storage_Toolbox_Decommission-chef.sh index 1f68b3a..24411b8 100755 --- a/jenkins/Storage_Toolbox_Decommission-chef.sh +++ b/jenkins/Storage_Toolbox_Decommission-chef.sh @@ -22,11 +22,11 @@ # - text:false # DEVICE_MOUNT_POINT: # Category: Storage -# Description: 'The mount point to mount the device on. Example: /mnt/storage' +# Description: 'The mount point to mount the device on. Example: /var/lib/jenkins' # Input Type: single # Required: true # Advanced: false -# Default: text:/mnt/storage +# Default: text:/var/lib/jenkins # DEVICE_NICKNAME: # Category: Storage # Description: 'Nickname for the device. rs-storage::volume uses this for the filesystem diff --git a/jenkins/Storage_Toolbox_Stripe-chef.sh b/jenkins/Storage_Toolbox_Stripe-chef.sh index 2b3d55e..50ea0e4 100755 --- a/jenkins/Storage_Toolbox_Stripe-chef.sh +++ b/jenkins/Storage_Toolbox_Stripe-chef.sh @@ -12,11 +12,11 @@ # Advanced: false # DEVICE_MOUNT_POINT: # Category: Storage -# Description: 'The mount point to mount the device on. Example: /mnt/storage' +# Description: 'The mount point to mount the device on. Example: /var/lib/jenkins' # Input Type: single # Required: true # Advanced: false -# Default: text:/mnt/storage +# Default: text:/var/lib/jenkins # DEVICE_VOLUME_SIZE: # Category: Storage # Description: 'Size of the volume or logical volume to create (in GB). Example: diff --git a/jenkins/Storage_Toolbox_Volume-chef.sh b/jenkins/Storage_Toolbox_Volume-chef.sh index c5610c1..02634ca 100755 --- a/jenkins/Storage_Toolbox_Volume-chef.sh +++ b/jenkins/Storage_Toolbox_Volume-chef.sh @@ -12,11 +12,11 @@ # Advanced: false # DEVICE_MOUNT_POINT: # Category: Storage -# Description: 'The mount point to mount the device on. Example: /mnt/storage' +# Description: 'The mount point to mount the device on. Example: /var/lib/jenkins' # Input Type: single # Required: true # Advanced: false -# Default: text:/mnt/storage +# Default: text:/var/lib/jenkins # DEVICE_NICKNAME: # Category: Storage # Description: 'Nickname for the device. rs-storage::volume uses this for the filesystem From f33403fc0d47e274e1bd69a52e52244f2ea8113d Mon Sep 17 00:00:00 2001 From: Stefhen Hovland Date: Wed, 10 May 2017 11:18:40 -0400 Subject: [PATCH 09/13] Added changelog --- jenkins/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 jenkins/CHANGELOG.md diff --git a/jenkins/CHANGELOG.md b/jenkins/CHANGELOG.md new file mode 100644 index 0000000..ccf1464 --- /dev/null +++ b/jenkins/CHANGELOG.md @@ -0,0 +1,5 @@ +### 2016-05-10 + +* Initial Jenkins Master / Slave import. +* Initial import of RL10 volume scripts. +* Initial import of generic CAT which will launch a master / slave cluster. From cf2db17353f181ec859dbf41507605301763ff1e Mon Sep 17 00:00:00 2001 From: Stefhen Hovland Date: Thu, 11 May 2017 16:09:43 -0400 Subject: [PATCH 10/13] ADD README.md --- jenkins/README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 jenkins/README.md diff --git a/jenkins/README.md b/jenkins/README.md new file mode 100644 index 0000000..95c0623 --- /dev/null +++ b/jenkins/README.md @@ -0,0 +1,43 @@ +### README: + +* Upload YAML files to your account with [right_st](https://github.com/rightscale/right_st) + +### IMPORTANT INPUTS: + +#### Jenkins Related: + +* `MASTER_IP`: Reachable address for the Jenkins slaves to contact and add themselves to the cluster. Usually the private IP address of the Jenkins Master host. + +* `SWARM_PLUGIN_VERSION`: Version of the Jenkins Swarm plugin to install which allows for slave / master discovery. Currently defaults to `3.4`. + +* `DESCRIPTION`: Text name of jenkins slave instances. + +* `AUTO_DISCOVERY_ADDRESS`: Enable this if using UDP based discovery. Not required. Current defaults allow Jenkins slaves to discover master via Swarm plugin and connecting to `MASTER_IP`. + +* `MASTER_PORT`: Default port Jenkins listens on. Defaults to `8080`. + +#### Storage Related: + +* `BACKUP_KEEP_DAILIES`: Number of daily backups to keep. Defaults to `14`. + +* `BACKUP_KEEP_LAST`: Number of snapshots to keep. Defaults to `60`. + +* `BACKUP_KEEP_MONTHLIES`: Number of monthly backups to keep. Defaults to `12`. + +* `BACKUP_KEEP_WEEKLIES`: Number of weekly backups to keep. Defaults to `6`. + +* `BACKUP_KEEP_YEARLIES`: Number of yearly backups to keep. Defaults to `2`. + +* `STOR_BACKUP_LINEAGE`: Name of backup lineage to use for snapshots. + +* `DEVICE_MOUNT_POINT`: Mount point of data volume. Defaults to `/var/lib/jenkins`, which is the Jenkins home / work directory. + +* `DEVICE_NICKNAME`: Name of the LVM device to be created. Defaults to `data_storage`. + +* `DEVICE_COUNT`: Number of devices to create which will make up the underlying LVM volume. + +* `DEVICE_DESTROY_ON_DECOMMISSION`: If set to true, the devices will be destroyed on decommission. Defaults to `false`. + +* `STOR_RESTORE_LINEAGE`: If set, restore from the supplied backup name. + +* `STOR_RESTORE_TIMESTAMP`: The filesystem to be used on the data volume. Defaults to `ext4`. \ No newline at end of file From eb23d45ca19c78fe904a90d742590fc23ef3ce17 Mon Sep 17 00:00:00 2001 From: Richard Shade Date: Thu, 12 Dec 2019 14:17:12 -0600 Subject: [PATCH 11/13] moving item --- .../jenkins}/CHANGELOG.md | 0 .../jenkins}/Jenkins-Master.yml | 0 .../jenkins}/Jenkins-Slave.yml | 0 {jenkins => chef-templates/jenkins}/README.md | 0 .../jenkins}/RL10_Jenkins_Install_Master.sh | 0 .../jenkins}/RL10_Jenkins_Install_Slave.sh | 0 ...RL5_6_10_Setup_Custom_Logrotate_Configs.sh | 0 .../jenkins}/Storage_Toolbox_Backup-chef.sh | 0 .../Storage_Toolbox_Decommission-chef.sh | 0 .../jenkins}/Storage_Toolbox_Schedule-chef.sh | 0 .../jenkins}/Storage_Toolbox_Stripe-chef.sh | 0 .../jenkins}/Storage_Toolbox_Volume-chef.sh | 0 .../jenkins}/Update_R53_A_Record.sh | 0 .../jenkins}/attachments/chef | 0 .../attachments/libnss_rightscale.tgz | Bin .../attachments/rightscale_login_policy.te | 0 .../jenkins}/attachments/rs-ssh-keys.sh | 0 ...69f08f87743e072eba619a3fba6a9c9dd6bc89.tar | Bin .../attachments/rsc_jenkins-201704183.tar | Bin .../jenkins}/jenkins.cat.rb | 0 jenkins/RL10_Linux_Enable_Managed_Login.sh | 323 ------------ jenkins/RL10_Linux_Enable_Monitoring.sh | 472 ------------------ jenkins/RL10_Linux_Setup_Alerts.sh | 239 --------- jenkins/RL10_Linux_Setup_Automatic_Upgrade.sh | 119 ----- jenkins/RL10_Linux_Setup_Hostname.sh | 181 ------- jenkins/RL10_Linux_Shutdown_Reason.sh | 73 --- jenkins/RL10_Linux_Upgrade.sh | 155 ------ 27 files changed, 1562 deletions(-) rename {jenkins => chef-templates/jenkins}/CHANGELOG.md (100%) rename {jenkins => chef-templates/jenkins}/Jenkins-Master.yml (100%) rename {jenkins => chef-templates/jenkins}/Jenkins-Slave.yml (100%) rename {jenkins => chef-templates/jenkins}/README.md (100%) rename {jenkins => chef-templates/jenkins}/RL10_Jenkins_Install_Master.sh (100%) rename {jenkins => chef-templates/jenkins}/RL10_Jenkins_Install_Slave.sh (100%) rename {jenkins => chef-templates/jenkins}/RL5_6_10_Setup_Custom_Logrotate_Configs.sh (100%) rename {jenkins => chef-templates/jenkins}/Storage_Toolbox_Backup-chef.sh (100%) rename {jenkins => chef-templates/jenkins}/Storage_Toolbox_Decommission-chef.sh (100%) rename {jenkins => chef-templates/jenkins}/Storage_Toolbox_Schedule-chef.sh (100%) rename {jenkins => chef-templates/jenkins}/Storage_Toolbox_Stripe-chef.sh (100%) rename {jenkins => chef-templates/jenkins}/Storage_Toolbox_Volume-chef.sh (100%) rename {jenkins => chef-templates/jenkins}/Update_R53_A_Record.sh (100%) rename {jenkins => chef-templates/jenkins}/attachments/chef (100%) rename {jenkins => chef-templates/jenkins}/attachments/libnss_rightscale.tgz (100%) rename {jenkins => chef-templates/jenkins}/attachments/rightscale_login_policy.te (100%) rename {jenkins => chef-templates/jenkins}/attachments/rs-ssh-keys.sh (100%) rename {jenkins => chef-templates/jenkins}/attachments/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar (100%) rename {jenkins => chef-templates/jenkins}/attachments/rsc_jenkins-201704183.tar (100%) rename {jenkins => chef-templates/jenkins}/jenkins.cat.rb (100%) delete mode 100755 jenkins/RL10_Linux_Enable_Managed_Login.sh delete mode 100755 jenkins/RL10_Linux_Enable_Monitoring.sh delete mode 100755 jenkins/RL10_Linux_Setup_Alerts.sh delete mode 100755 jenkins/RL10_Linux_Setup_Automatic_Upgrade.sh delete mode 100755 jenkins/RL10_Linux_Setup_Hostname.sh delete mode 100755 jenkins/RL10_Linux_Shutdown_Reason.sh delete mode 100755 jenkins/RL10_Linux_Upgrade.sh diff --git a/jenkins/CHANGELOG.md b/chef-templates/jenkins/CHANGELOG.md similarity index 100% rename from jenkins/CHANGELOG.md rename to chef-templates/jenkins/CHANGELOG.md diff --git a/jenkins/Jenkins-Master.yml b/chef-templates/jenkins/Jenkins-Master.yml similarity index 100% rename from jenkins/Jenkins-Master.yml rename to chef-templates/jenkins/Jenkins-Master.yml diff --git a/jenkins/Jenkins-Slave.yml b/chef-templates/jenkins/Jenkins-Slave.yml similarity index 100% rename from jenkins/Jenkins-Slave.yml rename to chef-templates/jenkins/Jenkins-Slave.yml diff --git a/jenkins/README.md b/chef-templates/jenkins/README.md similarity index 100% rename from jenkins/README.md rename to chef-templates/jenkins/README.md diff --git a/jenkins/RL10_Jenkins_Install_Master.sh b/chef-templates/jenkins/RL10_Jenkins_Install_Master.sh similarity index 100% rename from jenkins/RL10_Jenkins_Install_Master.sh rename to chef-templates/jenkins/RL10_Jenkins_Install_Master.sh diff --git a/jenkins/RL10_Jenkins_Install_Slave.sh b/chef-templates/jenkins/RL10_Jenkins_Install_Slave.sh similarity index 100% rename from jenkins/RL10_Jenkins_Install_Slave.sh rename to chef-templates/jenkins/RL10_Jenkins_Install_Slave.sh diff --git a/jenkins/RL5_6_10_Setup_Custom_Logrotate_Configs.sh b/chef-templates/jenkins/RL5_6_10_Setup_Custom_Logrotate_Configs.sh similarity index 100% rename from jenkins/RL5_6_10_Setup_Custom_Logrotate_Configs.sh rename to chef-templates/jenkins/RL5_6_10_Setup_Custom_Logrotate_Configs.sh diff --git a/jenkins/Storage_Toolbox_Backup-chef.sh b/chef-templates/jenkins/Storage_Toolbox_Backup-chef.sh similarity index 100% rename from jenkins/Storage_Toolbox_Backup-chef.sh rename to chef-templates/jenkins/Storage_Toolbox_Backup-chef.sh diff --git a/jenkins/Storage_Toolbox_Decommission-chef.sh b/chef-templates/jenkins/Storage_Toolbox_Decommission-chef.sh similarity index 100% rename from jenkins/Storage_Toolbox_Decommission-chef.sh rename to chef-templates/jenkins/Storage_Toolbox_Decommission-chef.sh diff --git a/jenkins/Storage_Toolbox_Schedule-chef.sh b/chef-templates/jenkins/Storage_Toolbox_Schedule-chef.sh similarity index 100% rename from jenkins/Storage_Toolbox_Schedule-chef.sh rename to chef-templates/jenkins/Storage_Toolbox_Schedule-chef.sh diff --git a/jenkins/Storage_Toolbox_Stripe-chef.sh b/chef-templates/jenkins/Storage_Toolbox_Stripe-chef.sh similarity index 100% rename from jenkins/Storage_Toolbox_Stripe-chef.sh rename to chef-templates/jenkins/Storage_Toolbox_Stripe-chef.sh diff --git a/jenkins/Storage_Toolbox_Volume-chef.sh b/chef-templates/jenkins/Storage_Toolbox_Volume-chef.sh similarity index 100% rename from jenkins/Storage_Toolbox_Volume-chef.sh rename to chef-templates/jenkins/Storage_Toolbox_Volume-chef.sh diff --git a/jenkins/Update_R53_A_Record.sh b/chef-templates/jenkins/Update_R53_A_Record.sh similarity index 100% rename from jenkins/Update_R53_A_Record.sh rename to chef-templates/jenkins/Update_R53_A_Record.sh diff --git a/jenkins/attachments/chef b/chef-templates/jenkins/attachments/chef similarity index 100% rename from jenkins/attachments/chef rename to chef-templates/jenkins/attachments/chef diff --git a/jenkins/attachments/libnss_rightscale.tgz b/chef-templates/jenkins/attachments/libnss_rightscale.tgz similarity index 100% rename from jenkins/attachments/libnss_rightscale.tgz rename to chef-templates/jenkins/attachments/libnss_rightscale.tgz diff --git a/jenkins/attachments/rightscale_login_policy.te b/chef-templates/jenkins/attachments/rightscale_login_policy.te similarity index 100% rename from jenkins/attachments/rightscale_login_policy.te rename to chef-templates/jenkins/attachments/rightscale_login_policy.te diff --git a/jenkins/attachments/rs-ssh-keys.sh b/chef-templates/jenkins/attachments/rs-ssh-keys.sh similarity index 100% rename from jenkins/attachments/rs-ssh-keys.sh rename to chef-templates/jenkins/attachments/rs-ssh-keys.sh diff --git a/jenkins/attachments/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar b/chef-templates/jenkins/attachments/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar similarity index 100% rename from jenkins/attachments/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar rename to chef-templates/jenkins/attachments/rs-storage-d669f08f87743e072eba619a3fba6a9c9dd6bc89.tar diff --git a/jenkins/attachments/rsc_jenkins-201704183.tar b/chef-templates/jenkins/attachments/rsc_jenkins-201704183.tar similarity index 100% rename from jenkins/attachments/rsc_jenkins-201704183.tar rename to chef-templates/jenkins/attachments/rsc_jenkins-201704183.tar diff --git a/jenkins/jenkins.cat.rb b/chef-templates/jenkins/jenkins.cat.rb similarity index 100% rename from jenkins/jenkins.cat.rb rename to chef-templates/jenkins/jenkins.cat.rb diff --git a/jenkins/RL10_Linux_Enable_Managed_Login.sh b/jenkins/RL10_Linux_Enable_Managed_Login.sh deleted file mode 100755 index 79792f1..0000000 --- a/jenkins/RL10_Linux_Enable_Managed_Login.sh +++ /dev/null @@ -1,323 +0,0 @@ -#!/bin/bash - -# --- -# RightScript Name: RL10 Linux Enable Managed Login -# Description: | -# Enable does install of RightScale NSS plugin, and update of PAM and SSH configuration to -# allow SSH connectivity to RightScale accounts. Disable undoes enablement. -# Inputs: -# MANAGED_LOGIN: -# Category: RightScale -# Description: To enable or disable managed login. Default is 'enable'. -# Input Type: single -# Required: true -# Advanced: true -# Default: text:auto -# Possible Values: -# - text:auto -# - text:enable -# - text:disable -# Attachments: -# - rs-ssh-keys.sh -# - rightscale_login_policy.te -# - libnss_rightscale.tgz -# ... - -set -e - -# Run passed-in command with retries if errors occur. -# -# $@: full line command -# -function retry_command() { - # Setting config variables for this function - retries=5 - wait_time=10 - - while [ $retries -gt 0 ]; do - # Reset this variable before every iteration to be checked if changed - issue_running_command=false - $@ || { issue_running_command=true; } - if [ "$issue_running_command" = true ]; then - (( retries-- )) - echo "Error occurred - will retry shortly" - sleep $wait_time - else - # Break out of loop since command was successful. - break - fi - done - - # Check if issue running command still existed after all retries - if [ "$issue_running_command" = true ]; then - echo "ERROR: Unable to run: '$@'" - return 1 - fi -} - -# Read/source os-release to obtain variable values determining OS -if [[ -e /etc/os-release ]]; then - source /etc/os-release -else - # CentOS/RHEL 6 does not use os-release, so use redhat-release - if [[ -e /etc/redhat-release ]]; then - # Assumed format example: CentOS release 6.7 (Final) - ID=$(cut -d" " -f1 /etc/redhat-release) - VERSION_ID=$(cut -d" " -f3 /etc/redhat-release) - else - echo "ERROR: /etc/os-release or /etc/redhat-release is required but does not exist" - exit 1 - fi -fi -ID="${ID,,}" # convert to lowercase - -# Determine location of rsc -[[ -e /usr/local/bin/rsc ]] && rsc=/usr/local/bin/rsc || rsc=/opt/bin/rsc - -# Determine lib_dir and bin_dir location -if [[ "$ID" == "coreos" ]]; then - lib_dir="/opt/lib" - bin_dir="/opt/bin" -else - lib_dir="/usr/local/lib" - bin_dir="/usr/local/bin" -fi - -if ! $rsc rl10 actions 2>/dev/null | grep --ignore-case --quiet /rll/login/control; then - echo "This script must be run on a RightLink 10.5 or newer instance" - exit 1 -fi - -if [[ "$MANAGED_LOGIN" == "auto" ]]; then - if [[ "$ID" == "coreos" ]]; then - echo "Managed login is not supported on CoreOS. Not setting up managed login." - managed_login="disable" - else - managed_login="enable" - fi -else - managed_login=$MANAGED_LOGIN -fi - -case "$managed_login" in -enable) - if [[ "$ID" == "coreos" ]]; then - echo "Managed login is not supported on CoreOS. MANAGED_LOGIN must be set to 'disabled' or 'auto'." - exit 1 - fi - - echo "Enabling managed login" - - # Ubuntu 12.04 has a version of OpenSSH that does not allow AuthorizedKeysCommand. Instead use AuthorizedKeysFile. - if [[ "$ID" == "ubuntu" && "$VERSION_ID" == "12.04" ]]; then - ssh_config_entry="AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 /var/lib/rightlink_keys/%u" - rll_login_control="compat" - if sudo cut --delimiter=# --fields=1 /etc/ssh/sshd_config | grep --invert-match "${ssh_config_entry}" | grep --quiet "AuthorizedKeysFile\b"; then - echo "AuthorizedKeysFile already in use. This is required to continue - exiting without configuring managed login" - exit 1 - elif sudo cut --delimiter=# --fields=1 /etc/ssh/sshd_config | grep --quiet "${ssh_config_entry}"; then - echo "AuthorizedKeysFile already setup" - ssh_previously_configured="true" - fi - else - # sshd does not have a version flag, but it does give a version on its error message for an invalid POSIX flag - sshd_version=`sshd -V 2>&1 | grep "^OpenSSH" | cut --delimiter=' ' --fields=1 | cut --delimiter='_' --fields=2` - ssh_config_entry="AuthorizedKeysCommand ${bin_dir}/rs-ssh-keys.sh" - rll_login_control="on" - if sudo cut --delimiter=# --fields=1 /etc/ssh/sshd_config | grep --invert-match "${ssh_config_entry}" | grep --quiet "AuthorizedKeysCommand\b"; then - echo "AuthorizedKeysCommand already in use. This is required to continue - exiting without configuring managed login" - exit 1 - elif sudo cut --delimiter=# --fields=1 /etc/ssh/sshd_config | grep --quiet "${ssh_config_entry}"; then - echo "AuthorizedKeysCommand already setup" - ssh_previously_configured="true" - fi - # OpenSSH version 6.2 and higher uses AuthorizedKeysCommand and requires AuthorizedKeysCommandUser - if [[ "$(printf "$sshd_version\n6.2" | sort --version-sort | tail --lines=1)" == "$sshd_version" ]]; then - ssh_config_entry+="\nAuthorizedKeysCommandUser nobody" - fi - fi - - if [[ "$ssh_previously_configured" != "true" ]]; then - # Generate SSH staging config and test that the config is valid. If valid, just copy the staging config later. - sshd_staging_config=$(mktemp /tmp/sshd_config.XXXXXXXXXX) - sudo cp -a /etc/ssh/sshd_config $sshd_staging_config - sudo bash -c "echo -e '\n${ssh_config_entry}' >> $sshd_staging_config" - # Test staging sshd_config file - if ! `sudo sshd -t -f $sshd_staging_config`; then - echo "sshd_config changes are invalid - exiting without configuring managed login" - exit 1 - fi - fi - - # Check that pam config for sshd exists - if [ ! -e /etc/pam.d/sshd ]; then - echo "Unable to determine location of required PAM sshd configuration - exiting without configuring managed login" - exit 1 - fi - - # Verify /var/lib/rightlink directory was created during install of RL10. Create if missing. - # It may be missing due to upgrade. - if [ ! -d /var/lib/rightlink ]; then - echo "Expected /var/lib/rightlink directory - creating" - sudo install --directory --group=rightlink --owner=rightlink --mode=0755 /var/lib/rightlink - fi - - # Create /var/lib/rightlink_keys directory created if set to 'compat' - if [[ "$rll_login_control" == "compat" ]]; then - sudo install --directory --group=root --owner=root --mode=0755 /var/lib/rightlink_keys - fi - - # Install $bin_dir/rs-ssh-keys.sh - echo "Installing ${bin_dir}/rs-ssh-keys.sh" - attachments=${RS_ATTACH_DIR:-attachments} - sudo install --target-directory=${bin_dir} --group=root --owner=root --mode=0755 ${attachments}/rs-ssh-keys.sh - - # Copy staging sshd_config file - if [[ "$ssh_previously_configured" != "true" ]]; then - sudo mv $sshd_staging_config /etc/ssh/sshd_config - # Determine if service name is ssh or sshd - case "$ID" in - ubuntu|debian) - ssh_service_name='ssh' - ;; - *) - ssh_service_name='sshd' - ;; - esac - sudo service ${ssh_service_name} restart - fi - - # Create /etc/sudoers.d/90-rightscale-sudo-users - if [ -e /etc/sudoers.d/90-rightscale-sudo-users ]; then - echo "Sudoers file already exists" - else - echo "Creating sudoers file" - sudo bash -c "umask 0337 && printf '# Members of the rightscale_sudo group may gain root privileges\n%%rightscale_sudo ALL=(ALL) SETENV:NOPASSWD:ALL\n' > /etc/sudoers.d/90-rightscale-sudo-users" - fi - - # Update pam config to create homedir on login - if cut --delimiter=# --fields=1 /etc/pam.d/sshd | grep --quiet pam_mkhomedir; then - echo "PAM config /etc/pam.d/sshd already contains pam_mkhomedir" - else - echo "Adding pam_mkhomedir to /etc/pam.d/sshd" - sudo bash -c "printf '# Added by RightScale Managed Login script\nsession required pam_mkhomedir.so skel=/etc/skel/ umask=0022\n' >> /etc/pam.d/sshd" - fi - - # Update nsswitch.conf - if cut --delimiter=# --fields=1 /etc/nsswitch.conf | grep --quiet rightscale; then - echo "/etc/nsswitch.conf already configured" - else - echo "Configuring /etc/nsswitch.conf" - sudo sed -i '/^\(passwd\|group\|shadow\)/ s/$/ rightscale/' /etc/nsswitch.conf - fi - - # Install NSS plugin library. This has been designed to overwrite existing library. - sudo mkdir -p /etc/ld.so.conf.d ${lib_dir} - sudo tar --no-same-owner -xzf ${attachments}/libnss_rightscale.tgz -C ${lib_dir} - sudo bash -c "echo ${lib_dir} > /etc/ld.so.conf.d/rightscale.conf" - sudo ldconfig - - # Configure selinux to allow sshd and pam to read the login policy file at - # /var/lib/rightlink/login_policy. This policy adds the following rules, as - # well as make the user's homedir on the fly. - if which sestatus >/dev/null 2>&1; then - if sudo sestatus | grep enabled >/dev/null 2>&1; then - # install checkmodule if it is not installed - if ! which checkmodule >/dev/null 2>&1; then - case "$ID" in - ubuntu|debian) - retry_command sudo apt-get install -y checkpolicy - ;; - centos|fedora|rhel) - retry_command sudo yum install -y checkpolicy - ;; - esac - fi - - # install semodule_package if it is not installed - if ! which semodule_package >/dev/null 2>&1; then - case "$ID" in - ubuntu|debian) - retry_command sudo apt-get install -y policycoreutils - ;; - centos|fedora|rhel) - retry_command sudo yum install -y policycoreutils-python - ;; - esac - fi - - policy_file="${attachments}/rightscale_login_policy.te" - installed_version=$(sudo semodule -l | grep rightscale_login_policy | awk '{print $2}' | sed 's/\.//') - desired_version=$(grep module $policy_file | awk '{print $3}' | sed 's/[\.;]//g') - if [[ "$desired_version" == "$installed_version" ]]; then - echo "rightscale_login_policy selinux policy already installed, skipping re-installation." - else - echo "Installing selinux policy to support reading of login policy file and creation of homedir" - checkmodule -M -m -o rightscale_login_policy.mod $policy_file - semodule_package -m rightscale_login_policy.mod -o rightscale_login_policy.pp - sudo semodule -i rightscale_login_policy.pp - fi - fi -fi - - # Send enable action to RightLink - $rsc --retry=5 --timeout=10 rl10 update /rll/login/control "enable_login=${rll_login_control}" - - # Adding rs_login:state=user tag - $rsc --retry=5 --timeout=60 --rl10 cm15 multi_add /api/tags/multi_add resource_hrefs[]=$RS_SELF_HREF tags[]=rs_login:state=user - ;; -disable) - if [[ "$ID" == "coreos" ]]; then - exit 0 - fi - - echo "Disabling managed login" - - # Remove rs_login:state=user tag - $rsc --retry=5 --timeout=60 --rl10 cm15 multi_delete /api/tags/multi_delete resource_hrefs[]=$RS_SELF_HREF tags[]=rs_login:state=user - - # Send disable action to RightLink - $rsc --retry=5 --timeout=10 rl10 update /rll/login/control "enable_login=off" - - # Remove NSS plugin library files - sudo rm -frv $lib_dir/libnss_rightscale.* - sudo rm -frv /etc/ld.so.conf.d/rightscale.conf - sudo ldconfig - - # Remove rightscale NSS plugin from /etc/nsswitch.conf - sudo sed -i '/^\(passwd\|group\|shadow\)/ s/\s\?rightscale\s*/ /; s/\s*$//' /etc/nsswitch.conf - - # Remove pam_mkhomedir line from /etc/pam.d/sshd - sudo sed -i '/^# Added by RightScale Managed Login script$/ {N; /^#.*session required pam_mkhomedir.so skel=\/etc\/skel\/ umask=0022$/d}' /etc/pam.d/sshd - - # Remove sudoers file - sudo rm -frv /etc/sudoers.d/90-rightscale-sudo-users - - # Remove AuthorizedKeysCommand and AuthorizedKeysCommandUser from sshd_config - sudo sed -i '/^AuthorizedKeysCommand \/usr\/local\/bin\/rs-ssh-keys.sh$/d' /etc/ssh/sshd_config - sudo sed -i '/^AuthorizedKeysCommandUser nobody$/d' /etc/ssh/sshd_config - sudo sed -i '/^AuthorizedKeysFile .ssh\/authorized_keys .ssh\/authorized_keys2 \/var\/lib\/rightlink_keys\/%u$/d' /etc/ssh/sshd_config - - # Remove rs-ssh-keys.sh - sudo rm -frv $bin_dir/rs-ssh-keys.sh - - # Remove /var/lib/rightlink folder - sudo rm -frv /var/lib/rightlink/ - - # Remove /var/lib/rightlink_keys folder - sudo rm -frv /var/lib/rightlink_keys/ - - # Remove rightscale managed login selinux policy - if which sestatus >/dev/null 2>&1; then - if sudo sestatus | grep enabled >/dev/null 2>&1; then - if sudo semodule -l | grep rightscale_login_policy >/dev/null 2>&1; then - sudo semodule -r rightscale_login_policy - fi - fi - fi - ;; -*) - echo "Unknown action: $managed_login" - exit 1 - ;; -esac diff --git a/jenkins/RL10_Linux_Enable_Monitoring.sh b/jenkins/RL10_Linux_Enable_Monitoring.sh deleted file mode 100755 index d3d161b..0000000 --- a/jenkins/RL10_Linux_Enable_Monitoring.sh +++ /dev/null @@ -1,472 +0,0 @@ -#! /bin/bash -e - -# --- -# RightScript Name: RL10 Linux Enable Monitoring -# Description: | -# Chose to either enable built-in RightLink monitoring or install and setup collectd with basic set of plugins. -# Both methods work with RightScale TSS (Time Series Storage), a backend system for aggregating and -# displaying monitoring data. Using collectd will sent monitoring data to the RightLink process on the localhost -# as HTTP using the write_http plugin, which then forwards that data to the TSS servers over HTTPS with authentication. -# -# ## Known Limitations: -# Choosing to use use collectd on very small instance types (less than 1GB memory) may result in a failure -# to install "collectd_tcp_network_connect" because of a lack of memory. -# This can be worked around by adding a 1GB or larger swap file to your server prior to running this script. -# Inputs: -# RS_INSTANCE_UUID: -# Category: RightScale -# Description: If using collectd, the monitoring ID for this server. -# Input Type: single -# Required: true -# Advanced: true -# Default: env:RS_INSTANCE_UUID -# COLLECTD_SERVER: -# Category: RightScale -# Description: If using collectd, the FQDN or IP address of the remote collectd -# server. -# Input Type: single -# Required: true -# Advanced: true -# Default: env:RS_TSS -# MONITORING_METHOD: -# Category: RightScale -# Description: | -# Determine the method of monitoring to use, either RightLink monitoring or collectd. Setting to -# 'auto' will use code to select method. -# Input Type: single -# Required: true -# Advanced: true -# Default: text:auto -# Possible Values: -# - text:auto -# - text:collectd -# - text:rightlink -# Attachments: [] -# ... -# - -# Check if a file needs to be written. First checks if the target file exists and if so checks if the checksums of the -# target file and the temporary file match. -# -# $1: the target file path to be checked -# $2: the temporary file path with new contents to check against -# -function run_check_write_needed() { - sudo [ ! -f $1 ] || [[ `run_checksum $2` != `run_checksum $1` ]] -} - -# Get the SHA256 checksum of a file. -# -# $1: the file path to get the checksum from -# -function run_checksum() { - sudo sha256sum $1 | cut -d ' ' -f 1 -} - -# Add a temporary file to the list of temporary files to clean up on exit. -# -# $@: one or more file paths to add to the list -# -function add_mktemp_file() { - mktemp_files=("$@" "${mktemp_files[@]}") -} - -# Configure a collectd plugin. -# -# $1: the name of the collectd plugin to configure -# $@: zero or more configuration options to set -# -function configure_collectd_plugin() { - local collectd_plugin=$1 - # Remove $1 from $@ - shift - local collectd_plugin_conf="$collectd_conf_plugins_dir/${collectd_plugin}.conf" - # Create a temporary file for the collectd plugin configration - local collectd_plugin_conf_tmp=`sudo mktemp "${collectd_plugin_conf}.XXXXXXXXXX"` - add_mktemp_file $collectd_plugin_conf_tmp - - sudo dd of="$collectd_plugin_conf_tmp" 2>/dev/null </dev/null < -EOF - - for option in "$@"; do - sudo bash -c "echo ' $option' >> $collectd_plugin_conf_tmp" - done - sudo bash -c "echo '' >> $collectd_plugin_conf_tmp" - fi - - # Overwrite and backup the collectd plugin configration if it has changed - if run_check_write_needed $collectd_plugin_conf $collectd_plugin_conf_tmp; then - sudo chmod 0644 $collectd_plugin_conf_tmp - sudo [ -f $collectd_plugin_conf ] && sudo cp --archive $collectd_plugin_conf "${collectd_plugin_conf}.`date -u +%Y%m%d%H%M%S`" - sudo mv --force $collectd_plugin_conf_tmp $collectd_plugin_conf - collectd_service_notify=1 - fi - - echo "collectd plugin $collectd_plugin configured" -} - -# Run passed-in command with retries if errors occur. -# -# $@: full line command -# -function retry_command() { - # Setting config variables for this function - retries=5 - wait_time=10 - - while [ $retries -gt 0 ]; do - # Reset this variable before every iteration to be checked if changed - issue_running_command=false - $@ || { issue_running_command=true; } - if [ "$issue_running_command" = true ]; then - (( retries-- )) - echo "Error occurred - will retry shortly" - sleep $wait_time - else - # Break out of loop since command was successful. - break - fi - done - - # Check if issue running command still existed after all retries - if [ "$issue_running_command" = true ]; then - echo "ERROR: Unable to run: '$@'" - return 1 - fi -} - -# Ensure rsc is in the path -export PATH="/usr/local/bin:/opt/bin:$PATH" - -# Determine what mode to use if MONITORING_METHOD is set to 'auto' -if [[ "$MONITORING_METHOD" == "auto" ]]; then - # Currently, the only criteria to automatically use RightLink monitoring is if OS is CoreOS - if grep -iq "id=coreos" /etc/os-release 2> /dev/null; then - monitoring_method="rightlink" - else - monitoring_method="collectd" - fi -else - monitoring_method=$MONITORING_METHOD -fi - -# Determine which network interfaces exist excluding lo so we can configure collectd -interfaces=(`ip -o link | awk '{ sub(/:$/, "", $2); if ($2 != "lo") { print $2; } }'`) - -# Determine if swap is enabled -if [[ $(sudo swapon -s | wc -l) -gt 1 ]]; then - swap=1 -else - swap=0 -fi - -# Determine if using RightLink monitoring or collectd -if [[ "$monitoring_method" == "rightlink" ]]; then - # Enable built-in monitoring - echo "Using RightLink monitoring" - rsc --retry=5 --timeout=10 rl10 update /rll/tss/control enable_monitoring=all -else - # Initialize variables - if [[ ! "$COLLECTD_SERVER" =~ tss ]]; then - echo "ERROR: This script will only run on a TSS enabled account. Contact RightScale Support to enable." - exit 1 - fi - echo "Using collectd for monitoring" - - # TSS is compatible with both collectd 4 and 5 while the previous monitoring backend - # only supported collectd 4. We forward ported collectd 4 to newer OSes b/c of this. - # If we installed a custom forward port of collectd4 previously, remove it now to - # replace it with OS standard collectd. - if which apt-get >/dev/null 2>&1; then - if [[ -e /etc/apt/preferences.d/rightscale-collectd-pin-1001 ]]; then - sudo rm /etc/apt/preferences.d/rightscale-collectd-pin-1001 - fi - rs_version="$(apt-cache showpkg collectd-core | grep rightscale | head -n 1 | awk '{print $1}')" - if [[ -n "$rs_version" ]]; then - installed_version=$(dpkg -l | grep '^ii' | grep collectd-core | awk '{print $3}') - if [[ "$installed_version" == "$rs_version" ]]; then - echo "Removing collectd 4 package" - retry_command sudo apt-get purge -y collectd collectd-core - fi - fi - elif yum list collectd 2>&1 | grep '@rightscale-epel' >/dev/null 2>&1; then - if grep collectd-4 /etc/yum/pluginconf.d/versionlock.list >/dev/null 2>&1; then - sudo sed -i '/collectd/d' /etc/yum/pluginconf.d/versionlock.list - fi - echo "Removing collectd 4 package" - retry_command sudo yum remove -y "collectd*" - fi - - # Collectd package is located in the EPEL repository. Install if its not already - # installed. - if [[ -e /etc/redhat-release ]]; then - if [[ `cat /etc/redhat-release` =~ ^([^0-9]+)\ ([0-9])\. ]]; then - distro="${BASH_REMATCH[1]}" - ver="${BASH_REMATCH[2]}" - else - echo "Could not parse distro and version from /etc/redhat-release" - exit 1 - fi - - case "$ver" in - 6) - if ! yum list installed "epel-release-6*"; then - echo "Installing EPEL repository" - retry_command sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm - if [[ "$distro" =~ CentOS ]]; then - # versions of CentOS 6.x have trouble with https... - sudo sed -i 's/https/http/' /etc/yum.repos.d/epel.repo - fi - fi - ;; - 7) - if ! yum list installed "epel-release-7*"; then - echo "Installing EPEL repository" - retry_command sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm - fi - ;; - esac - fi - - - # Declare a list for temporary files to clean up on exit and set the command to delete them if they still exist when the - # script exits - declare -a mktemp_files - trap 'sudo rm --force "${mktemp_files[@]}"' EXIT - - collectd_base_dir=/var/lib/collectd - collectd_types_db=/usr/share/collectd/types.db - collectd_interval=20 - collectd_read_threads=5 - collectd_server_port=3011 - collectd_service=collectd - collectd_service_notify=0 - - if [[ -d /etc/apt ]]; then - collectd_conf_dir=/etc/collectd - collectd_conf_plugins_dir="$collectd_conf_dir/plugins" - collectd_plugin_dir=/usr/lib/collectd - elif [[ -d /etc/yum.repos.d ]]; then - collectd_conf_dir=/etc - collectd_conf_plugins_dir="$collectd_conf_dir/collectd.d" - collectd_plugin_dir=/usr/lib64/collectd - else - echo "unsupported distribution!" - exit 1 - fi - - collectd_conf="$collectd_conf_dir/collectd.conf" - collectd_collection_conf="$collectd_conf_dir/collection.conf" - collectd_thresholds_conf="$collectd_conf_dir/thresholds.conf" - - # Install platform specific collectd packages - if [[ -d /etc/apt ]]; then - # Resync the package index with sources - retry_command sudo apt-get update -y - retry_command sudo apt-get install -y curl collectd-core - elif [[ -d /etc/yum.repos.d ]]; then - # Workaround for broken collectd - if yum info collectd | grep -E '5.6.1|5.6.0'; then - if rpm -qi collectd | grep -E '5.6.1|5.6.0'; then - retry_command sudo yum remove -y collectd - fi - echo "Collectd v5.6.0 or v5.6.1 detected. Collectd write_http plugin is temporarily broken for CentOS/RHEL operating systems." - echo "See: https://github.com/collectd/collectd/issues/1996" - echo "Falling back to using RightLink monitoring" - rsc --retry=5 --timeout=10 rl10 update /rll/tss/control enable_monitoring=all - exit 0 - fi - - # keep these lines separate, yum doesn't fail for missing packages when grouped together - retry_command sudo yum install -y curl - retry_command sudo yum install -y collectd - fi - - # For TSS, collectd connects to the rightlink process, which runs with a random - # high port for localhost (127.0.0.1). Without this permission relaxed, we'll get - # permission denied connecting to that local ip - if sestatus 2>/dev/null | grep "SELinux status" | grep enabled; then - # Existence check - on CentOS 6 this variable doesn't exist and isn't needed - if getsebool collectd_tcp_network_connect >/dev/null 2>&1; then - echo "Setting SELinux variable collectd_tcp_network_connect to on" - sudo setsebool -P collectd_tcp_network_connect 1 - fi - fi - - sudo mkdir --mode=0755 --parents $collectd_conf_plugins_dir $collectd_base_dir $collectd_plugin_dir - - # Create a temporary file for the collectd configuration - collectd_conf_tmp=`sudo mktemp "${collectd_conf}.XXXXXXXXXX"` - add_mktemp_file $collectd_conf_tmp - - sudo dd of="$collectd_conf_tmp" 2>/dev/null </dev/null </dev/null < -# -# WarningMin 0.00 -# WarningMax 1000.00 -# FailureMin 0 -# FailureMax 1200.00 -# Invert false -# Persist false -# Instance "some_instance" -# -# -# -# Instance "eth0" -# -# DataSource "rx" -# FailureMax 10000000 -# -# -# -# -# -# Instance "idle" -# FailureMin 10 -# -# -# -# -# Instance "cached" -# WarningMin 100000000 -# -# -# -# -EOF - - # Overwrite and backup the collectd thresholds configuration if it has changed - if run_check_write_needed $collectd_thresholds_conf $collectd_thresholds_conf_tmp; then - sudo chmod 0644 $collectd_thresholds_conf_tmp - [[ -f $collectd_thresholds_conf ]] && sudo cp --archive $collectd_thresholds_conf "${collectd_thresholds_conf}.`date -u +%Y%m%d%H%M%S`" - sudo mv --force $collectd_thresholds_conf_tmp $collectd_thresholds_conf - collectd_service_notify=1 - fi - - configure_collectd_plugin syslog - - # Configure interface monitoring for all qualifying interfaces - declare -a interface_configs - for interface in "${interfaces[@]}"; do - interface_configs[${#interface_configs[@]}]="Interface \"$interface\"" - done - - configure_collectd_plugin interface \ - "${interface_configs[@]}" - - configure_collectd_plugin cpu - configure_collectd_plugin df \ - 'ReportReserved false' \ - 'FSType "proc"' \ - 'FSType "sysfs"' \ - 'FSType "fusectl"' \ - 'FSType "debugfs"' \ - 'FSType "securityfs"' \ - 'FSType "devtmpfs"' \ - 'FSType "devpts"' \ - 'FSType "tmpfs"' \ - 'IgnoreSelected true' - configure_collectd_plugin disk - configure_collectd_plugin memory - - if [[ $swap -eq 1 ]]; then - configure_collectd_plugin swap - else - echo "swapfile not setup, skipping collectd swap plugin" - fi - - # Populate RS_RLL_PORT - source /var/run/rightlink/secret - rsc --retry=5 --timeout=10 rl10 update /rll/tss/control enable_monitoring=util - collectd_ver=5 - if [[ "$(collectd -h)" =~ "collectd 4" ]]; then - collectd_ver=4 - fi - configure_collectd_plugin write_http \ - "URL \"http://127.0.0.1:$RS_RLL_PORT/rll/tss/collectdv$collectd_ver\"" - configure_collectd_plugin load - configure_collectd_plugin processes - configure_collectd_plugin users - - - # Make sure the collectd service is enabled - if [[ -d /etc/yum.repos.d ]]; then - sudo chkconfig $collectd_service on - fi - - if collectd -T 2>&1 | grep 'Parse error' >/dev/null 2>&1; then - echo "ERROR: collectd config contains syntax errors:" - collectd -T - exit 1 - fi - - # Start the collectd service if it is not running or restart it if it needs to be restarted - if ! sudo service $collectd_service status; then - sudo service $collectd_service start - elif [[ $collectd_service_notify -eq 1 ]]; then - sudo service $collectd_service restart - fi -fi diff --git a/jenkins/RL10_Linux_Setup_Alerts.sh b/jenkins/RL10_Linux_Setup_Alerts.sh deleted file mode 100755 index 4cc6c78..0000000 --- a/jenkins/RL10_Linux_Setup_Alerts.sh +++ /dev/null @@ -1,239 +0,0 @@ -#!/bin/bash -# --- -# RightScript Name: RL10 Linux Setup Alerts -# Description: | -# Set up the RightScale Alerts on the instance to match the metrics that it is actually reporting with either built-in -# RightLink monitoring or collectd. The RightScale Alerts on this ServerTemplate are set to match the metrics reported -# by the built-in RightLink monitoring and collectd 5, but there are a few metrics which have names which vary based -# on the system they are running and there are also some metrics which have different names with collectd 4 which is -# used on older Linux distribution versions (such as Ubuntu 12.04 and CentOS 6). -# -# The alerts that need to be set up by this script are: -# -# * **rs low space in root partition**: If a Linux system is running collectd 4, the metric used for this alert will -# be set to `df/df-root.free` rather than `df-root/df_complex-free.value`. -# * **rs high network tx activity** and **rs high network rx activity**: On newer Linux distribution versions (such as -# CoreOS and Ubuntu 16.04) the network interface name is not necessarily `eth0` and there may be more network -# interfaces on the system, so this script will update and add the alerts to match the network interfaces on the -# system. -# * **rs low swap space**: If no swap is set up on a Linux system, no swap metrics will be sent. If you enable swap on -# the system at a later point, this script can be rerun to re-enable the alert. -# Inputs: -# MONITORING_METHOD: -# Category: RightScale -# Description: | -# Determine the method of monitoring to use, either RightLink monitoring or collectd. Setting to -# 'auto' will use code to select method. -# Input Type: single -# Required: true -# Advanced: true -# Default: text:auto -# Possible Values: -# - text:auto -# - text:collectd -# - text:rightlink -# Attachments: [] -# ... - -set -e - -# Create an alert spec on the instance based on a template alert spec from the ServerTemplate with optional parameter -# overrides. -# -# $1: the alert spec template name -# $2: the instance name to append to the template name which is used to name the new alert spec -# $@: the rest of the arguments are parameter name and override value pairs for the new alert spec -# -function create_alert_spec() { - local template_name="$1" - local name="$template_name $2" - shift 2 # remove the first two arguments from $@ - echo -n "creating alert spec '$name' from '${template_name}': " - if [[ $# -ne 0 ]]; then - echo -n 'overriding ' - local -i index=0 - for override in "$@"; do - if [[ $(((index += 1) % 2)) -eq 1 ]]; then - echo -n "$override=" - else - echo -n "'$override' " - fi - done - echo -n '... ' - fi - - # check in the alert specs to see if the one we want to create is already created - if rsc json --x1 "object:has(.name:val(\"$name\"))" <<<"$alert_specs" 1>/dev/null 2>&1; then - echo 'already exists' - return - fi - - # create an associative array of the parameters with our new name and all of the other parameters from the template - # alert spec - local -A parameters=([name]="$name") - for parameter in condition description duration escalation_name file threshold variable vote_tag vote_type; do - value=`rsc json --x1 "object:has(.name:val(\"$template_name\")).$parameter" <<<"$alert_specs" 2>/dev/null || true` - if [[ -n "$value" ]]; then - parameters[$parameter]="$value" - fi - done - - # iterate through the rest of the arguments to override any parameters - while [[ $# -gt 0 ]]; do - local parameter="$1" - local value="$2" - parameters[$parameter]="$value" - shift 2 # remove these two arguments from $@ - done - - # transform the associative array of parameters into an array of arguments for rsc - local -a arguments - for parameter in "${!parameters[@]}"; do - arguments[${#arguments[@]}]="alert_spec[$parameter]=${parameters[$parameter]}" - done - - # use rsc to create the new alert spec with the parameters as arguments - rsc --rl10 cm15 create "$RS_SELF_HREF/alert_specs" "${arguments[@]}" - echo 'created' -} - -# Destroy an alert if the matching alert spec is defined on the ServerTemplate or destroy an alert spec if it is defined -# on the instance. No action will be taken if the alert or alert spec has already been destroyed or does not otherwise -# exist. -# -# $1: the name of the alert spec to destroy the alert for or to just destroy -# -function destroy_alert_or_alert_spec() { - local name="$1" - echo -n "destroying alert or alert spec '$name' from instance: ... " - - # check if the alert or alert spec has already been destroyed - if ! alert_for_alert_spec_exists "$name"; then - echo 'already destroyed' - return - fi - - # destroy the alert if the alert spec is inherited from the ServerTemplate or delete the alert spec otherwise - if [[ $subject_href =~ ^/api/server_templates/[^/]+$ ]]; then - alert_href=`rsc json --xj "object:has(.href:val(\"$alert_spec_href\")) ~ object" <<<"$alerts" | rsc json --x1 'object:has(.rel:val("self")).href'` - rsc --rl10 cm15 destroy "$alert_href" - else - rsc --rl10 cm15 destroy "$alert_spec_href" - fi - - echo 'destroyed' -} - -# Check if an alert for an alert spec exists on the instance. -# -# $1: the name of the alert spec to check for -# -# Output variables: -# -# alert_spec_href: the HREF of the named alert spec -# subject_href: the HREF of the subject of the named alert spec -# -function alert_for_alert_spec_exists() { - local name="$1" - - # get the alert spec and subject HREFs for the named alert spec - alert_spec_href=`rsc json --x1 "object:has(.name:val(\"$name\")) object:has(.rel:val(\"self\")).href" <<<"$alert_specs" 2>/dev/null` - subject_href=`rsc json --x1 "object:has(.name:val(\"$name\")) object:has(.rel:val(\"subject\")).href" <<<"$alert_specs" 2>/dev/null` - - # check if the alert spec HREF was found - if [[ -n $alert_spec_href ]]; then - if [[ $subject_href =~ ^/api/server_templates/[^/]+$ ]]; then - # the subject of the alert spec is a ServerTemplate so the alert spec is inherited - # check if there is an alert for the alert spec - if rsc json --x1 "object:has(.href:val(\"$alert_spec_href\"))" <<<"$alerts" 1>/dev/null 2>&1; then - # an alert for the alert spec exists - return 0 - else - # there is no alert for the alert spec - return 1 - fi - else - # the alert spec is not inherited from the ServerTemplate and it exists so it definitely exists - return 0 - fi - else - # there was no alert spec HREF found so the named alert spec does not exist - return 1 - fi -} - -# Ensure rsc is in the path -export PATH="/usr/local/bin:/opt/bin:$PATH" - -# Determine what mode to use if MONITORING_METHOD is set to 'auto' -if [[ "$MONITORING_METHOD" == "auto" ]]; then - # Currently, the only criteria to automatically use RightLink monitoring is if OS is CoreOS - if grep -iq "id=coreos" /etc/os-release 2> /dev/null; then - monitoring_method="rightlink" - else - monitoring_method="collectd" - fi -else - monitoring_method=$MONITORING_METHOD -fi - -# Determine which network interfaces exist excluding lo so we can update alert specs -interfaces=(`ip -o link | awk '{ sub(/:$/, "", $2); if ($2 != "lo") { print $2; } }'`) - -# Determine if swap is enabled -if [[ $(sudo swapon -s | wc -l) -gt 1 ]]; then - swap=1 -else - swap=0 -fi - -# get all of the alert specs and alerts defined on the instance; these variables are used with rsc json by the above -# functions instead of making individual API calls to query this data -alert_specs=`rsc --rl10 cm15 index "$RS_SELF_HREF/alert_specs" with_inherited=true` -[[ -z "$alert_specs" ]] && alert_specs='{}' -alerts=`rsc --rl10 cm15 index "$RS_SELF_HREF/alerts"` -[[ -z "$alerts" ]] && alerts='{}' - -if [[ $swap -eq 0 ]]; then - # if swap is not enabled, remove the swap alert - destroy_alert_or_alert_spec 'rs low swap space' - destroy_alert_or_alert_spec 'rs low swap space recreated' -else - # if swap was previously disabled, recreate the alert now that it is enabled - if ! alert_for_alert_spec_exists 'rs low swap space' && ! alert_for_alert_spec_exists 'rs low swap space recreated'; then - create_alert_spec 'rs low swap space' recreated - fi -fi - -disable_eth0=1 # by default remove the original network alert specs -reenable_eth0=0 # by default do not create new network alert specs for eth0 -interface_file='interface-eth0/if_octets' # this is the format for the network metric for collectd 5 and built-in - -if [[ $monitoring_method == collectd && "$(collectd -h)" =~ "collectd 4" ]]; then - # change the root partition alert to use the collectd4 metric - destroy_alert_or_alert_spec 'rs low space in root partition' - create_alert_spec 'rs low space in root partition' 'collectd4' file df/df-root variable free - - reenable_eth0=1 # since the metric for interfaces is different on collectd 4, the alert specs needs to be redefined - interface_file='interface/if_octets-eth0' # this is the format for the network metric for collectd 4 -fi - -for interface in "${interfaces[@]}"; do - # if the interface is eth0 and the network does not need to be redefined, do not create a new alert spec - if [[ "$interface" == eth0 && $reenable_eth0 -eq 0 ]]; then - echo -e "keeping 'rs high network tx activity'\nkeeping 'rs high network rx activity'" - disable_eth0=0 # since the eth0 interface exists do not remove the original network alerts - continue - fi - - # add network alert specs for this network interface by replacing eth0 in the network metric format with the actual - # interface name - create_alert_spec 'rs high network tx activity' "$interface" file "${interface_file/eth0/$interface}" - create_alert_spec 'rs high network rx activity' "$interface" file "${interface_file/eth0/$interface}" -done - -# if there is no eth0 interface or the network alerts needed to be redefined for collectd 4, remove the original alerts -if [[ disable_eth0 -eq 1 ]]; then - destroy_alert_or_alert_spec 'rs high network tx activity' - destroy_alert_or_alert_spec 'rs high network rx activity' -fi diff --git a/jenkins/RL10_Linux_Setup_Automatic_Upgrade.sh b/jenkins/RL10_Linux_Setup_Automatic_Upgrade.sh deleted file mode 100755 index b0c69cb..0000000 --- a/jenkins/RL10_Linux_Setup_Automatic_Upgrade.sh +++ /dev/null @@ -1,119 +0,0 @@ -#! /bin/bash -e - -# --- -# RightScript Name: RL10 Linux Setup Automatic Upgrade -# Description: Subscribes to receive updates to the RightLink agent automatically. Creates -# a cron job that performs a daily check to see if an upgrade to RightLink is available -# and upgrades if there is. -# Inputs: -# ENABLE_AUTO_UPGRADE: -# Category: RightScale -# Description: Enables or disables automatic upgrade of RightLink10. -# Input Type: single -# Required: false -# Advanced: true -# Default: text:true -# Possible Values: -# - text:true -# - text:false -# UPGRADES_FILE_LOCATION: -# Category: RightScale -# Description: External location of 'upgrades' file -# Input Type: single -# Required: false -# Advanced: true -# Default: text:https://rightlink.rightscale.com/rightlink/upgrades -# Attachments: [] -# ... -# - -# Determine directory location of rightlink / rsc -[[ -e /usr/local/bin/rsc ]] && bin_dir=/usr/local/bin || bin_dir=/opt/bin -rsc=${bin_dir}/rsc - -# Will compare current version of rightlink 'running' with latest version provided from 'upgrades' -# file. If they differ, will update to latest version. Note that latest version can be an older version -# if a downgrade is best as found in the $UPGRADES_FILE_LOCATION -UPGRADES_FILE_LOCATION=${UPGRADES_FILE_LOCATION:-"https://rightlink.rightscale.com/rightlink/upgrades"} - -# Add entry in /etc/cron.d/ to check and execute an upgrade for rightlink daily. -cron_file='/etc/cron.d/rightlink-upgrade' -exec_file="${bin_dir}/rightlink_check_upgrade" -# Add entry in /etc/systemd/system if system doesn't support cron -service_file='/etc/systemd/system/rightlink-upgrade.service' -timer_file='/etc/systemd/system/rightlink-upgrade.timer' - -# Grab toggle option to enable -if [[ "$ENABLE_AUTO_UPGRADE" == "false" ]]; then - if [[ -e $exec_file ]]; then - sudo rm -f ${timer_file} ${cron_file} ${exec_file} ${service_file} - echo "Automatic upgrade disabled." - else - echo "Automatic upgrade never enabled - no action done" - fi -else - # If cron file already exists, will recreate it and update cron config with new random times. - scheduled_hour=$(( $RANDOM % 24 )) - scheduled_minute=$(( $RANDOM % 60 )) - - # Generate executable script to run by cron - sudo dd of="${exec_file}" 2>/dev/null </dev/null) =~ CoreOS ]]; then - # Generate service file to be executed by systemd timers - sudo dd of="${service_file}" 2>/dev/null </dev/null < ${cron_file}" - - # Set perms regardless of umask since the file could be overwritten with existing perms. - sudo chmod 0600 ${cron_file} - echo "Configured cron file at ${cron_file} to run daily." - fi - - echo "Subscribed to receive upgrades from ${UPGRADES_FILE_LOCATION}." - echo "Automatic upgrade enabled." -fi diff --git a/jenkins/RL10_Linux_Setup_Hostname.sh b/jenkins/RL10_Linux_Setup_Hostname.sh deleted file mode 100755 index 9d9d372..0000000 --- a/jenkins/RL10_Linux_Setup_Hostname.sh +++ /dev/null @@ -1,181 +0,0 @@ -#! /bin/bash -e - -# --- -# RightScript Name: RL10 Linux Setup Hostname -# Description: | -# Changes the hostname of the server. -# -# ## Known Limitations: -# On AzureRM, the Azure Linux Agent (waagent) may change the hostname if it has not finished provisioning the server after boot. -# Inputs: -# SERVER_HOSTNAME: -# Category: RightScale -# Description: The server's hostname is set to the longest valid prefix or suffix -# of this variable. E.g. 'my.example.com V2', 'NEW my.example.com', and 'database.io -# my.example.com' all set the hostname to 'my.example.com'. Set to an empty string -# to avoid any change to the hostname. -# Input Type: single -# Required: false -# Advanced: true -# Default: blank -# Attachments: [] -# ... -# - -# The server's hostname is set to the longest valid prefix or suffix of -# this SERVER_HOSTNAME variable eg 'my.example.com V2', 'NEW my.example.com', and -# 'database.io my.example.com' all set the hostname to 'my.example.com'. -# If SERVER_HOSTNAME is empty, will maintain current hostname. - -# Run passed-in command with retries if errors occur. -# -# $@: full line command -# -function retry_command() { - # Setting config variables for this function - retries=5 - wait_time=10 - - while [ $retries -gt 0 ]; do - # Reset this variable before every iteration to be checked if changed - issue_running_command=false - $@ || { issue_running_command=true; } - if [ "$issue_running_command" = true ]; then - (( retries-- )) - echo "Error occurred - will retry shortly" - sleep $wait_time - else - # Break out of loop since command was successful. - break - fi - done - - # Check if issue running command still existed after all retries - if [ "$issue_running_command" = true ]; then - echo "ERROR: Unable to run: '$@'" - return 1 - fi -} - -# Ensure rsc is in the path -export PATH="/usr/local/bin:/opt/bin:$PATH" - -# Give warning about the possibility of waagent on AzureRM changing the hostname again after this script -current_cloud_href=$(rsc --retry=5 --timeout=60 --rl10 cm15 index_instance_session /api/sessions/instance --x1 ':has(.rel:val("cloud")).href' 2>/dev/null || true) -cloud_type=$(rsc --retry=5 --timeout=60 --rl10 cm15 --x1='.cloud_type' show $current_cloud_href 2>/dev/null || true) -if [[ $cloud_type == "azure_v2" ]]; then - echo "WARNING: waagent on AzureRM may change the hostname after this script is completed!" - echo "See http://docs.rightscale.com/clouds/azure_resource_manager/reference/limitations.html#azure-linux-agent for more details" -fi - -if [[ -n "$SERVER_HOSTNAME" ]]; then - prefix= - suffix= - - re='^[-A-Za-z0-9_][-A-Za-z0-9_.]*[-A-Za-z0-9_]( #[0-9]+){0,1}' - if [[ "$SERVER_HOSTNAME" =~ $re ]]; then - prefix=${BASH_REMATCH[0]} - echo "prefix set to ${prefix}" - fi - - re='[-A-Za-z0-9_][-A-Za-z0-9._]*[-A-Za-z0-9_]( #[0-9]+){0,1}$' - if [[ "$SERVER_HOSTNAME" =~ $re ]]; then - suffix=${BASH_REMATCH[0]} - echo "suffix set to ${suffix}" - fi - - if (( ${#prefix} >= ${#suffix} && ${#prefix} > 1 )); then - echo "Setting hostname to prefix '$prefix'" - hostname="$prefix" - elif (( ${#suffix} > 1 )); then - echo "Setting hostname to suffix '$suffix'" - hostname="$suffix" - fi - - # - # Check for a numeric suffix (like in a server array) - # example: array_name #1 - # and convert into: array_name-1 - # - if [ $( echo $hostname | grep "#" -c ) -gt 0 ]; then - numeric_suffix=$( echo $hostname | cut -d'#' -f2 ) - hostname=$( echo $hostname | cut -d'#' -f1 ) - echo "Find array numeric suffix '$numeric_suffix'" - - sname=$(echo $hostname | cut -d'.' -f 1) - dname=${hostname#"$sname"} - hostname="$sname-$numeric_suffix$dname" - fi - - # Set the hostname and make it persist across reboots, etc. - # If we are on a system with hostnamectl, it will take care of all that, but if not there are several ways that the - # hostname may be stored. - if type -P hostnamectl >/dev/null; then - # even if hostnamectl is available, dbus might not be available so we install it - if ! type -P dbus-daemon >/dev/null; then - # Read/source os-release to obtain variable values determining OS - if [[ -e /etc/os-release ]]; then - source /etc/os-release - else - # CentOS/RHEL 6 does not use os-release, so use redhat-release - if [[ -e /etc/redhat-release ]]; then - # Assumed format example: CentOS release 6.7 (Final) - ID=$(cut -d" " -f1 /etc/redhat-release) - VERSION_ID=$(cut -d" " -f3 /etc/redhat-release) - else - echo "ERROR: /etc/os-release or /etc/redhat-release is required but does not exist" - exit 1 - fi - fi - - case "${ID,,}" in - ubuntu|debian) - retry_command sudo apt-get update - retry_command sudo apt-get install -y dbus - ;; - centos|fedora|rhel) - retry_command sudo yum install -y dbus - sudo chkconfig dbus on - sudo service dbus start - ;; - esac - fi - - # CentOS 7, CoreOS, and Ubuntu 14+ all use hostnamectl! - sudo hostnamectl set-hostname "$hostname" - else - if [[ -f /etc/sysconfig/network ]]; then - # CentOS 6 (and probably RHEL 6 as well) uses the /etc/sysconfig/network file to store the hostname - if grep --quiet '^HOSTNAME=' /etc/sysconfig/network; then - sudo sed --expression="s/^HOSTNAME=.*$/HOSTNAME=$hostname/" --in-place /etc/sysconfig/network - else - echo "HOSTNAME=$hostname" | sudo tee -a /etc/sysconfig/network - fi - else - # Ubuntu 12 uses /etc/hostname to store the hostname - echo "$hostname" | sudo tee /etc/hostname - fi - sudo hostname "$hostname" - fi - - # At least on CentOS 7, cloud-init can sometimes also try to manage the hostname, so configure cloud-init to not - # change the hostname - preserve_hostname='preserve_hostname: true' - if [[ -d /etc/cloud/cloud.cfg.d ]]; then - echo "$preserve_hostname" | sudo tee /etc/cloud/cloud.cfg.d/99_preserve_hostname.cfg - elif [[ -f /etc/cloud/cloud.cfg ]] && ! grep --quiet "$preserve_hostname" /etc/cloud/cloud.cfg; then - echo "$preserve_hostname" | sudo tee -a /etc/cloud/cloud.cfg - fi -fi - -# This works around spurious warnings generated by sudo if the hostname can't resolve. -# /etc/sudoers is designed to be able to be distributed among multiple servers. -# Each permission in the /etc/sudoers has a host portion. Sudo does a hostname -# lookup to enforce the host portion, and will throw a warning if it can't -# resolve the hostname in some way. - -hostname=$(hostname) -if ! grep "$hostname" /etc/hosts >/dev/null 2>&1; then - echo "Adding $hostname to /etc/hosts" - echo "127.0.0.1 $hostname" | sudo tee -a /etc/hosts -fi diff --git a/jenkins/RL10_Linux_Shutdown_Reason.sh b/jenkins/RL10_Linux_Shutdown_Reason.sh deleted file mode 100755 index 04b4679..0000000 --- a/jenkins/RL10_Linux_Shutdown_Reason.sh +++ /dev/null @@ -1,73 +0,0 @@ -#! /bin/bash - -# --- -# RightScript Name: RL10 Linux Shutdown Reason -# Description: Print out the reason for shutdown. -# Inputs: {} -# Attachments: [] -# ... -# - -# We pull the runlevel or equivalent from the init system and call it -# os_decom_reason. os_decom_reason possible values are: -# shutdown = system is halting, powering off, or going into single user mode -# reboot = system is rebooting -# service_restart = service was restarted -# -# We pull the reason RightScale thinks the instance is going down and put it in -# rs_decom_reason. Note that this variable will only be populated if we issue a -# stop/terminate/reboot from either the RightScale dashboard or the API. It will -# be empty if we shutdown or rebooted at the command line, or if a shutdown/reboot -# was issued on the cloud provider's console. Note we can't tell if a terminate -# was issued on a cloud provider's console, as we just know the system is going -# down. rs_decom_reason possible values are: -# stop = instance is being stopped/shutdown but disk persists -# terminate = instance is being destroyed/deleted -# reboot = instance is being rebooted -# -# DECOM_REASON synthesizes the two values. We export this value as an environment -# parameter so subsequent scripts in the decommission bundle may have use it. The -# following values are possible: -# stop -# terminate -# reboot -# service_restart - -# Determine location of rsc -[[ -e /usr/local/bin/rsc ]] && rsc=/usr/local/bin/rsc || rsc=/opt/bin/rsc - -echo "Decommissioning. Calculating reason for decommission: " - -rs_decom_reason="$($rsc --retry=5 --timeout=10 rl10 show /rll/proc/shutdown_kind)" -os_decom_reason=service_restart # Our default -if [[ `systemctl 2>/dev/null` =~ -\.mount ]] || [[ "$(readlink /sbin/init)" =~ systemd ]]; then - # Systemd doesn't use runlevels, so we can't rely on that - jobs="$(systemctl list-jobs)" - echo "$jobs" | egrep -q 'reboot.target.*start' && os_decom_reason=reboot - echo "$jobs" | egrep -q 'halt.target.*start' && os_decom_reason=shutdown - echo "$jobs" | egrep -q 'poweroff.target.*start' && os_decom_reason=shutdown -else - # upstart, sysvinit, or unknown system. The current runlevel should tell us what's up - [[ `runlevel | cut -d ' ' -f 2` == "6" ]] && os_decom_reason=reboot - [[ `runlevel | cut -d ' ' -f 2` =~ 0|1|S ]] && os_decom_reason=shutdown -fi - -case "$os_decom_reason" in -reboot|service_restart) - decom_reason=$os_decom_reason - ;; -shutdown) - if [[ "$rs_decom_reason" == "terminate" ]]; then - decom_reason=terminate - else - decom_reason=stop - fi - ;; -esac - -echo " OS decommission reason is: $os_decom_reason" -echo " RightScale decommission reason is: $rs_decom_reason" -echo " Combined DECOM_REASON is: $decom_reason" -echo "" -echo "exporting DECOM_REASON=$decom_reason into the environment for subsequent scripts" -$rsc --retry=5 --timeout=10 rl10 update /rll/env/DECOM_REASON payload=$decom_reason diff --git a/jenkins/RL10_Linux_Upgrade.sh b/jenkins/RL10_Linux_Upgrade.sh deleted file mode 100755 index e0c934f..0000000 --- a/jenkins/RL10_Linux_Upgrade.sh +++ /dev/null @@ -1,155 +0,0 @@ -#! /bin/bash -e - -# --- -# RightScript Name: RL10 Linux Upgrade -# Description: Check whether a RightLink upgrade is available and perform the upgrade. -# Inputs: -# UPGRADE_VERSION: -# Category: RightScale -# Description: The new version of RightLink to upgrade to. -# Input Type: single -# Required: true -# Advanced: true -# Default: blank -# Attachments: [] -# ... -# - -# Determine directory location of rightlink / rsc -[[ -e /usr/local/bin/rightlink ]] && bin_dir=/usr/local/bin || bin_dir=/opt/bin - -# Determine if the version of rsc supports retry. The upgrades script can be called -# as an any script and RL may have an older rsc bundled with it. -rsc=${bin_dir}/rsc -[[ $(${bin_dir}/rsc --help | grep retry) ]] && rsc="$rsc --retry=5 --timeout=10" - -upgrade_rightlink() { - sleep 1 - # Use 'logger' here instead of 'echo' since stdout from this is not sent to - # audit entries as RightLink is down for a short time during the upgrade process. - - res=$(${bin_dir}/rsc rl10 upgrade /rll/upgrade exec=${bin_dir}/rightlink-new 2>/dev/null || true) - if [[ "$res" =~ successful ]]; then - # Delete the old version if it exists from the last upgrade. - sudo rm -rf ${bin_dir}/rightlink-old - # Keep the old version in case of issues, ie we need to manually revert back. - sudo mv ${bin_dir}/rightlink ${bin_dir}/rightlink-old - sudo cp ${bin_dir}/rightlink-new ${bin_dir}/rightlink - logger -t rightlink "rightlink updated" - else - logger -t rightlink "Error: ${res}" - exit 1 - fi - - # Check updated version in production by connecting to local proxy - # The update takes a few seconds so retries are done. - for retry_counter in {1..5}; do - new_installed_version=$($rsc rl10 show /rll/proc/version 2>/dev/null || true) - if [[ "$new_installed_version" == "$UPGRADE_VERSION" ]]; then - logger -t rightlink "New version active - ${new_installed_version}" - break - else - logger -t rightlink "Waiting for new version to become active." - sleep 5 - fi - done - if [[ "$new_installed_version" != "$UPGRADE_VERSION" ]]; then - logger -t rightlink "New version does not appear to be desired version: ${new_installed_version}" - exit 1 - fi - - # Report to audit entry that RightLink was upgraded. - for retry_counter in {1..5}; do - instance_href=$($rsc --rl10 --x1 ':has(.rel:val("self")).href' cm15 index_instance_session /api/sessions/instance || true) - if [[ -n "$instance_href" ]]; then - logger -t rightlink "Instance href found: ${instance_href}" - break - else - logger -t rightlink "Instance href not found, retrying" - sleep 5 - fi - done - - if [[ -n "$instance_href" ]]; then - audit_entry_href=$($rsc --rl10 --xh 'location' cm15 create /api/audit_entries "audit_entry[auditee_href]=${instance_href}" \ - "audit_entry[detail]=RightLink updated to '${new_installed_version}'" "audit_entry[summary]=RightLink updated" 2>/dev/null) - if [[ -n "$audit_entry_href" ]]; then - logger -t rightlink "audit entry created at ${audit_entry_href}" - else - logger -t rightlink "failed to create audit entry" - fi - else - logger -t rightlink "unable to obtain instance href for audit entries" - fi - - # Update RSC after RightLink has successfully updated. - if [[ -x ${bin_dir}/rsc ]]; then - sudo mv ${bin_dir}/rsc ${bin_dir}/rsc-old - fi - sudo mv /tmp/rightlink/rsc ${bin_dir}/rsc - # If new RSC is correctly installed then remove the old version - if [[ -x ${bin_dir}/rsc ]]; then - sudo rm -rf ${bin_dir}/rsc-old - else - logger -t rightlink "failed to update to new version of RSC" - sudo mv ${bin_dir}/rsc-old ${bin_dir}/rsc - fi - exit 0 -} - -# Determine current version of rightlink -current_version=$($rsc rl10 show /rll/proc/version) - -if [[ -z "$current_version" ]]; then - echo "Can't determine current version of RightLink" - exit 1 -fi - -if [[ -z "$UPGRADE_VERSION" ]]; then - echo "No upgrade version supplied" - exit 1 -fi - -if [[ "$UPGRADE_VERSION" == "$current_version" ]]; then - echo "RightLink is already up-to-date (current=${current_version})" - exit 0 -fi - -echo "RightLink updating:" -echo " from current=${current_version}" -echo " to desired=${UPGRADE_VERSION}" - -echo "downloading RightLink version '${UPGRADE_VERSION}'" - -# Download new version -cd /tmp -sudo rm -rf rightlink rightlink.tgz -curl --silent --show-error --retry 3 --output rightlink.tgz https://rightlink.rightscale.com/rll/${UPGRADE_VERSION}/rightlink.tgz -tar zxf rightlink.tgz || (cat rightlink.tgz; exit 1) - -# Check downloaded version -sudo mv rightlink/rightlink ${bin_dir}/rightlink-new -echo "checking new version" -new=`${bin_dir}/rightlink-new --version | awk '{print $2}'` -if [[ "$new" == "$UPGRADE_VERSION" ]]; then - echo "new version looks right: ${new}" - - # We pre-run the self-check now so we can fail fast. - . <(sudo sed '/^export/!s/^/export /' /var/lib/rightscale-identity) - self_check_output=$(${bin_dir}/rightlink-new --selfcheck 2>&1) - if [[ "$self_check_output" =~ "Self-check succeeded" ]]; then - echo "new version passed connectivity check" - else - echo "initial self-check failed:" - echo "$self_check_output" - exit 1 - fi - - echo "restarting RightLink to pick up new version" - # Fork a new task since this main process is started - # by RightLink and we are restarting it. - upgrade_rightlink & -else - echo "Updated version does not appear to be desired version: ${new}" - exit 1 -fi From 0cb61c95558f3b35d2fa5b90ae1a073cbc35b9c1 Mon Sep 17 00:00:00 2001 From: Richard Shade Date: Thu, 12 Dec 2019 14:18:06 -0600 Subject: [PATCH 12/13] cleanup --- .../jenkins/attachments/libnss_rightscale.tgz | Bin 18799 -> 0 bytes .../attachments/rightscale_login_policy.te | 18 -------- .../jenkins/attachments/rs-ssh-keys.sh | 41 ------------------ 3 files changed, 59 deletions(-) delete mode 100644 chef-templates/jenkins/attachments/libnss_rightscale.tgz delete mode 100644 chef-templates/jenkins/attachments/rightscale_login_policy.te delete mode 100644 chef-templates/jenkins/attachments/rs-ssh-keys.sh diff --git a/chef-templates/jenkins/attachments/libnss_rightscale.tgz b/chef-templates/jenkins/attachments/libnss_rightscale.tgz deleted file mode 100644 index fdf5d5c45923ed0a8ac2cde1f8ed6520d65cd243..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18799 zcmb5UV{k5A&^8*|-mz`lww>(Qwrx8*)=uu&wr$&XvSWUE-umj)`|F%KRWp69YjyXk z>8{n&GgXTq8VYFoI9&q>^im7n1x+ojTApH7Fkc61mQXqvPtFKRijZ6g)H2D!_0l4Z zV2ErrWcmh4SW?3pDS1 z3e3*GR0It-H}-9o`iA*O_bU`;=7tk9(;a4WdGWM_+>Asn3YA*ZWids1Iu<%Uy3co& z>66rP99woFD_Z~jWt^Owj^Xcg{Y1Tw&+0q#L4WzD?~!i?r%y6n*}IwXDBSOu%E>mQ zOT#-zS`v|3-*{@#p0D^3f9J%DC#+z@1a_Ez;D2dX7`gKfUT+Yl#xR{i5^ulZgJL}n zz5+hn=fiiv{{&-B;{;wznwOe(+phX%B<`^d@BK4+>BQw{2>)mO%x)Lu#&Ne+_t6r5 zps{_`f9p-#la8NCeY@tulI}kANn`k;m-Vc{XdiMr@;fs(`o(MR!zt{dVykI%FB=T_ zfC9>Wvq@F+x7)|(RRcrIM|EYU&Fj63F(mLddP=a zM?xE;fa#vIQ{~)4NJ2X!h9||q4fl&4V$a!a7H|(vYYocl8%G~QhCq?E@?JVb57#Zv zE9_0!WhL@^v#;{!GsRbzxvuiZM^}cz;k(@j@$KNrOsL&wOYfRvUX>2})z@1O-OE(E zf?f90xXruF*oY4%AnP6`>M761=jH+W6Ebg|@oOpD*M7?Kmq7KU^?MD+vuWq|$9R`a zeL7f)hy0Qd| z1Cm<=EaC%4r56VAy&hW8;TG|}bg{l~ny3#@rP~FiLj(LZ;$8E?QE0KgAxghh%+T*+ z$_xF7!V}h)shEHf39aXmka%Pp4yHGmI0hsvzlfDKG2FbN*DL_bn`w6+IkJD}t<|{0 zYj|6>&-6?>vX5>YgzS+A)kw$7aK`A-cglq2uDH*%BkZ2W$w>LXo^tVKIE^% zQ#&mloW6vocX%V`v~}@!TTPjZ+?}|%bmiaR#Cv*SZ(ZUzZd)BVpiFTEoJoofxVkq2 znjDi7rXN?%?{+NSbZ1VlaMRoT!LB*3;5N(8#y$nY4r=aP={m7f9X@+zKN6UAXV5cu zS_xRc;}1M6L5g5oaXD5-hF6Xj40`pt%xt@GI&jCXFgBYWo04{`gK*$HGso}hI;)=w zr2F(f0=$(>U8^+8ZD>nrp1o+gg1kMPPoLDK;StrBWrU57f}0-E``5$9z1#=Z+qGxB zkW@81mqNzhVA%UqT9$QQA+;*nY}|_!LuahJYNb6xJG$$o=E?gV4!nR%R@!g`2Ow!e z%7@3L-HTSP{;9LW=$Fkkln9mH*Pq$3ZZxc4m1$j7Q`b~QcbfRVVrw$*C)6|(_ajL@ zv**hp$Hej~PMPOhmUgrNv&N4OrUasgwUs~Er8n&IKVQjfBr1mTQy?;d;&i3LUt9IT z3ZGYmupPO&TJxPoaPJEHvj+5xzK(9qYU(hk6^M*Fg3JY9lWdjath`}|gf+o;w>y<3 zC89y2$X*|7g7v6!h~LQ^23qlx)PGmt6or+v*JTP1JeX4tRK!5;=-VN0rlKDybFFs3 zkSiaEHgZ`yL*|9&GB4D>Oq+bi1S>Fcr|=E+bG-?CnxnNFYi^Cm zWGeH(bg*?K8bUWU8P^$0oiy50$BjV!Yvg~8dMlpOSZ?C$%)iv?b+}Yh2`#9Q2_Lz* z1?B$0#`BX5SD4)s<{yxN5owBjnB5b{vzyzqnE4s{=`Ze$ad)bQ$1mUn4rfw_akT*)U? zKI}88AHpQ5K>i+iodw^RdP(tyJFhb8SExY9_aA|pUrG8DB@p$(UPELZ)>Ga0%P~V8 zTy~=(-xM>nU#Kpg@;u8AARL##lfigbkNoO157bE57bCmTAe8pS4~YuA;FoNIt`^+q zaRBvnWE@HTC|;ejNBi7@V0sQ%G0WADkXo`sI%+LqTtJpT1yf&y9L9;ij@y8b4?Bvh zN9U=ST+s2*KV}P*G^C;=lmmZ))?IL<85G?9WJKc+@oWpKn7ka55iO`Pq>{So!9{>P zD48_NvkP)WHEV#cog%zNqv&E@UqWz^u;#IF$6dbtbi)bjc^4?ZmByJ5KfIAPzNb6K zN??FE&{ybCwn1;usBR!|7(;&&Dg5xpL@Jj_yEMq6>(IRye>RL?J8>5Kd6+jq+r zizS~-=}n7#$y!SwcoB5r$sf&YQKIM|C4!Z|Iv)wwb{Pe>@U;<;hL?Jz{#e@iQp%QW z^Gyuv5uR*8&zxIUTUp@M74@Wcn#9V4A@61fX6Nh}VasL?@d`TM8^~vs_Xd0?3Hc$K zJqdDW=;Q|SLSf9E;bj(%9SIJ1&q4*L{uUU)dp2w2If}=9P8sdMlfjcARA68T3pkEI zGK+?y)?CW8r=pf`Ti6VmfP}p&ONj|}vtnzH4!^JP#Q);}kgAWo4=?;Eqa4{-D)Dns ziS$|StCxvvc`p}xZKU-7n>P2S5h@6<{^m#_{iK@iqx<+^T}J4Mmd@Ax=(~fhlp(kv zXcMHDBcvim)<-|qN}kS{X|Tg!$QKa_mDmu4#05(xljmhl-~ovyA%}ZkeN9lu3mHG$ za{VvX4NPKCF)BxxOx`~jy@UmzsGeTqkiwCqepwjr(h>IDS{DX%Ik?MJ778rwDS@(L6R5W503Ka}WzV&)!PYUG<6N1Nk zhY^os;};9Ol^pj>rSez3rCtnkX`d%145;olp;XNF|ev>9r}=9Yer%nh}Q{2``e3piZVC{sN$=eVm7n!?GA@wk_85F}OwF!7!_)3}d5 zKUJRB)u!q=KJ!u)RZ1Kfl@9jVh2Ok zTf-(o{Rft3P|z{Pf_{^xG5RZ5oar_H^oE7^7Up!@bXY$y$}MB7P<|L3M9Utr;13i; z*jI2E_ffvrIj^Cuh$i4|%~M$+lN2INFaT5wC2m}ZQfehQB5Ap1H32>BI+%zug3-ie z-hPF&Ou>n%VN!?gs~gUF0uCy^=Z4=oIu(C@s*0me#5q~WLxqwRGuPk_%H$WM*rqRj zI;_gkH#}Pn&K3D8O%HZ&p~J7JSsKvIREA#A!L6v7RSo+!i##{{!7Tp=k$g9Ughk~= zC^vz>d-6-)Z08#$iYLg_MA&GiMcn8RjEEYRa4ORzjDiE;n|LvdsuMV zff9TkahA%IHO*t-7#`W=n4}ToDk((4YSJl)FV`q7E=Krg%)hpTJmK(_L;ynW&4?eq z?io5gKuK6&v3t*;oeX0yo$ug}Mb4Gnr{^LTpoStR;Od^-V4|;}+>oVTB4fMZz%}0p zrE>DGoho00n?{A}S8RQTgyWcJCT?T3dyC+QQTULWe9yREj=|{DQ$f8+Yei>=xqfl$ zY&7jF!rrX4q-HUvYbWD;=6;91Hj^+Yz3F7R4v{A*x+aOyD2pdEg|pIq#b|%75mYzL zkU)(YdW9Gub_VcT@p1-~r^VxH8i6&=CGW1*Dy%NdYp9>qxq|AR$oqa#HjeZ%mUa!| zgBle0y2S22xc6tpU=pjPgeb|HR%m$w9&^mYN=;a2!qIr40(POWZ)eyy zZc{7Xt46=BSKi|>B@|#O(6=$9medMe-ylcxPyiODJ@!u-LlTy~+AE(P{rU5i@C9tH( z3KXU}=n9k-Dj5p!Vs(b40Gjb#&zpxE_OiTwnBJq2?Mlj8$G^ZYz7nu?9L_K9IN7;d zadF1tl};D{r!2isuDbzo3bTNNB>+&80@9TLvodxQd=Dk5``8T^Tpq?R2x;CfvNpg} z{09a1bi)jA$Fg$D91ZqU^u3ie^k{v*{%|t5`luWDxtmbO5)GZ(SUR4L+^_fck^6tx z=e*g$wN$4c@3*Ynu;(Dz0rXtxU^Xb%aDUAz9P{O+^695{;Wq7@sOLvz2&W-$NGqy_ z`h=f^mdhqXrTEHYgn11@P%Bboy4NC6iN4OYaT7JN8p##>Nx7SgLWwyS``arSeR~8^ zD}@XxhrQRs^y0jwupr>4x$!G-=X%yi!Opz%SdmpES`<^4YpO5yVj*aMz6_$!L-0UYsAQl)hE#BDP&RADGGuJ;XG5Gmh65}k=YQ~LL=~KyJuotObTWJ#7 z^FXXC>y%}q74F*Yfw<(6O2IW%eHa-Ca_uja1^A))3hLK|rMdau@xJsRGXkf2 zxYU}$7F6Vk%2|5EnA#~l+KbP5z359(W@*RQ*NNdpFjLNsY2uJr&@$*exptR2S7uXB zd=sHk=@rlsaXnN_^g$%$y)*2p$XP`u2ShIW>D4_fFb}P2;Oxb}6gs$vhz&7tU$eza zE5ONxg|VS#ICfDo;FPXk4>c4WtZZ%Z_E6^p zk%4cYOwgJR7oUeL0l~o?nUtM`H=scn)+dG^!_CIn2yMhh2pv$R7q(g8GG@2D_uF!pujWE?71Yb> zvbyC}wufgbYP}_$>zN1{8DY9yss{AIv%3=WgTdMan*}ZMxG0+^sruMos5d3y3vGu} z3*fq!kH9H=S{YXrak9h`Q1;UU76Q-6de-}pPGMgWn|xMD1X zoF$;X0x~v11qBdjFd*74ySV}JoGxQ0dZ-)!0C%CEeQ4_uf=$2n22y=NG?*Ch*lOCp=aaf{K){Fjo@?Cz6@lV= z{DJpX0P7e*3n&C!j4LDlmyY>coZAi7Um*;?=7T(MgPXGWvX3DwLmONs#42TMosJGM zZwA~B{6Tkt=^4HJ6<|E=nVpr?)=)qD!) z{cse{h26>g9>U#>%)$6Zmq3Dgu5}T9(=FxuAR*}ydYfNvhBS4s6@B!Tz#X;Z>GyFt zam92wt*i1?{sDEk78Tj!bXEh7UVGIdw0Xv+a5@lTv|UYjipT?cDupKh zeo@&B$IkL;!OQ#4hTsX(%Wi&fJ+cUW1r~TyzfFZAb;al9yJzCF9bwsNIe>SGmV9w| zuVCw`B^E1edCwf=9^%`f;Cr5s6YYTzK@-g)r^tf{XSS>o(-Vkl>(d!v+=RnK4M*%5 z@>t<+;16e*lI*iC@FR(9#XRNn?HB3jXmV3GlLQCPuf|0Qx|{i{bzFCyu-_KtG#x8k zYb!QYJgqfZYvioISE!sE_8fwo`)F4`F&WGZ)Se)lP8&0xNU;Mp&&Xk!8+~l=w;++? zEl8|la2J}RFJf3P>Q0qR2c59$ki~5RkpX=XEQV-Z9keF{f4}actE1>~qIBt;KqE-p zPF7mt(wPv4Ebz}d_QWz1-*ck3+fu`ZiJFh{6uRF{>RT}V3%zhsyYPHdyrbbQx3@`T zd=s)2es>?n=iP4ZJNb>)vq5s;Zz+4yWks5Tqw)T}~_%9T4v7yVvW}>e!lxejZxW)Rk_BizI<5**Cv)TvpXB&~` zz2a2FEV95(*eBfZLDSilabkse%{mG10Sr;^37e4cm*4eYP%;|ldr`Ilu zS8R{kl%R9{WGv>~IZ7}eMC}1*>#VZ*Ok7j?Fjq<1?1-bWWjKQT`y@3Wc`g$ zFObD>svLzgsuUIMVh5%#wkCx$8bD;cGG{7DN^ao;T5+3spN}po0IGzDssGPl3j;w0YOv=Z8{o*kk(0b+5?6 z*sAYLv)YkWmQJgKy@p6Z8|F)^^wTQ4hbfbC2%hick?~2TKocVZ( z)F2%bPt7elgHSRIwxLoh_|nHeU1a>uB}=*DptxM#CkVgW9@DHPbMS+ooyH>t1osM^ zzrwB_0aUwl$B%vuj$JK7yj%S-QL%8YU4VNk+FR;U{P#$BcLVU2${jQQ5}zW_BnO}l zpZQ1FACFzzc~%#VMcYB?-kh;u%>p>C*~%68@`C&{lssut1u|>B|Gi%FZ(GBEDeCs# zCb+YVZ74i<@)rGJj~jbk`Fq%;=O%A?z>@UD9l;{lNd92>$qg!}Z|7Y*7HtbPx3zo3 zJ|=_m$s4T#x#Qvv$URB?9KjZLI-Ki^)OUfIStw7~|K>DoxzoQwS&3#h44PKTfc^#T zTTS%!IVixzbF%X9;`Q;v%a5-o_xJxpyEkgG{7;G=6?)u#vV}7ICgaoySKPTWBYj@i?@F7yBzPTP|Q zV0nUr2Q7I-hc^U(1lMP#3e6)~vGZr9(FrZaNx^R^@9$^b=ixTLgOQkDzoLILdB5(P zPFR!EY5II7Wf?s#k(7tS|7zF8Kp-f!XiF|Mi_8pugFgxvIZ3O0VZoiM*~#u=@gVx@ z@V4~(EU{|#CHi6s&HUYCse{SS(Q`%mfN7tAP?%=Z!jNz|x}Nem6i^$d}po;2b+{!oQ5BRoYvj-%(nz3cFGZc0* ziXmlcPJ@;cbxs)zz$n@OhUEKQa=xplL5xF~*oTl|D|%L9W+Icg6;pYzs&m#qtB8vP z?`~wjGl}voTK0~zK7mm*E8ez8U(DQ)w@NKFGBn4?l0H`25lWirDSO^&ZJ3EGzan|Rx;hSDq}h`*Hlj6Iy1R>`=2^9|2m8( zD*IHK3N0$ThEHznr=epUfC8Io2jkZ-#j*CIo82wkTJ$}e*L!*el z_L$dTrCJQvK~xhQP|p&(_DG1*?INunOrtg^J!v00q3?_@6cH_CTV$IALAj$3?0frs zR?a938=)Pr4<;q<(C!?kRQt$M0u-Aa1v9K=zO_C*4*oH3XZy%&Uo|0#$n|EO;-(od z+hMNgC4$F5g;mx{R-%mV+kotFDpXc4uH_?On+`vqCmN5%A`fCCz3^8gO2l7J@q*L+ zrd@?@JKVSSgCXNvBOd}Is*|vi!8~EH@VYz%)hrh{r|&jTveaX2c_UC_H{s(9rG3nW zoIB>%D#k~mH-WGEs#cOzFrjXV~g`TcdX`ICCE>SA+yU zDBR-`bw|&Y^(8M!Fm}s1&mTEZ{U$AGJ}+nh*`=rkvjm=hMwOuPUGM;L&jV+mO5wEI z|7LQ!eCQKTM^iaOn*kKMn-Py!c*~#TIJabAG>p9 zu`4%RzsLGqe@4Rk2#vYik4~`XnuHlKxDzV)gP?SfXWj@prHZiN)oC_8sB=P{poIxR ztG$6HIVV-C2y14uM{2P~YI&kk>4oCjwuZk z_XC6bYY;QEGvJdTq88OHs&(s|8TT zvG9-|EQwIy)WXzgvrJKAbt5|a{nuZ@hQd&OybhQtaDAST?1q-G{{e|LcUmy!7bh4L z5g1fAd<(v^{3rDI`g&PSzxI$k-gZD5WO$BOI4NFuPCIcC0*|ZMG56&n`Y-3zG8*RV zS``hGssVYuMEL(S?Eh)j_J1Z1S^qOP|KSX3@_NHohl>={fd8z2%Jj$4DPussOD?Gb z*X`WHA6tIQ5by;m!sQyC^JaRvi05{`(xBqLT2{lB@*lL|jF<8JEZil>`JdGLA1U)A zZ#e!(|J#!Czoqj4IbMIV--4m0Q&dJ49a2>!$`S+DZk;)OWrOmOi2!k?vnujA5?dHM~jFMDJqCm06!?90H<>$w{t8a1uj=M%`iZAJ2uUT zio9MKFyMMj>!US^CJVYZKJ!YRMS+!^n{ zfq1?vKMBV6$GqJgNp;Cp8r2@IlqhQav0O-vhWdC;uCq1QH;%F zKnUJmT?Lop#rB?`gF-QhZs08jE0^?Sw3c5Y?2(JPawgHxHxA~ah*{YoT3?U=iK=y| z9WerJ6J-lh6voabISP&U2g?e*yniN{yPf%dSX;e!jJVd}myiUEr@vxi5QWCz2aQ&9 z3>pktsH9<5pd^s}zv%jcfs5(R4fHCMQd_{o(oWu@@j3e zdpo0O+;rLWrJ3S}$dG(V71?XZR^p|f#@=s*W$5_>*jR?Y{{vPFb8C{yK;#nB9|#4( zTU)2uj`90s&+6Luit%)fdx~-oayR{fD?&tMtxXs?+pV?OvFY(jBGA<+(a&R(u1V}r z+mEgIjep9q%ZY~2gQDZ2Jtx zqzrw7?jZXa{&+};WPz<2VEbk$5m{1%b|oN=G~f{%RDzpNppF}egSG-lEua5y28 zmUZ-@$tiiN!j{K2?Mz1UOGZE@IFOVTzg)!qAj`ujluR(_5ap|co90IC6h$y)G?HZQ zd&v@=HHlATBeMrwDG1R=xhfN#!T!Hww%~NeJfP!l$punucVSDYo$JNLz19waf2+#s z`1ogrXlfJ4r(I`j622GE!4?%I@iSKtRUZ4p2GEv}0u|iDX%KfTOr%$`l^*C-1FffL z3Hd=*vI~TKz^b`Onq}LLp>&}V>(3A|)nU;_u&OQHk0r*KUJcs7JOcf69^&Ip~V%!+5|oWdly7F^ZC$h$Zxg9lCo z);1;i(ln|yQHS&;MLwYC?nSIXdM1fO*pvUIqE{ev*EG;YLk+TYUx*mCrJ#)na=_uV z!wg+2o%+O^Nw&IPBBHL9Q0S?cvDiZ@$Pptk6pKfxL3S8?!yMh{RkUC-a`*fH*WExffp#eB&H8KH&T8nz(gPw^ICY#f{XjvE=%nLY1AwM zeo)y5b(D$F9@G=!kTanpG6t`xZLW{}d|x%DltMu_6I@3*LCK5=m5xuOk_5>mB~SEw zx3VE$mn1E`uzSo#h}b&C__w!lP!rYIdWwmya;5Fyn`}@M*VuZtiLH8NM~D|xiRK8Y z*3V_SeA*Ks(CSJ9@HmmvW2g6AYdthQSTx1?;|mL*!NYTIG-#sV&KPw|l%k$riyjeF zpLl1Lw^#PPlaw+-`)2~Q@SDZW(d)GHo&f;+W1(`mlYEl=T_fFX_TeqxgSmW9L3%V{ z!=I}Dw}IvrmC)a-JB{JFd(nhy-LEeSwK~p#C_FT9h9~lLb^o-oac!wD^*dobQd{mS-G0`VX3kgfe zrJ$O{Jf9|+prvtpBF7VXU<5)1?lfS@R!>n%`8#a6!qHle@DtX=q6^!X2TFOn&D!B) zSV})ocWqhlibt@#7w2L|pE!CKV@UfJ?Gq(-lXeBa4Q`9r-bK0CgW=DzkSNXQgkW

e2>{S#UFTv!*tzgM#fp{y))n>Q-j#nNh0>Gql@dWMCQPh*I5ns5=QqWV-A?h#VUfh5ssCMrU;dgKBxv!l7 zNUi##LK3qgxlI{F0zN{DSWlL^t`3+hdi@U!E5552-?D-KwF0kmnj2(GKw6-FKs4Py5K|o@%Fn~?a!~ZwS-_$Y81l@^5Y&aF4Q+j3Sy;P#-)`up*?*%U@P$Z@ zph*$cEg;>8Aw$-nM0d=fikOfV(oG|9)bblNeML?`lKB5aEPuR3bk(u<>*tZuQ^Q&- zSqDvviRfwI9ku?K3ORk~$BvkOBD|HBV88y$9w{BKP|F+a*<794<2v|>n z1=?xL!h-Piz6y#Hz9y;*A(2bw=ET+yDn|=RM+*@Bjy%%{t8S` zy{@gf_}aIry|(N!QV-hqejz5!`fCe*TY@HOP|*v0B5>h6?C?U}bDUUPNs_CjOEGkU zHeAV2V-t4WBFI(-HmTBd-J)WRYY`T2_=2o#DVVgW9!o`h2aUeqv$o(AiX*VOG-^}v z_nLUAh5p%mYx>AIe2=&x4gxb}Zudk_eyJ$XF4G{gbjeXaCroLtkf(7)lJ3$1q;f+Q z|2+Tte18o=`l<5;ckuy^#Rqda-P#cL<;jDX&dk{k*-7;zHd&8RZVMM*;x1pxVX79% zGKON&EB)ICaT8iP&d|+RZSZKJ3hm&2HI2{>1$bAD9TxNIPCjIwOz@dNBx7)JsNo|T zVqzb}IvpAm>UhoDS@( z&T|HwtE*_qm1+?+vT-%#NWU|1f6rM_Q+H;^ycW5ZrbR{Ly z34{>b5%+*KKQfjlnvRKc8jwyjH)>0DH2<~cQ=d2DTYgWl;i$tML--?Tl%WwsaA9yV zSb%^i;)yj4%#jVmhnr7U47|PzAp&m;!juq}u;6yQ{d$s@v(^M|=`6p&$Ir9#@%-KM zYW|hsf3mG-U2oZ)Rnw+h5fSk+N%$+Jku{uu?1a!a+)KL4u`#MYG@X;%NYj2B;5FL1wD24M*<%e<%YG~8Pk z@k!y*gbYeKiwsJNIkejRtxbCHeG;?|vC9(;y+rWRylzVMG%cVf9narouuq`{l7J)` z3!H=r26d297OiMEh|)wDt^Q{$9n)`$6?*wIYA#|VbA&kRg?sZy%J~j#3NFgY;9S>= zG|T`K>VymWV;gSlw4czfN0y;#3lm2esnou^qWZRJmuX=dYDnCanVZX)!lD=rJ~2N| zhuq4bfIgoQ$&{UnwYL^2Bom`%MHk8oW0w5Eg&4%U zlM9MQA8=MXi_KZs6oKLyK~6^8ru_>hdS7~Z%w;38LfT`~!nKY!IxPZZz397RA*v&Z zA@|JmysNoVBwlrTu94PumJ-bJIB`}pm%b~8H;{~pqsA3|^C#5-9Nwba&H zJ4b)Z7HRO)J$uPMvq0T74?s`mF0u3OWky z`-8>K@=x}rZ!P9!NXS-^j|0vE6m9WtPa9oH*=AoL?W8Cj0^?^J6|Ts z01D^!TJL9PUCG1){nYET>%b=V!8nZkC=y{izC|kfO zl4s$9=gVwH`z|+GW6wVRNdx;k<}5?P=+@#iSg8z^gJWA67>Wx}NrAd9?q|9%^z94@eq4hz%p z&Z%SPDwS{1LA+)>)776w)J?ZW53>7Ns~9>oD&7bH5W8=Uop^Q~SheF}1m004XfWWP z#9!WE5om)gLW4iIG%5;YVl0v<-NHruWoLIgwE0#NQ4!^rSYn;so4V}aVoSIlHE=1$ zu=u+#`tjJN)mU;@5B=wF{Og0h8VV047?H5J*!goD15(~rJ&mn0&|}~RatzV5=T14R zX8b=b4$4{e@*cR$!X+rFDJYLgMonkwEGwh?t%90S3z(9F?pe2zk6*l|V$nCK+Pa4_ zZt`QqC#_^|*xDaVmxj-A`7VN3zMXs}Tz@;vj?(BX`3zWnZBn&df(6r)P!eMkvZmxN zimhyUt6t$bnFF4sNdDD6`bW6r{ZS`+ML@M7xYWJ&$ z1JlpvsuG!MLXS?sjGL~We|Me4H&2zI0Go~Ki29qWMtb)GX2;r2<5P*;-l{>R5<%rM zMM}*xM^(dx+Qnn3!VK;l;FpSv#$p?3IGis=jz%J~;N0iTIZs87C)Y(6y7+U4Bgx5c zyGqNYE)sFwnd^CT&S+dUbaBHa?k)S5Y|pm3RPU8)mg8k4Z;qxNW{^_fZwj@GY}gW> z^m#KgMI{HYS-JNd@YTWga)JvLg%K<4+&7bCeQ)_)UBOh2cp$571&c?G#+8*CJ<}rt z|1h>D=C8iYjN!Mrx-M1T;lU!^&Jhd=y1VFyuBe$Srnly-?xoq5;rEZat~~h#3f({0 z)oTwM_UEYb_*b5_-fi7i5&V0hd|yP;uIe{kg3L-{&sBM+bFgo;BKqUG+q@%6`NYmffNtC>x3{yz|1v)Is^$^2`f(G{mY7UY{6B#@qBC&Zb8^`3* z|3Yv9@81jPUD!4w@M)cViiimB7wX4~LZN8)+GrzGhzIL<2hFi-m*_75fXZX7A!nP6zC#MD9|R&`M}6%!V?oR5 z{O(0?={UUzi`~XyXSaEwUTRURT-DY`9-cN8PPsfCdXsX<*u=J?@%Srjb7@Gi%8j$Y zO|w`+wM^WX<8rLoRB=@}NdJ}nxh457``rJeS=-Wp1erg}PoXU7Zu53G2Stw1bK+$m zY#zMZ!sk8arKxYE4X8>Q;}GPL4eyAagmlZ$CGDRkypY!!S=JoAW|f=x>`YFJn6YEG zS-vDIn&%Ll=O@7N9#tl&vO*BwSdWZgP;VzJdYE*0#(ok=AgNO%w84Y2!qE!1La=ZuZV>A+`nC0a-*w7A|<>u`xmR%^$By>D>S&VX!)^f5xqM(hyuz)24&DzN@OZh0rJ@nvJVC$~CYcMb?YSEuzf0!MDI`SrO53 zBax|AlC6eknQ8n^c?#pQ%%R1xxF8|ME+15JGxSRk4>_=zazOT_DY2hmbz8LApKH3D zU3VZvxo8rgY@8OfuZ^$#l_Y(YEya&AN=%eHD_fGwU?bjd!ab)7p;yZnhRt*dn@}s{ z-}Kd+U}`lo)-4MeSpwOumGn(~DJEZZ75|vw14axDxj!C$90gdI$AE6wx)hu4BlDVE zPpj1uCw+pHB0TdP#N^Un;ipXZvgN_Gg+=B1H%{KHFd^q^!O*#TgUH!L1bWMyVhT!+ z{s80+#wX`xYiJ5Efb_^SfP7IGQaBD0Sh)+y2Yumu$3bXke?YFucE~5*t&$gFQiGkT zoiAVm;yndYxaVzX$4!MP(}&jb)yb zE^z{FDW@}Df7~orZ+;6%?J+w7b7IjylSg`V5=PymJPaXsa4(Rw8!%93nPUkU)kEAw zELawic7C*SmQE*Usu1%@LmvT7cXT3Xd``+IR|(amF{C(!`xW4xPm6O)pK=7U9m~wI zYoAX`aI2q!4!j*+uiWc?;buvPR=QbHM7$eJNdw}8W%?R$KRk{w^WWo)pp5bhQ3ct2Q;9o3hTgO1>BhmSwo5N0#sgXrEoy~$OVUC;0+F=)FtaO zm?0@y350*FK6MU7N%Pq%D#`=WiXH4}fkoZaIWlxtdstdb+2W8?hbK`CKrc358|uNp z0Nuq56$5=SHFN~_Q_~Cy_*U1f4DctXwdxhX#1Pokv)pCW3Q_zeB_h^a^b=qw=1+k3 z;u$!%{687_!Wgdy-U(v{y%m}hdIcwW!;kj`6}(OS3zk7Gm8KZk2{ac-swLc1A!7tE zgI@XxP-jy{#Z`9F-kwSY%!pvWS$cuEp}*v1uI6yvEXB^N9zE5+aA?N1 zg#C(nghFgH!&BI&(8qfzGZ=!kj*R@BQoj~KpP?7I3s^M}r_>D7%h3>1CX>e^FreHa z0%YzWgmYoW>$} zGx)}omD{?2KsU!#BU894QI>#h4%F$W6O&R@i4g^pb$-fdd|y4%2gtEC*~Y>^c7oHD zuJ^J33Us$*G1xnT?HS|v{x_(oQ@HRVOjq>ZZuIu4j8zCCkk!em^Cd&&v@c*YHi^>> zTuZ1^ZUuIT`n<9GzOHG}oWDGw#Og2|AfOJ=KO3Y*P>X(7I;9QxcX+)|FGqeQ)U8)a zDoD4C2k%MP_?EC6un*#R6p+8dsCob*j28T@A<;W<9IO_~trAfd$d~z?kepXv#IUAR z5=8F+C!T3JDXJXVJ;>nut9YuU7JPgIVr;|9E4Twsi?TWs?|NpCx(XT%YNkKkWBBEb z)+<3LK@(8Rzd+pgYGG4o)B4~jSZREo8P%`k)a0hRJSJCL{%BAwwFXK2u&PHcXE;2>M1%Al6Zfm30K1_ z@U_?jd)2Y=QmU9&p{7I&aU*+<9+1@L4ukUWBQug=(AQ&V1Wd&W4gypay`VEbhBYuA zZ2ZIA6ErI@GaW$gkv}!iije0HtQ&&Z5>Or(jg3wEM4HFi8{6@7b{o;L2Z|9suLx*z z2tc>nhfRN9t;DOSOy!|CkyQcOic6qd)>Wb64KU$N-2i1o%%dyY#81_ErB!P4rB1w= zSN}4E@DCvN)J962R6$UQQRt|x(>n)rk5a4y7(R9 z7&L&ZGg7F<2E%Bjo8~W1Z^oq!a?*9~QR=0ODwr-Ib&1s;rx|Ym!G8NxQfU&cDWMmV z23Ri#qbrCH<^b?5Xl}R2G$$)(G{y1>3R z8(>30*Rle_QIa8tsgp4*VCq%sqv{Q&oB;p8{Aob=;#&N>N1=0tfAovNEgH z4~|w|kElY_W}>oz_#{Sa1AXyX2{~iiPs1YdDJ~T53+0>(MUU$NoM7O@d(vQE6dj4-!oBtWin#`ij^^U3Z&5~3 zTopeA6@20*^9VAwyd2Hdh0b3fPBKTkE3fsRU7`#!=;16@XZ#AcLT!;{F1|2f_Tcj5 z0*m)}@w8-Z0&**$#dN?J-wdEA_{oLoPj}rD0+P@gQ!#y{&vR(6$IYZ zcK2BCC7LA|4yo3~a(GjSzs@!jROeT>B z6;m*HzYF4%T3ZI% zsk!z}QEC2^gr#Ci;ZkO)oUIE)s^__h^5fb4D_EvJSq^Yqg=KWHtI#;DRYLIBU zKb_xAv}_c`MkTgNYR@yN*PEetbxvKkXZ9e7$~C?{TFh%kzns^Y8-x7i^CuORbxY%{ zd6z}@0at&$pMH#C^`qlu*=Q7~6OZHK9ZzwMjuJ%Q3hL(_HhN6(4G)Cl0NW!{D9!vw zP&JmvF(Au0+_FHXisB&sCy6NtXUt-Ju^I2lzU zWqztebpVg!WK@Zi`Kc0l0R9Lkqe`UAPnF0A@BuDrRf*IeHZqmFaEgJ|ODF>Pu`n^x z80lnAUOQ_-VtdJMi-78%4Agmt;eW;PO=b46UmUDzLOc`na!b(HCuN zC*^;&cQr9m6j8WmXON#o*hN78ov1-vbb>4pObG7mA3}CnT{cm}p`D%S*_magd(u6N z3kRbHFC2_=5l<2m6C)SV%Mt^@Xb3?Ln5YMdx(RAly|9Vl=i=H`^#hM44<7m* z_H}*peyXagt9pB;zpA@Jm+;7T>Q-jVp2+Ywr zWye+urvI61RdUP_j%t;G zmS_#+pJ`F`?NlRgOTZr=m32XE^q-!uYC8SVtLs^V@1ZX1zp+)-#G?YD{l%ZpWw(>e2B6yZM!^}=U`tCkW?>PyeR zNBr^O80u-#;cY~}O8nc}Ref@Gv_Hx*;{Q>Hs+SOZTL0tVkI!(XI#fMK?6Lo_StsBa z`+vb^RsUkBLi3*@{x>$O`U-KN%_jc-KaNqOI(;wgDQpyKo7Is=gW0j#TUr+R>c>}byUR{$@NjiTjjc^ z;)~^arsDU@bxOsT$n{6Xm&$cT#oOe%q2ldwJy7vwa-LW52ju*%;>+c{tl}%=e5>Ls z8}q1wKPcx%6%T!J3ixUbzD9$u)!^$i_<9Y#L4!XO!o>9#KJToUGG^zf{W|UwK3^Ri z51+4{91owbKFGU;wD&{6PpuH;YhZt&geeq0KW`4ZlbgT;(xD+|7S9KoZo^t(=gs}m@*Csj>9~O z?L496GMW2^LnmDgv9Naq*@V5ZRT_w*0eiHEKmWwjJKmQrvxJ5Aj z-sP*5xHqIS&F#bYKfghoE~qT_&zz?IMn1==2&<0GcoE&Yk$3A}eWF<8oPj+fL&N64 z-UB11>6dzy(!QQRq2QQf6=yV8G5J$GGdD45bwtJw@Y)13PXal>t_6+Rp?lHG!wq~|B z<)`Evkg9o@aMHARZ3EnqMQ)_}1(_&K{`}RCUa{=vm65EQoKH4?$jp}xnZ;bW(s0`r zqCaGGk2S|rBfHisWxGJ?6l9m=%#)r~Gso_se}L0ePc$5)pVTrOa$ZU`8|(6Fjnp7; z9hl*>D`^-h!Ka3=v+7@2PX4ZqLo1=m^*!>qQ zs*(`7$f!E++8D_~yYH|$Y>kz@y5;s%{LyIn!^MjjE-Hy>fNfOISscL`nxD+Ev7W1x zkJ77-e;uLaSoQ~_;4x(bzTw%K*%mcd#u7^`vBVNfEV0BAODwU(5=$(x#1cy^vHXwZ MAM|dYTmbL@0J;sy6#xJL diff --git a/chef-templates/jenkins/attachments/rightscale_login_policy.te b/chef-templates/jenkins/attachments/rightscale_login_policy.te deleted file mode 100644 index 66e4021..0000000 --- a/chef-templates/jenkins/attachments/rightscale_login_policy.te +++ /dev/null @@ -1,18 +0,0 @@ -module rightscale_login_policy 1.0; - -require { - type sshd_t; - type var_lib_t; - type chkpwd_t; - type unconfined_t; - type oddjob_mkhomedir_exec_t; - class file { open read entrypoint ioctl getattr }; -} - -#============= sshd_t ============== -allow sshd_t var_lib_t:file { ioctl open read getattr }; -allow chkpwd_t var_lib_t:file { ioctl open read getattr }; - - -#============= unconfined_t ============== -allow unconfined_t oddjob_mkhomedir_exec_t:file entrypoint; diff --git a/chef-templates/jenkins/attachments/rs-ssh-keys.sh b/chef-templates/jenkins/attachments/rs-ssh-keys.sh deleted file mode 100644 index 2b1cf53..0000000 --- a/chef-templates/jenkins/attachments/rs-ssh-keys.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -# -# rs-ssh-keys.sh - tool to obtain users' ssh public keys from the RightScale policy file. -# - -set -e - -# Check that username is provided -if [ $# -eq 0 ]; then - logger -i -p auth.warn -t rs-ssh-keys.sh "username was not provided and is required" - exit 1 -fi -username=$1 - -# Grab username info from policy file and exit if it does not exist -policy_username_entry=`grep -E "^$username:|^[0-9a-z_\-]*:$username:" /var/lib/rightlink/login_policy` || true -if [[ "$policy_username_entry" == "" ]]; then - # Not in policy file - exit 0 -fi -read preferred_name unique_name policy_uid <<< $(echo $policy_username_entry | cut -d: -f1,2,4 --output-delimiter=' ') - -# Grab username info from system -system_username_entry=`getent passwd ${username}` || true -if [[ "$system_username_entry" == "" ]]; then - # At this point, user from policy file should be returned. If nothing or error is returned, exit 1 with no keys. - logger -i -p auth.warn -t rs-ssh-keys.sh "issue searching for username: ${username}" - exit 1 -fi -read system_uid <<< $(echo $system_username_entry | cut -d: -f3 --output-delimiter=' ') - -# Determine if the entry found has matching system UID. -# If there is another user from another NSS plugin, this is not our user, so return no keys. -if [[ "$system_uid" == "$policy_uid" ]]; then - # User is from policy file so get and set keys - logger -i -p auth.info -t rs-ssh-keys.sh "username '${username}' matches entry in login policy - sending keys" - echo $policy_username_entry | cut -d: -f7- | tr : "\n" -else - logger -i -p auth.warn -t rs-ssh-keys.sh "username '${username}' matches another NSS method - not using login policy keys" -fi From a7c2832ba97368d343417d18e60cfb8beccfa41a Mon Sep 17 00:00:00 2001 From: Richard Shade Date: Thu, 12 Dec 2019 14:22:11 -0600 Subject: [PATCH 13/13] adding local versions --- chef-templates/jenkins/Jenkins-Master.yml | 20 ++++++++++++++----- chef-templates/jenkins/Jenkins-Slave.yml | 20 ++++++++++++++----- .../jenkins/RL10_Jenkins_Install_Master.sh | 2 +- .../jenkins/RL10_Jenkins_Install_Slave.sh | 2 +- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/chef-templates/jenkins/Jenkins-Master.yml b/chef-templates/jenkins/Jenkins-Master.yml index 280decd..08379c6 100644 --- a/chef-templates/jenkins/Jenkins-Master.yml +++ b/chef-templates/jenkins/Jenkins-Master.yml @@ -15,11 +15,21 @@ Inputs: RS_INSTANCE_UUID: env:RS_INSTANCE_UUID RightScripts: Boot: - - RL10_Linux_Setup_Hostname.sh - - RL10_Linux_Enable_Managed_Login.sh - - RL10_Linux_Enable_Monitoring.sh - - RL10_Linux_Setup_Alerts.sh - - RL10_Linux_Setup_Automatic_Upgrade.sh + - Name: RL10 Linux Wait For EIP + Revision: 5 + Publisher: RightScale + - Name: RL10 Linux Setup Hostname + Revision: 8 + Publisher: RightScale + - Name: RL10 Linux Enable Managed Login + Revision: 12 + Publisher: RightScale + - Name: RL10 Linux Setup Alerts + Revision: 2 + Publisher: RightScale + - Name: RL10 Linux Setup Automatic Upgrade + Revision: 4 + Publisher: RightScale - RL5_6_10_Setup_Custom_Logrotate_Configs.sh - Storage_Toolbox_Stripe-chef.sh - RL10_Jenkins_Install_Master.sh diff --git a/chef-templates/jenkins/Jenkins-Slave.yml b/chef-templates/jenkins/Jenkins-Slave.yml index 65e39bb..2851584 100644 --- a/chef-templates/jenkins/Jenkins-Slave.yml +++ b/chef-templates/jenkins/Jenkins-Slave.yml @@ -15,11 +15,21 @@ Inputs: RS_INSTANCE_UUID: env:RS_INSTANCE_UUID RightScripts: Boot: - - RL10_Linux_Setup_Hostname.sh - - RL10_Linux_Enable_Managed_Login.sh - - RL10_Linux_Enable_Monitoring.sh - - RL10_Linux_Setup_Alerts.sh - - RL10_Linux_Setup_Automatic_Upgrade.sh + - Name: RL10 Linux Wait For EIP + Revision: 5 + Publisher: RightScale + - Name: RL10 Linux Setup Hostname + Revision: 8 + Publisher: RightScale + - Name: RL10 Linux Enable Managed Login + Revision: 12 + Publisher: RightScale + - Name: RL10 Linux Setup Alerts + Revision: 2 + Publisher: RightScale + - Name: RL10 Linux Setup Automatic Upgrade + Revision: 4 + Publisher: RightScale - RL5_6_10_Setup_Custom_Logrotate_Configs.sh - Storage_Toolbox_Stripe-chef.sh - RL10_Jenkins_Install_Slave.sh diff --git a/chef-templates/jenkins/RL10_Jenkins_Install_Master.sh b/chef-templates/jenkins/RL10_Jenkins_Install_Master.sh index 5c50a1a..ac9e08a 100755 --- a/chef-templates/jenkins/RL10_Jenkins_Install_Master.sh +++ b/chef-templates/jenkins/RL10_Jenkins_Install_Master.sh @@ -41,7 +41,7 @@ set -e export LC_CTYPE=en_US.UTF-8 if [ ! -e /usr/bin/chef-client ]; then - curl -L https://www.opscode.com/chef/install.sh | sudo bash -s -- -v 12.19.36 + curl -L https://omnitruck.chef.io/install.sh | sudo bash -s -- "12.19.36" fi chef_dir="/home/rightscale/.chef" diff --git a/chef-templates/jenkins/RL10_Jenkins_Install_Slave.sh b/chef-templates/jenkins/RL10_Jenkins_Install_Slave.sh index 345fdb7..eae630d 100755 --- a/chef-templates/jenkins/RL10_Jenkins_Install_Slave.sh +++ b/chef-templates/jenkins/RL10_Jenkins_Install_Slave.sh @@ -187,7 +187,7 @@ set -e export LC_CTYPE=en_US.UTF-8 if [ ! -e /usr/bin/chef-client ]; then - curl -L https://www.opscode.com/chef/install.sh | sudo bash -s -- -v 12.19.36 + curl -L https://omnitruck.chef.io/install.sh | sudo bash -s -- "12.19.36" fi chef_dir="/home/rightscale/.chef"