commit 69f5baba5b21aaaa7ad9d4303f71b5657af9537c Author: Eric Renfro Date: Thu May 17 17:36:29 2018 -0400 initial commit diff --git a/.kitchen.yml b/.kitchen.yml new file mode 100644 index 0000000..79b5f8f --- /dev/null +++ b/.kitchen.yml @@ -0,0 +1,61 @@ +--- +driver: + name: docker + use_sudo: false + privileged: true + require_chef_omnibus: false + +verifier: + name: inspec + inspec_tests: + - test/integration/fabio/inspec + +platforms: + - name: ubuntu-14.04 + driver_config: + disable_upstart: false + image: ubuntu-upstart:14.04 + run_command: /sbin/init + + - name: debian-9.4 + driver_config: + run_command: /bin/systemd + + - name: ubuntu-16.04 + driver_config: + run_command: /sbin/init + + - name: centos-7 + driver_config: + run_command: /usr/lib/systemd/systemd + +provisioner: + name: salt_solo + #log_level: quiet + require_chef: false + formula: fabio + state_top: + base: + '*': + - fabio + pillars-from-files: + base.sls: pillar.example + pillars: + top.sls: + base: + '*': + - base + - fabio + fabio.sls: + fabio: + register: [] + scripts: [] + +suites: + - name: fabio-server + provisioner: + pillars: + fabio.sls: + fabio: + config: + server: True diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..5aef44f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +sudo: required +language: python +services: + - docker + +before_install: + - bundle install + +env: + matrix: + - INSTANCE: consul-server-ubuntu-1404 + - INSTANCE: consul-server-ubuntu-1604 + - INSTANCE: consul-server-centos-7 + +script: + - bundle exec kitchen verify ${INSTANCE} diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..c94467b --- /dev/null +++ b/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "test-kitchen" +gem "kitchen-docker" +gem "kitchen-salt" +gem "kitchen-inspec" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d919c41 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ + Copyright (c) 2013-2015 Salt Stack Formulas + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..a2f9fe0 --- /dev/null +++ b/README.rst @@ -0,0 +1,48 @@ +====== +fabio +====== + +.. note:: + + See the full `Salt Formulas installation and usage instructions + `_. + +Available states +================ + +.. contents:: + :local: + +``fabio`` +------------ + +Installs and configures the fabio service. + +``fabio.install`` +------------------ + +Downloads and installs the fabio binary file. + +``fabio.config`` +----------------- + +Provision the fabio configuration files and sources. + +``fabio.service`` +------------------ + +Adds the fabio service startup configuration or script to an operating system. + +To start a service during Salt run and enable it at boot time, you need to set following Pillar: + +.. code:: yaml + + fabio: + service: True + +``fabio-template`` +------------------- + +Installs and configures fabio template. + +.. vim: fenc=utf-8 spell spl=en cc=100 tw=99 fo=want sts=4 sw=4 et diff --git a/fabio/config.sls b/fabio/config.sls new file mode 100644 index 0000000..6ce0a85 --- /dev/null +++ b/fabio/config.sls @@ -0,0 +1,43 @@ +{%- from slspath + '/map.jinja' import fabio with context -%} + +fabio-config: + file.serialize: + - name: /etc/fabio/config.json + - formatter: json + - dataset: {{ fabio.config }} + - user: {{ fabio.user }} + - group: {{ fabio.group }} + - mode: 0640 + - require: + - user: fabio-user + {%- if fabio.service %} + - watch_in: + - service: fabio + {%- endif %} + +{% for script in fabio.scripts %} +fabio-script-install-{{ loop.index }}: + file.managed: + - source: {{ script.source }} + - name: {{ script.name }} + - template: jinja + - context: {{ script.get('context', {}) | yaml }} + - user: {{ fabio.user }} + - group: {{ fabio.group }} + - mode: 0755 +{% endfor %} + +fabio-script-config: + file.serialize: + - name: /etc/fabio.d/services.json + {% if fabio.service != False %} + - watch_in: + - service: fabio + {% endif %} + - user: {{ fabio.user }} + - group: {{ fabio.group }} + - require: + - user: fabio-user + - formatter: json + - dataset: + services: {{ fabio.register }} diff --git a/fabio/defaults.yaml b/fabio/defaults.yaml new file mode 100644 index 0000000..51491c0 --- /dev/null +++ b/fabio/defaults.yaml @@ -0,0 +1,22 @@ +fabio: + version: 1.5.9 + goversion: 1.10.2 + download_host: github.com + + service: false + + user: root + group: root + + config: + server: false + bind_addr: 0.0.0.0 + data_dir: /var/fabio + ui: true + enable_debug: false + log_level: info + retry_join: [] + retry_interval: 30s + datacenter: "main" + register: [] + scripts: [] diff --git a/fabio/files/config.json b/fabio/files/config.json new file mode 100644 index 0000000..e69de29 diff --git a/fabio/files/fabio.service b/fabio/files/fabio.service new file mode 100644 index 0000000..314c25e --- /dev/null +++ b/fabio/files/fabio.service @@ -0,0 +1,15 @@ +[Unit] +Description=fabio +Wants=network.target +After=network.target + +[Service] +EnvironmentFile=-/etc/{% if grains['os_family'] == 'Debian' %}default{% else %}sysconfig{% endif %}/fabio +ExecStart=/usr/local/bin/fabio agent -config-dir=/etc/fabio.d +ExecReload=/bin/kill -HUP $MAINPID +KillSignal=TERM +User={{ user }} +Group={{ group }} + +[Install] +WantedBy=multi-user.target diff --git a/fabio/files/fabio.sysvinit b/fabio/files/fabio.sysvinit new file mode 100644 index 0000000..f5176f9 --- /dev/null +++ b/fabio/files/fabio.sysvinit @@ -0,0 +1,196 @@ +#!/bin/bash +# +# fabio Manage the fabio agent +# +# chkconfig: 2345 95 95 +# description: fabio is a tool for service discovery and configuration +# processname: fabio +# config: /etc/fabio.conf +# pidfile: /var/run/fabio.pid + +### BEGIN INIT INFO +# Provides: fabio +# Required-Start: $local_fs $network +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Manage the fabio agent +# Description: fabio is a tool for service discovery and configuration +### END INIT INFO + +# source function library +. /etc/rc.d/init.d/functions + +prog="fabio" +exec="/usr/local/bin/$prog" +pidfile="/var/run/$prog.pid" +lockfile="/var/lock/subsys/$prog" +logfile="/var/log/$prog" +confdir="/etc/fabio.d" + +# pull in sysconfig settings +[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog + +user=${fabio_USER:-fabio} +group=${fabio_GROUP:-fabio} + +export GOMAXPROCS=${GOMAXPROCS:-2} + +start() { + [ -x $exec ] || exit 5 + + [ -d $confdir ] || exit 6 + + umask 077 + + touch $logfile $pidfile + chown "$user:$group" $logfile $pidfile + + echo -n $"Starting $prog: " + + ## holy shell shenanigans, batman! + ## daemon can't be backgrounded. we need the pid of the spawned process, + ## which is actually done via runuser thanks to --user. + ## you can't do "cmd &; action" but you can do "{cmd &}; action". + ## fabio 0.2.1 added -pid-file; although the following creates $pidfile + ## owned by fabio:fabio, using -pid-file results in a permission error. + daemon \ + --pidfile=$pidfile \ + --user="$user" \ + " { $exec agent -config-dir=$confdir &>> $logfile & } ; echo \$! >| $pidfile " + + RETVAL=$? + echo + + [ $RETVAL -eq 0 ] && touch $lockfile + + echo -n $"Waiting for fabio ready: " + + ## wait up to 60s for the rpc port to become listened-upon + ## fabio 0.2.1 got much slower to start! + count=0 + ready=0 + pid=$( cat ${pidfile} ) + while checkpid ${pid} && [ $count -lt 60 ] && [ $ready -ne 1 ]; do + count=$(( count + 1 )) + + if netstat -lptn | egrep -q ":8400.*LISTEN +${pid}/" ; then + ready=1 + else + sleep 1 + fi + done + + if [ $ready -eq 1 ]; then + RETVAL=0 + success + else + RETVAL=1 + failure + fi + + echo + return $RETVAL +} + +stop() { + echo -n $"Shutting down $prog: " + + ## graceful shutdown with leave + $exec leave &> /dev/null + RETVAL=$? + + ## wait up to 10s for the daemon to exit + if [ $RETVAL -eq 0 ]; then + count=0 + stopped=0 + pid=$( cat ${pidfile} ) + while [ $count -lt 10 ] && [ $stopped -ne 1 ]; do + count=$(( count + 1 )) + + if ! checkpid ${pid} ; then + stopped=1 + else + sleep 1 + fi + done + + if [ $stopped -ne 1 ]; then + RETVAL=125 + fi + fi + + if [ $RETVAL -eq 0 ]; then + success + rm -f $lockfile $pidfile + else + failure + fi + + echo + return $RETVAL +} + +restart() { + stop + start +} + +reload() { + echo -n $"Reloading $prog: " + killproc -p $pidfile $exec -HUP + echo +} + +force_reload() { + restart +} + +rh_status() { + status -p "$pidfile" -l $prog $exec + + RETVAL=$? + + [ $RETVAL -eq 0 ] && $exec members + + return $RETVAL +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart) + $1 + ;; + reload) + rh_status_q || exit 7 + $1 + ;; + force-reload) + force_reload + ;; + status) + rh_status + ;; + condrestart|try-restart) + rh_status_q || exit 0 + restart + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac + +exit $? diff --git a/fabio/files/fabio.upstart b/fabio/files/fabio.upstart new file mode 100644 index 0000000..ef3a5a2 --- /dev/null +++ b/fabio/files/fabio.upstart @@ -0,0 +1,25 @@ +description "fabio agent" + +start on runlevel [2345] +stop on runlevel [!2345] + +respawn + +script + if [ -f /etc/default/fabio ]; then + . /etc/default/fabio + fi + + # Make sure to use all our CPUs, because fabio can block a scheduler thread + export GOMAXPROCS=`nproc` + + # Get the public IP + BIND=`ifconfig eth0 | grep "inet addr" | awk '{ print substr($2,6) }'` + + exec start-stop-daemon --start \ + --chuid ${fabio_USER:-fabio}:${fabio_GROUP:-fabio} \ + --exec /usr/local/bin/fabio agent -- \ + -config-dir="/etc/fabio.d" \ + ${fabio_FLAGS} \ + >> /var/log/fabio.log 2>&1 +end script diff --git a/fabio/init.sls b/fabio/init.sls new file mode 100644 index 0000000..48610da --- /dev/null +++ b/fabio/init.sls @@ -0,0 +1,6 @@ +{% from slspath+"/map.jinja" import fabio with context %} + +include: + - {{ slspath }}.install + - {{ slspath }}.config + - {{ slspath }}.service diff --git a/fabio/install.sls b/fabio/install.sls new file mode 100644 index 0000000..eaddb7f --- /dev/null +++ b/fabio/install.sls @@ -0,0 +1,73 @@ +{%- from slspath + '/map.jinja' import fabio with context -%} + +fabio-bin-dir: + file.directory: + - name: /usr/local/bin + - makedirs: True + + +{# +# Create fabio user +fabio-group: + group.present: + - name: {{ fabio.group }} + +fabio-user: + user.present: + - name: {{ fabio.user }} + - groups: + - {{ fabio.group }} + - home: {{ salt['user.info'](fabio.user)['home']|default(fabio.config.data_dir) }} + - createhome: False + - system: True + - require: + - group: fabio-group +#} + +# Create directories +fabio-config-dir: + file.directory: + - name: /etc/fabio + - user: {{ fabio.user }} + - group: {{ fabio.group }} + - mode: 0750 + +{# +fabio-data-dir: + file.directory: + - name: {{ fabio.config.data_dir }} + - makedirs: True + - user: {{ fabio.user }} + - group: {{ fabio.group }} + - mode: 0750 +#} + +# Install agent +fabio-download: + file.managed: + - name: /tmp/fabio-{{ fabio.version }} + - source: https://{{ fabio.download_host }}/fabiolb/fabio/releases/download/v{{ fabio.version }}/fabio{{ fabio.version }}-go{{ fabio.goversion }}-linux_{{ fabio.arch }} + - source_hash: https://github.com/fabiolb/fabio/releases/download/v{{ fabio.version }}/fabio-{{ fabio.version }}-go{{ fabio.goversion }}.sha256 + - unless: test -f /usr/local/bin/fabio-{{ fabio.version }} + +fabio-install: + file.rename: + - name: /usr/local/bin/fabio-{{ fabio.version }} + - source: /tmp/fabio-{{ fabio.version }} + - require: + - file: /usr/local/bin + - watch: + - file: fabio-download + +fabio-clean: + file.absent: + - name: /tmp/fabio-{{ fabio.version }} + - watch: + - file: fabio-install + +fabio-link: + file.symlink: + - target: fabio-{{ fabio.version }} + - name: /usr/local/bin/fabio + - watch: + - file: fabio-install diff --git a/fabio/map.jinja b/fabio/map.jinja new file mode 100644 index 0000000..550979d --- /dev/null +++ b/fabio/map.jinja @@ -0,0 +1,21 @@ +{% import_yaml slspath+"/defaults.yaml" as defaults %} + +{% set fabio = salt['pillar.get']('fabio', default=defaults.fabio, merge=True) %} + +{## Add any overrides based on CPU architecture. ##} +{% set fabio = salt['grains.filter_by']({ + 'armv6l': { + "arch": 'arm' + }, + 'armv7l': { + "arch": 'arm' + }, + 'x86_64': { + "arch": 'amd64' + } + } + ,grain="cpuarch" + ,merge=fabio) +%} + +{% do fabio.config.update({'retry_join': fabio.config.retry_join or []}) %} diff --git a/fabio/service.sls b/fabio/service.sls new file mode 100644 index 0000000..3aa8896 --- /dev/null +++ b/fabio/service.sls @@ -0,0 +1,51 @@ +{%- from slspath+"/map.jinja" import fabio with context -%} + +fabio-init-env: + file.managed: + {%- if grains['os_family'] == 'Debian' %} + - name: /etc/default/fabio + {%- else %} + - name: /etc/sysconfig/fabio + - makedirs: True + {%- endif %} + - user: root + - group: root + - mode: 0644 + - contents: + - fabio_USER={{ fabio.user }} + - fabio_GROUP={{ fabio.group }} + - fabio_UI_BETA={{ fabio.ui_beta }} + - GOMAXPROCS=2 + - PATH=/usr/local/bin:/usr/bin:/bin + +fabio-init-file: + file.managed: + {%- if salt['test.provider']('service') == 'systemd' %} + - source: salt://{{ slspath }}/files/fabio.service + - name: /etc/systemd/system/fabio.service + - template: jinja + - context: + user: {{ fabio.user }} + group: {{ fabio.group }} + - mode: 0644 + {%- elif salt['test.provider']('service') == 'upstart' %} + - source: salt://{{ slspath }}/files/fabio.upstart + - name: /etc/init/fabio.conf + - mode: 0644 + {%- else %} + - source: salt://{{ slspath }}/files/fabio.sysvinit + - name: /etc/init.d/fabio + - mode: 0755 + {%- endif %} + +{%- if fabio.service %} + +fabio-service: + service.running: + - name: fabio + - enable: True + - watch: + - file: fabio-init-env + - file: fabio-init-file + +{%- endif %} diff --git a/pillar.example b/pillar.example new file mode 100644 index 0000000..3cdcb90 --- /dev/null +++ b/pillar.example @@ -0,0 +1,15 @@ +fabio: + # Start Fabio + service: True + + # Set user and group for Fabio config files and running service + user: fabio + group: fabio + + config: + server: True + bind_addr: 0.0.0.0 + + enable_debug: True + +# vim: ft=yaml diff --git a/test/integration/fabio/inspec/fabio_spec.rb b/test/integration/fabio/inspec/fabio_spec.rb new file mode 100644 index 0000000..67c489a --- /dev/null +++ b/test/integration/fabio/inspec/fabio_spec.rb @@ -0,0 +1,4 @@ +describe service('fabio') do + it { should be_enabled } + it { should be_running } +end