manifest 9.45 KB
Newer Older
Darko Poljak's avatar
Darko Poljak committed
1
#!/bin/sh -e
2 3
#
# 2015 Steven Armstrong (steven-cdist at armstrong.cc)
4
# 2015-2019 Nico Schottelius (nico-cdist at schottelius.org)
5
# 2019 Timothée Floure (timothee.floure at ungleich.ch)
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#

os=$(cat "$__global/explorer/os")

25 26
###
# Type parameters.
27 28 29 30

state="$(cat "$__object/parameter/state")"
user="$(cat "$__object/parameter/user")"
group="$(cat "$__object/parameter/group")"
31 32 33 34 35 36 37 38
release=$(cat "$__global/explorer/lsb_release")
if [ -f "$__object/parameter/use-distribution-package" ]; then
  use_distribution_package=1
fi

###
# Those are default that might be overriden by os-specific logic.

39 40 41
data_dir="/var/lib/consul"
conf_dir="/etc/consul/conf.d"
conf_file="config.json"
42
tls_dir="$conf_dir/tls"
43

44 45
###
# Sane deployment, based on distribution package when available.
46

47 48 49 50 51
distribution_setup () {
  case "$os" in
     debian)
       # consul is only available starting Debian 10 (buster).
       # See https://packages.debian.org/buster/consul
52
       if [ "$release" -lt 10 ]; then
53 54 55 56 57 58 59 60 61
         echo "Consul is not available for your debian release." >&2
         echo "Please use the 'manual' (i.e. non-package) installation or \
           upgrade the target system." >&2
         exit 1
       fi

       # Override previously defined environment to match debian packaging.
       conf_dir='/etc/consul.d'
       user='consul'
62
       group='consul'
63
     ;;
64 65 66 67 68 69 70 71 72 73 74
     alpine)
       # consul is only available starting Alpine 3.12 (= edge during the 3.11 cycle).
       # See https://pkgs.alpinelinux.org/packages?name=consul&branch=edge

       # Override previously defined environment to match alpine packaging.
       conf_dir='/etc/consul'
       conf_file='server.json'
       data_dir='/var/consul'
       user='consul'
       group='consul'
     ;;
75 76 77 78 79 80 81 82 83 84
     *)
        echo "Your operating system ($os) is currently not supported with the \
          --use-distribution-package flag (${__type##*/})." >&2
        echo "Please use non-package installation or contribute an \
          implementation for if you can." >&2
        exit 1
     ;;
  esac

  # Install consul package.
85
  __package consul --state "$state"
86 87 88 89 90 91

  export config_deployment_requires="__package/consul"
}

###
# LEGACY manual deployment, kept for compatibility reasons.
92

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
init_sysvinit()
{
    __file /etc/init.d/consul \
        --owner root --group root --mode 0755 \
        --state "$state" \
        --source "$__type/files/consul.sysv-$1"
    require="__file/etc/init.d/consul" __start_on_boot consul
}

init_systemd()
{
    __file /lib/systemd/system/consul.service \
        --owner root --group root --mode 0644 \
        --state "$state" \
        --source "$__type/files/consul.systemd"
        require="__file/lib/systemd/system/consul.service" __start_on_boot consul
}

init_upstart()
{
113
    __file /etc/init/consul-prepare.conf \
114 115
        --owner root --group root --mode 0644 \
        --state "$state" \
116 117 118 119 120 121
        --source "$__type/files/consul-prepare.upstart"
    require="__file/etc/init/consul-prepare.conf" \
        __file /etc/init/consul.conf \
            --owner root --group root --mode 0644 \
            --state "$state" \
            --source "$__type/files/consul.upstart"
122 123
    require="__file/etc/init/consul.conf" __start_on_boot consul
}
124

125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
manual_setup () {
  case "$os" in
     alpine|scientific|centos|debian|devuan|redhat|ubuntu)
        # whitelist safeguard
        :
     ;;
     *)
        echo "Your operating system ($os) is currently not supported by this \
          type (${__type##*/})." >&2
        echo "Please contribute an implementation for it if you can." >&2
        exit 1
     ;;
  esac

  # FIXME: there has got to be a better way to handle the dependencies in this case
  case "$state" in
     present)
        __group "$group" --system --state "$state"
        require="__group/$group" __user "$user" \
          --system --gid "$group" --home "$data_dir" --state "$state"
     ;;
     *)
        echo "The $state state is not (yet?) supported by this type." >&2
        exit 1
     ;;
  esac

  # Create data directory.
153
  require="__user/consul" __directory "$data_dir" \
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
    --owner "$user" --group "$group" --mode 770 --state "$state"

  # Create config directory.
  require="__user/consul" __directory "$conf_dir" \
    --parents --owner root --group "$group" --mode 750 --state "$state"

  # Install init script to start on boot
  case "$os" in
      devuan)
          init_sysvinit debian
          ;;
      centos|redhat)
          os_version="$(sed 's/[^0-9.]//g' "$__global/explorer/os_version")"
          major_version="${os_version%%.*}"
          case "$major_version" in
              [456])
                  init_sysvinit redhat
                  ;;
              7)
                  init_systemd
                  ;;
              *)
                  echo "Unsupported CentOS/Redhat version: $os_version" >&2
                  exit 1
                  ;;
          esac
          ;;

      debian)
          os_version=$(cat "$__global/explorer/os_version")
          major_version="${os_version%%.*}"

          case "$major_version" in
              [567])
                  init_sysvinit debian
              ;;
              [89]|10)
                  init_systemd
              ;;
              *)
                  echo "Unsupported Debian version $os_version" >&2
                  exit 1
              ;;
          esac
          ;;

      ubuntu)
          init_upstart
          ;;
  esac

  config_deployment_requires="__user/consul __directory/$conf_dir"
}

###
# Trigger requested installation method.
if [ $use_distribution_package ]; then
  distribution_setup
else
  manual_setup
fi

216 217 218 219 220 221 222 223 224 225 226 227 228 229
###
# Install TLS certificates.

if [ -f "$__object/parameter/ca-file-source" ] || \
   [ -f "$__object/parameter/cert-file-source" ] || \
   [ -f "$__object/parameter/key-file-source" ]; then

   requires="$config_deployment_requires" __directory $tls_dir \
     --owner root --group "$group" --mode 750 --state "$state"

   # Append to service restart requirements.
   restart_requires="$restart_requires __directory/$conf_dir/tls"
fi

230 231
###
# Generate and deploy configuration.
232

233 234 235 236 237 238 239 240 241 242 243 244
json_configuration=$(
  echo "{"

  # parameters we define ourself
  printf '   "data_dir": "%s"\n' "$data_dir"

  cd "$__object/parameter/"
  for param in *; do
     case "$param" in
        state|user|group|json-config|use-distribution-package) continue ;;
        ca-file-source|cert-file-source|key-file-source)
           source="$(cat "$__object/parameter/$param")"
245 246
           destination="$tls_dir/${source##*/}"
           require="__directory/$tls_dir" \
247 248 249 250 251 252
              __file "$destination" \
                 --owner root --group consul --mode 640 \
                 --source "$source" \
                 --state "$state"
           key="$(echo "${param%-*}" | tr '-' '_')"
           printf '   ,"%s": "%s"\n' "$key" "$destination"
253
        ;;
254 255 256 257 258
        disable-remote-exec|disable-update-check|leave-on-terminate\
          |rejoin-after-leave|server|enable-syslog|verify-incoming|verify-outgoing)
           # handle boolean parameters
           key="$(echo "$param" | tr '-' '_')"
           printf '   ,"%s": true\n' "$key"
259
        ;;
260 261 262 263 264
        retry-join)
           # join multiple parameters into json array
           retry_join="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join")"
           # remove trailing ,
           printf '   ,"retry_join": [%s]\n' "${retry_join%*,}"
265
        ;;
266 267 268 269 270 271 272 273 274 275
        retry-join-wan)
           # join multiple parameters into json array over wan
           retry_join_wan="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join-wan")"
           # remove trailing ,
           printf '   ,"retry_join_wan": [%s]\n' "${retry_join_wan%*,}"
        ;;
        bootstrap-expect)
           # integer key=value parameters
           key="$(echo "$param" | tr '-' '_')"
           printf '   ,"%s": %s\n' "$key" "$(cat "$__object/parameter/$param")"
276
        ;;
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
        *)
           # string key=value parameters
           key="$(echo "$param" | tr '-' '_')"
           printf '   ,"%s": "%s"\n' "$key" "$(cat "$__object/parameter/$param")"
        ;;
     esac
  done
  if [ -f "$__object/parameter/json-config" ]; then
     json_config="$(cat "$__object/parameter/json-config")"
     if [ "$json_config" = "-" ]; then
        json_config="$__object/stdin"
     fi
     # remove leading and trailing whitespace and commas from first and last line
     # indent each line with 3 spaces for consistency
     json=$(sed -e 's/^[ \t]*/   /' -e '1s/^[ \t,]*//' -e '$s/[ \t,]*$//' "$json_config")
     printf '   ,%s\n' "$json"
  fi
  echo "}"
)
echo "$json_configuration" | require="$config_deployment_requires" \
  __file "$conf_dir/$conf_file" \
      --owner root --group "$group" --mode 640 \
      --state "$state" \
      --source -

# Set configuration deployment as requirement for service restart.
restart_requires="__file/$conf_dir/$conf_file"

###
# Restart consul agent after everything else.
require="$restart_requires" __service consul --action restart