diff --git a/.travis.yml b/.travis.yml index 05533c2..621cbd5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,19 +6,16 @@ sudo: false matrix: fast_finish: true include: - - rvm: 1.8.7 - env: PUPPET_GEM_VERSION="~> 3.3.0" - - rvm: 1.8.7 - env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" - - rvm: 1.9.3 - env: PUPPET_GEM_VERSION="~> 3.3.0" - rvm: 1.9.3 - env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" + env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 2.0.0 - env: PUPPET_GEM_VERSION="~> 3.3.0" + env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 2.0.0 env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" - - rvm: 2.1.0 + - rvm: 2.1.5 + env: PUPPET_GEM_VERSION="~> 4.0" + allow_failures: + - rvm: 2.0.0 env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" notifications: email: false diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index 52d936d..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,12 +0,0 @@ - Allow not installing nodejs -20140417 - v0.2.0 - Add hubot alias command - Update nodejs module requirements -20131226 - v0.1.2 - Fix for empty external-scripts and hubot-scripts -20131005 - v0.1.1 - Added log extension to default logfile - Fixed params::display_name lookup -20131006 - v0.1.0: - Initial public release - diff --git a/LICENSE b/LICENSE index c2c07f3..ee50949 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,3 @@ - Copyright 2013 EvenUp Inc - 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 diff --git a/README.md b/README.md index 2c136ba..318098a 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A puppet module that installs and manages a [hubot](http://hubot.github.com) bot There are two methods of configuring hubot, setting the available parameters (useful for trying it out/simple configs) and storing your config and scripts in git. Instructions below as well on migrating from parameter config to repo configuration. -Configuring via puppet +Configuring via Puppet ---------------------- This method is great for giving hubot a try to figure out what it's all about and maintaining a simple configuration. If you want to be able to run hubot with only the shell adapter, no configuration is required other than including this class and then running /opt/hubot/hubot/bin/hubot (that's a lot of hubots) and interact with him on the shell. @@ -69,7 +69,7 @@ Puppet will now keep hubot up to date based on this git repo and restart the ser Known Issues: ------------- -Only tested on CentOS 6, but should be pretty agnostic. Feedback/PRs appreciated! +Only tested on Ubuntu 14.04 but should be flexible. Feedback/PRs appreciated! License: diff --git a/manifests/config.pp b/manifests/config.pp index e42b8de..8e81ed9 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -6,6 +6,7 @@ # # === Authors # +# * Foxx Block # * Justin Lambert # # @@ -19,17 +20,47 @@ fail("Use of private class ${name} by ${caller_module_name}") } - $exports = $::hubot::env_export - $scripts = $::hubot::scripts + $dependencies = $::hubot::dependencies + $exports = $::hubot::env_export $external_scripts = $::hubot::external_scripts - $dependencies = $::hubot::dependencies - file { '/etc/init.d/hubot': - ensure => 'file', - owner => 'root', - group => 'root', - mode => '0555', - content => template("hubot/${hubot::params::hubot_init}"), - notify => Class['hubot::service'], + $hubotversion = $::hubot::hubot_version + $scripts = $::hubot::scripts + + case $hubot::init_style { + 'upstart': { + file { '/etc/init.d/hubot': + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0555', + content => template("hubot/${hubot::params::hubot_init}"), + notify => Class['hubot::service'], + } + file { 'hubot upstart': + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0644', + path => '/etc/init/hubot.conf', + content => template('hubot/hubot.upstart.erb'), + } + } + 'systemd': { + file { '/lib/systemd/system/hubot.service': + mode => '0644', + owner => 'root', + group => 'root', + content => template('hubot/hubot.systemd.erb'), + } + ~> exec { 'hubot-systemd-reload': + command => 'systemctl daemon-reload', + path => [ '/usr/bin', '/bin', '/usr/sbin' ], + refreshonly => true, + } + } + default: { + fail("init_style was not specified: ${hubot::init_style}!") + } } if $::hubot::git_source { @@ -76,28 +107,38 @@ revision => 'master', notify => Class['hubot::service'], } - + unless empty($::hubot::env_export) { file { "${::hubot::root_dir}/${::hubot::bot_name}/hubot.env": - ensure => 'file', - owner => 'hubot', - group => 'hubot', - mode => '0440', - content => template('hubot/hubot.env.erb'), - notify => Class['hubot::service'], - require => Vcsrepo["${::hubot::root_dir}/${::hubot::bot_name}"], + ensure => 'file', + owner => 'hubot', + group => 'hubot', + mode => '0440', + show_diff => $::hubot::env_file_show_diff, + content => template('hubot/hubot.env.erb'), + notify => Class['hubot::service'], + require => Vcsrepo["${::hubot::root_dir}/${::hubot::bot_name}"], } } } else { + file { "${::hubot::root_dir}/${::hubot::bot_name}": + ensure => 'directory', + owner => 'hubot', + group => 'hubot', + mode => '0750', + require => File[$::hubot::root_dir], + } + exec { 'Hubot init': - command => "hubot -c ${::hubot::bot_name}", - cwd => $::hubot::root_dir, - path => '/usr/bin', - unless => "test -d ${::hubot::root_dir}/${::hubot::bot_name}", + command => 'yo hubot --defaults --no-insight', + cwd => "${::hubot::root_dir}/${::hubot::bot_name}/", + creates => "${::hubot::root_dir}/${::hubot::bot_name}/bin/hubot", + path => '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin', user => 'hubot', group => 'hubot', logoutput => 'on_failure', + require => File["${::hubot::root_dir}/${::hubot::bot_name}"], } file { "${::hubot::root_dir}/${::hubot::bot_name}/debug.sh": @@ -148,7 +189,5 @@ notify => Class['hubot::service'], require => Exec['Hubot init'], } - } - } diff --git a/manifests/init.pp b/manifests/init.pp index f13525b..bdf823a 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -33,6 +33,11 @@ # that should be exported for this bot # Default: {} # +# [*env_file_show_diff*] +# Boolean. Enable showing diff of hubot environment variable file. Setting this to true could expose +# secrets that might be getting assigned to environment variables for hubot. +# Default: false +# # [*scripts*] # Array of Strings. Used when not using git_source. List of scripts to be # included from hubot-scripts @@ -120,6 +125,7 @@ $chat_alias = $::hubot::params::chat_alias, $build_deps = $::hubot::params::build_deps, $env_export = $::hubot::params::env_export, + $env_file_show_diff = $::hubot::params::env_file_show_diff, $scripts = $::hubot::params::scripts, $external_scripts = $::hubot::params::external_scripts, $log_file = $::hubot::params::log_file, @@ -133,6 +139,8 @@ $service_enable = $::hubot::params::service_enable, $install_nodejs = $::hubot::params::install_nodejs, $nodejs_manage_repo = $::hubot::params::nodejs_manage_repo, + $init_style = $::hubot::params::init_style, + ) inherits hubot::params { if $log_file { @@ -150,10 +158,25 @@ } if $install_nodejs { - class { '::nodejs': - manage_package_repo => $nodejs_manage_repo, - before => Package['hubot'], + + case $init_style { + 'upstart': { + class { '::nodejs': + manage_package_repo => $nodejs_manage_repo, + before => Package['hubot'], + } + } + 'systemd': { + class { '::nodejs': + manage_package_repo => $nodejs_manage_repo, + nodejs_dev_package_ensure => 'present', + npm_package_ensure => 'present', + before => Package['hubot'], + } + } + default: {} } + } class { '::hubot::install': } diff --git a/manifests/install.pp b/manifests/install.pp index 4be435c..6b19a25 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -66,4 +66,16 @@ require => Package['hubot'], provider => 'npm' }) + + ensure_resource('package', 'generator-hubot', { + ensure => present, + require => Package['hubot'], + provider => 'npm' + }) + + ensure_resource('package', 'yo', { + ensure => present, + require => Package['hubot'], + provider => 'npm' + }) } diff --git a/manifests/params.pp b/manifests/params.pp index 7f4afa8..ff88286 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -21,6 +21,7 @@ $chat_alias = '/' $build_deps = [] $env_export = {} + $env_file_show_diff = false $scripts = [] $external_scripts = [] $log_file = undef @@ -35,10 +36,32 @@ $install_nodejs = true case $::operatingsystem { - /Ubuntu|Debian/: { + /Debian/: { + if versioncmp($::operatingsystemrelease, '7.0') > 0 { + $init_style = 'systemd' + } + else { + $init_style = 'debian' + } $hubot_init = "hubot.init.${::operatingsystem}.erb" $nodejs_manage_repo = true } + /Ubuntu/: { + if versioncmp($::operatingsystemrelease, '14.04') > 0 { + $init_style = 'systemd' + } + else { + $init_style = 'upstart' + } + $hubot_init = "hubot.init.${::operatingsystem}.erb" + $nodejs_manage_repo = true + } + /RedHat|CentOS/: { + if versioncmp($::operatingsystemrelease, '7.0') > 0 { + $init_style = 'systemd' + $nodejs_manage_repo = false + } + } default: { $hubot_init = 'hubot.init.erb' $nodejs_manage_repo = false diff --git a/metadata.json b/metadata.json index 3967088..de3fede 100644 --- a/metadata.json +++ b/metadata.json @@ -1,21 +1,21 @@ { - "name": "evenup-hubot", - "version": "0.2.0", - "author": "Justin Lambert ", + "name": "frozenfoxx-hubot", + "version": "1.4.0", + "author": "frozenfoxx ", "license": "Apache-2.0", "summary": "Installs, configures, and runs a hubot bot by configuring all parameters or as config from a git repo", - "source": "https://github.com/evenup/evenup-hubot", - "project_page": "https://github.com/evenup/evenup-hubot", - "issues_url": "https://github.com/evenup/evenup-hubot/issues", - "tags": ["hubot", "jira"], + "source": "https://github.com/frozenfoxx/puppet-hubot", + "project_page": "https://github.com/frozenfoxx/puppet-hubot", + "issues_url": "https://github.com/frozenfoxx/puppet-hubot/issues", + "tags": ["hubot", "chatops"], "operatingsystem_support": [ { "operatingsystem": "RedHat", "operatingsystemrelease": [ "6", "7" ] }, { "operatingsystem": "CentOS", "operatingsystemrelease": [ "6", "7" ] }, - { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ "10.04", "12.04", "14.04" ] }, + { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ "14.04", "16.04" ] }, { "operatingsystem": "Debian", "operatingsystemrelease": [ "7", "8" ] } ], "dependencies": [ - { "name": "puppet/nodejs", "version_requirement": ">=1.0.0 <2.0.0" }, + { "name": "puppet/nodejs", "version_requirement": ">=1.0.0 <2.3.0" }, { "name": "puppetlabs/stdlib", "version_requirement": ">=3.2.0 <5.0.0" } ] } diff --git a/spec/classes/hubot_spec.rb b/spec/classes/hubot_spec.rb index 44a12e2..9af2fb7 100644 --- a/spec/classes/hubot_spec.rb +++ b/spec/classes/hubot_spec.rb @@ -96,9 +96,8 @@ context 'no git_source' do it { should contain_exec('Hubot init').with( - :command => 'hubot -c hubot', - :cwd => '/opt/hubot', - :unless => 'test -d /opt/hubot/hubot' + :command => 'yo hubot --defaults --no-insight', + :cwd => '/opt/hubot/hubot', ) } it { should contain_file('/opt/hubot/hubot/hubot.env')} it { should contain_file('/opt/hubot/hubot/hubot-scripts.json')} @@ -120,8 +119,8 @@ context 'changing bot_name' do let(:params) { { :bot_name => 'foobot' } } it { should contain_exec('Hubot init').with( - :command => 'hubot -c foobot', - :unless => 'test -d /opt/hubot/foobot' + :command => 'yo hubot --defaults --no-insight', + :cwd => '/opt/hubot/foobot', ) } it { should contain_file('/opt/hubot/foobot/hubot.env')} it { should contain_file('/opt/hubot/foobot/hubot-scripts.json')} diff --git a/templates/hubot.env.erb b/templates/hubot.env.erb index 9cfbff2..52830b1 100644 --- a/templates/hubot.env.erb +++ b/templates/hubot.env.erb @@ -1,3 +1,7 @@ <% @exports.sort_by{|k,v| k}.each do |k,v| -%> +<% if scope.lookupvar('hubot::init_style') == 'upstart' -%> export <%= "#{k}=\"#{v}\"" %> +<% elsif scope.lookupvar('hubot::init_style') == 'systemd' -%> +<%= "#{k}=\"#{v}\"" %> +<% end -%> <% end -%> diff --git a/templates/hubot.init.Debian.erb b/templates/hubot.init.Debian.erb deleted file mode 120000 index 974469f..0000000 --- a/templates/hubot.init.Debian.erb +++ /dev/null @@ -1 +0,0 @@ -hubot.init.Ubuntu.erb \ No newline at end of file diff --git a/templates/hubot.init.Debian.erb b/templates/hubot.init.Debian.erb new file mode 100644 index 0000000..a4cf5c3 --- /dev/null +++ b/templates/hubot.init.Debian.erb @@ -0,0 +1,74 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: hubot +# Required-Start: $all +# Required-Stop: $all +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: starts the hubot service +# Description: starts the Hubot bot for the ADAPTER service specified +### END INIT INFO + +ROOT_DIR="<%= scope.lookupvar('hubot::root_dir') %>/<%= scope.lookupvar('hubot::bot_name') %>" +ADAPTER="<%= scope.lookupvar('hubot::adapter') %>" +LOG_FILE="<%= scope.lookupvar('hubot::log_file_real') %>" +USER=hubot +DISPLAY_NAME="<%= scope.lookupvar('hubot::display_name') %>" +ALIAS="<%= scope.lookupvar('hubot::chat_alias') %>" + +HUBOT_BIN="$ROOT_DIR/bin/hubot" +HUBOT_OPTS="--name ${DISPLAY_NAME} --adapter ${ADAPTER} --alias ${ALIAS}" +PIDFILE=/var/run/hubot.pid + +test -x $HUBOT_BIN || exit 0 + +. /lib/lsb/init-functions + +# ${ROOT_DIR}/hubot.env contains default settings +if [ -r ${ROOT_DIR}/hubot.env ]; then + . ${ROOT_DIR}/hubot.env +fi + +set -e + +start_bot () +{ + start-stop-daemon --start --quiet --chuid $USER --chdir $ROOT_DIR --pidfile $PIDFILE --make-pidfile --background --name hubot --startas $HUBOT_BIN -- $HUBOT_OPTS + log_end_msg $? +} + +stop_bot () +{ + start-stop-daemon --stop --quiet --pidfile $PIDFILE + STATUS=$? + if [ $STATUS == 0 ]; then + rm -r $PIDFILE + fi + log_end_msg $STATUS +} + +status_bot () +{ + if [ -r $PIDFILE ]; then + ps -fp `cat /var/run/hubot.pid ` + else + echo "No PIDfile $PIDFILE" + fi +} + +case "$1" in +start) log_daemon_msg "Starting Hubot - ${DISPLAY_NAME}" "hubot" + start_bot + ;; +stop) log_daemon_msg "Stopping Hubot - ${DISPLAY_NAME}" "hubot" + stop_bot + ;; +restart) log_daemon_msg "Restarting Hubot - ${DISPLAY_NAME}" "hubot" + stop_bot + start_bot + ;; +status) log_daemon_msg "Status of Hubot - ${DISPLAY_NAME}" "hubot" + status_of_proc -p /var/run/hubot.pid node hubot && exit 0 || exit $? + ;; +esac diff --git a/templates/hubot.systemd.erb b/templates/hubot.systemd.erb new file mode 100644 index 0000000..060d506 --- /dev/null +++ b/templates/hubot.systemd.erb @@ -0,0 +1,17 @@ +[Unit] +Description=hubot agent +Requires=network-online.target +After=network-online.target + +[Service] +EnvironmentFile=<%= scope['hubot::root_dir'] %>/<%= scope['hubot::bot_name'] %>/hubot.env +Restart=on-failure +WorkingDirectory=<%= scope['hubot::root_dir'] %>/<%= scope['hubot::bot_name'] %> +ExecStart=<%= scope['hubot::root_dir'] %>/<%= scope['hubot::bot_name'] %>/bin/hubot --name <%= scope['hubot::display_name'] %> --adapter <%= scope['hubot::adapter'] %> --alias <%= scope['hubot::chat_alias'] %> +ExecReload=/bin/kill -HUP $MAINPID +KillSignal=SIGINT +RestartSec=10s +User=hubot + +[Install] +WantedBy=multi-user.target diff --git a/templates/hubot.upstart.erb b/templates/hubot.upstart.erb new file mode 100644 index 0000000..69dacf0 --- /dev/null +++ b/templates/hubot.upstart.erb @@ -0,0 +1,24 @@ +description "Hubot chatbot" + +# Subscribe to these upstart events +# This will make Hubot start on system boot +start on filesystem or runlevel [2345] +stop on runlevel [!2345] + +# Path to Hubot installation + +# Keep the process alive, limit to 5 restarts in 60s +respawn +respawn limit 5 60 + +script + export HUBOT_PATH="<%= scope.lookupvar('hubot::root_dir') %>/<%= scope.lookupvar('hubot::bot_name') %>" + export LOGFILE="<%= scope.lookupvar('hubot::log_file_real') %>" + export DAEMON="${HUBOT_PATH}/bin/hubot" + export ARGS="-a <%= scope.lookupvar('hubot::adapter') %> -n <%= scope.lookupvar('hubot::display_name') %>" + export ENV="${HUBOT_PATH}/hubot.env" + + . $ENV + + exec start-stop-daemon --start --chuid ${HUBOT_USER} --chdir $HUBOT_PATH --exec ${DAEMON} -- ${ARGS} >> ${LOGFILE} 2>&1 +end script diff --git a/templates/package.json.erb b/templates/package.json.erb index 940d5d5..2d9a812 100644 --- a/templates/package.json.erb +++ b/templates/package.json.erb @@ -1,6 +1,6 @@ { "name": "hosted-hubot", - "version": "2.8.3", + "version": "<%= @hubotversion -%>", "private": true, "author": "GitHub Inc.",