Skip to content

Commit

Permalink
Initial import.
Browse files Browse the repository at this point in the history
  • Loading branch information
emilecantin committed Apr 18, 2012
0 parents commit 58557b9
Show file tree
Hide file tree
Showing 13 changed files with 636 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
@@ -0,0 +1,4 @@
*.gem
.bundle
Gemfile.lock
pkg/*
6 changes: 6 additions & 0 deletions Gemfile
@@ -0,0 +1,6 @@
source "http://rubygems.org"

# Specify your gem's dependencies in foreman-export-initscript.gemspec
gemspec

gem "fakefs", git: "git://github.com/defunkt/fakefs.git"
1 change: 1 addition & 0 deletions Rakefile
@@ -0,0 +1 @@
require "bundler/gem_tasks"
160 changes: 160 additions & 0 deletions data/export/initscript/master.erb
@@ -0,0 +1,160 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: <%= app %>
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Generated initscript for <%= app %>
# Description: This file starts <%= app %>. It should be placed in /etc/init.d
### END INIT INFO

# Author: Foreman generator
#

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Runs <%= app %>"
NAME=<%= app %>
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
# Add code here, if necessary, that waits for the process to be ready
# to handle requests from services started subsequently which depend
# on this one. As a last resort, sleep for some time.
}

### START EACH PROCESS
<% engine.procfile.entries.each do |process| %>
<% 1.upto(concurrency[process.name]) do |num| %>
do_start_<%= process.name %>_<%= num %>()
{
# This starts the process
}
<% end %>
<% end %>
###

#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}

### STOP EACH PROCESS
<% engine.procfile.entries.each do |process| %>
<% 1.upto(concurrency[process.name]) do |num| %>
do_stop_<%= process.name %>_<%= num %>()
{
# This starts the process
}
<% end %>
<% end %>
###

case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
#log_daemon_msg "Reloading $DESC" "$NAME"
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac

:
26 changes: 26 additions & 0 deletions foreman-export-initscript.gemspec
@@ -0,0 +1,26 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)

Gem::Specification.new do |s|
s.name = "foreman-export-initscript"
s.version = "0.0.1"
s.authors = ["Emile Cantin"]
s.email = ["emile.cantin@gmail.com"]
s.homepage = ""
s.summary = %q{Export foreman Procfile to a init script}
s.description = %q{Export foreman Procfile to a init script}

s.rubyforge_project = "foreman-export-initscript"

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]

# specify any dependencies here; for example:
s.add_development_dependency "rspec"
# s.add_development_dependency "fakefs", git: "git://github.com/defunkt/fakefs.git"
s.add_development_dependency "rr"
s.add_dependency "foreman"
# s.add_runtime_dependency "rest-client"
end
2 changes: 2 additions & 0 deletions lib/foreman-export-initscript.rb
@@ -0,0 +1,2 @@
require "foreman/export/initscript"

Empty file.
Binary file added lib/foreman/export/.initscript.rb.swp
Binary file not shown.
28 changes: 28 additions & 0 deletions lib/foreman/export/initscript.rb
@@ -0,0 +1,28 @@
require "erb"
require "foreman/export"

class Foreman::Export::Initscript < Foreman::Export::Base

def export
error("Must specify a location") unless location

FileUtils.mkdir_p location

app = self.app || File.basename(engine.directory)
user = self.user || app
log_root = self.log || "/var/log/#{app}"
template_root = Pathname.new(File.dirname(__FILE__)).join('..', '..', '..', 'data', 'export', 'initscript').expand_path

Dir["#{location}/#{app}"].each do |file|
say "cleaning up: #{file}"
FileUtils.rm(file)
end

master_template = export_template("initscript", "master.erb", template_root)
master_config = ERB.new(master_template).result(binding)
write_file "#{location}/#{app}", master_config

end

end

37 changes: 37 additions & 0 deletions spec/foreman/export/initscript_spec.rb
@@ -0,0 +1,37 @@
require "spec_helper"
require "foreman/engine"
require "foreman/export/initscript"
require "tmpdir"

describe Foreman::Export::Initscript, :fakefs do
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
let(:engine) { Foreman::Engine.new(procfile) }
let(:options) { Hash.new }
let(:initscript) { Foreman::Export::Initscript.new("/tmp/init", engine, options) }

before(:each) { load_export_templates_into_fakefs("initscript") }
before(:each) { stub(initscript).say }

it "exports to the filesystem" do
initscript.export
normalize_space(File.read("/tmp/init/app")).should == normalize_space(example_export_file("initscript/app"))
end

it "cleans up if exporting into an existing dir" do
mock(FileUtils).rm("/tmp/init/app")

initscript.export
require 'debug'
initscript.export
end

context "with concurrency" do
let(:options) { Hash[:concurrency => "alpha=2"] }

it "exports to the filesystem with concurrency" do
initscript.export
normalize_space(File.read("/tmp/init/app")).should == normalize_space(example_export_file("initscript/app-concurrency"))
end
end

end

0 comments on commit 58557b9

Please sign in to comment.