Permalink
Browse files

First commit

  • Loading branch information...
0 parents commit 1d26f40bd245236a3aa769408109a75526580628 Simon COURTOIS committed Oct 12, 2011
Showing with 356 additions and 0 deletions.
  1. +4 −0 .gitignore
  2. +55 −0 .rvmrc
  3. +4 −0 Gemfile
  4. +1 −0 Rakefile
  5. +62 −0 bin/ruploy
  6. +132 −0 data/ruploy-base.sh
  7. +28 −0 data/ruploy-init.mustache
  8. +46 −0 lib/ruploy.rb
  9. +3 −0 lib/ruploy/version.rb
  10. +21 −0 ruploy.gemspec
@@ -0,0 +1,4 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
55 .rvmrc
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+
+# This is an RVM Project .rvmrc file, used to automatically load the ruby
+# development environment upon cd'ing into the directory
+
+# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
+environment_id="ruby-1.9.2-p290@ruploy"
+
+#
+# Uncomment following line if you want options to be set only for given project.
+#
+# PROJECT_JRUBY_OPTS=( --1.9 )
+
+#
+# First we attempt to load the desired environment directly from the environment
+# file. This is very fast and efficient compared to running through the entire
+# CLI and selector. If you want feedback on which environment was used then
+# insert the word 'use' after --create as this triggers verbose mode.
+#
+if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
+then
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
+
+ if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
+ then
+ . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
+ fi
+else
+ # If the environment file has not yet been created, use the RVM CLI to select.
+ if ! rvm --create "$environment_id"
+ then
+ echo "Failed to create RVM environment '${environment_id}'."
+ exit 1
+ fi
+fi
+
+#
+# If you use an RVM gemset file to install a list of gems (*.gems), you can have
+# it be automatically loaded. Uncomment the following and adjust the filename if
+# necessary.
+#
+# filename=".gems"
+# if [[ -s "$filename" ]]
+# then
+# rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
+# fi
+
+# If you use bundler, this might be useful to you:
+# if command -v bundle && [[ -s Gemfile ]]
+# then
+# bundle install
+# fi
+
+
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in ruploy.gemspec
+gemspec
@@ -0,0 +1 @@
+require "bundler/gem_tasks"
@@ -0,0 +1,62 @@
+#!/usr/bin/env ruby
+
+require 'commander/import'
+require 'ruploy'
+
+program :name, 'Ruploy'
+program :version, '0.0.1'
+program :description, 'Generates init.d scripts to manage Rack apps using RVM'
+
+command :generate do |c|
+ c.syntax = 'ruploy generate init_script [options]'
+ c.description = 'Generates an init.d script for a given Rack application and prints it in init_script.'
+
+ c.option '-n', '--name NAME', 'Name of your application (default: current directory name)'
+ c.option '-d', '--directory PATH', 'Root path of the application (default: current directory)'
+ c.option '-a', '--address HOST', 'Bind to HOST address (default: 127.0.0.1)'
+ c.option '-p', '--port NUMBER', 'Use the given port number (default: 3000)'
+ c.option '-e', '--environment ENV', 'Framework environment (default: production)'
+ c.option '-u', '--user USERNAME', 'User to run as. Ignored unless running as root (default: www-data)'
+ c.option '--log-file FILENAME', 'Where to write log messages (default: /var/log/rack-$PROCNAME-$PORT.log)'
+ c.option '--pid-file FILENAME', 'Where to store the PID file (default: /var/lock/rack-$PROCNAME-$PORT)'
+ c.option '-s', '--server-type SERVER', 'Server type, can be "thin" or "passenger" (default: thin)'
+ c.option '--dependencies DEPS', 'Dependencies of the init script (default: apache2)'
+ c.option '-i', '--independent', 'Print the generic code in the file instead of including it'
+ c.option '--use-defaults', 'Do not ask for missing informations and use default values'
+
+ c.action do |args, opts|
+ script_file = args.shift
+ app_config = Ruploy.get_config(args, opts.__hash__)
+ init_file = Ruploy.generate_init_file(app_config, opts.independent)
+
+ File.open(script_file, 'w') do |f|
+ f.puts init_file
+ end
+
+ File.chmod(0755, script_file)
+ end
+end
+alias_command :g, :generate
+default_command :generate
+
+command :deploy do |c|
+ c.syntax = 'ruploy deploy init_script [service_name]'
+ c.description = 'Copies the init script to /etc/init.d/<service_name> and calls update-rc.d.'
+
+ c.option '-f', '--force', 'Force symlink creation if a file already exists'
+
+ c.action do |args, opts|
+ script, name = args
+ path = File.expand_path(script)
+ name ||= File.basename(script)
+ target = "/etc/init.d/#{name}"
+
+ print "Deploying #{name}... "
+
+ File.delete(target) if File.exists?(target) && opts.force
+ File.symlink(path, target)
+ `update-rc.d #{name} defaults`
+
+ puts '[OK]'
+ end
+end
@@ -0,0 +1,132 @@
+# Outputs [OK] or [KO] given the previous status code 0=ok *=ko
+ok_ko() {
+ local status=$?
+
+ case $status in
+ 0)
+ echo "[OK]"
+ ;;
+ *)
+ echo "[KO]"
+ ;;
+ esac
+
+ return $status
+}
+
+# returns the name of the running server process
+server_process() {
+ case $SERVER in
+ passenger)
+ echo "nginx"
+ ;;
+ thin)
+ echo "thin"
+ ;;
+ *)
+ echo "unknown_server"
+ ;;
+ esac
+}
+
+# Returns the PID of the given server instance
+server_pid() {
+ if [ -e "$PIDFILE" ]; then
+ if pidof $(server_process) | tr ' ' '\n' | grep -w $(cat $PIDFILE); then
+ return 0
+ fi
+ fi
+ return 1
+}
+
+# Returns the log-file option for the given server type
+logfile_option() {
+ case $SERVER in
+ passenger)
+ echo "--log-file"
+ ;;
+ thin)
+ echo "--log"
+ ;;
+ *)
+ echo "unknown_server"
+ ;;
+ esac
+}
+
+# Returns the pid-file option for the given server type
+pidfile_option() {
+ case $SERVER in
+ passenger)
+ echo "--pid-file"
+ ;;
+ thin)
+ echo "--pid"
+ ;;
+ *)
+ echo "unknown_server"
+ ;;
+ esac
+}
+
+# Starts the given server instance
+ruploy_start() {
+ echo -n "Starting ${NAME}... "
+ $SERVER start $DIRECTORY \
+ --address $ADDRESS \
+ --port $PORT \
+ --environment $ENVIRONMENT \
+ --user $USER \
+ $(pidfile_option) $PIDFILE \
+ $(logfile_option) $LOGFILE \
+ $OPTIONS > /dev/null
+ ok_ko
+}
+
+# Stops the given server instance
+ruploy_stop() {
+ echo -n "Stopping ${NAME}... "
+ $SERVER stop --pid-file $PIDFILE > /dev/null 2>&1
+ ok_ko
+}
+
+# Gives the status of the given server
+ruploy_status() {
+ PID=$(server_pid) || true
+ if [ -n "$PID" ]; then
+ echo "${NAME} is running (pid $PID)."
+ return 0
+ else
+ echo "${NAME} is NOT running."
+ return 1
+ fi
+}
+
+# Loading the rvm environment of the application
+. $DIRECTORY/.rvmrc
+
+case "$1" in
+ restart)
+ ruploy_stop
+ ruploy_start
+ exit $?
+ ;;
+ start)
+ ruploy_start
+ exit $?
+ ;;
+ status)
+ ruploy_status
+ exit $?
+ ;;
+ stop)
+ ruploy_stop
+ exit $?
+ ;;
+ *)
+ echo "Usage: $0 {restart|start|status|stop}"
+ exit 1
+ ;;
+esac
+
+exit 0
@@ -0,0 +1,28 @@
+#! /bin/sh
+### BEGIN INIT INFO
+# Provides: {{proc_name}}
+# Required-Start: $remote_fs $syslog
+# Required-Stop: $remote_fs $syslog
+# Should-Start: {{dependencies}}
+# Should-Stop: {{dependencies}}
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Start/Stop {{name}}
+# Description: Manage the actions related to the passenger instance of {{name}}
+# you can use start, stop, restart and status
+### END INIT INFO
+
+NAME="{{name}}"
+PROCNAME="{{proc_name}}"
+
+DIRECTORY="{{directory}}"
+ADDRESS="{{address}}"
+PORT="{{port}}"
+ENVIRONMENT="{{environment}}"
+USER="{{user}}"
+LOGFILE="{{log_file}}"
+PIDFILE="{{pid_file}}"
+OPTIONS="{{options}}"
+SERVER="{{server_type}}"
+
+{{{ruploy_base}}}
@@ -0,0 +1,46 @@
+require 'mustache'
+
+module Ruploy
+ DEFAULTS = {
+ :name => File.basename(File.expand_path '.'),
+ :address => '127.0.0.1',
+ :port => 3000,
+ :directory => File.expand_path('.'),
+ :environment => 'production',
+ :log_file => '/var/log/rack-$PROCNAME-$PORT.log',
+ :pid_file => '/var/lock/rack-$PROCNAME-$PORT',
+ :user => 'www-data',
+ :dependencies => 'apache2',
+ :server_type => 'thin',
+ :options => '--daemonize'
+ }
+
+ class << self
+ def get_config(args, opts)
+ config = DEFAULTS.merge(opts)
+
+ unless opts[:use_defaults]
+ config.merge! (config.keys - opts.keys).inject({}) { |h, key|
+ h[key] = ask("#{key} ") { |q| q.default = DEFAULTS[key] }
+ h
+ }
+ end
+
+ config[:options] << " #{args.join(' ')}" if args.any?
+ config[:proc_name] = config[:name].gsub(/\W/, '_').squeeze('_').downcase
+
+ return config
+ end
+
+ def generate_init_file(config, independant=false)
+ ruploy_init = File.expand_path('../../data/ruploy-init.mustache', __FILE__)
+ ruploy_base = File.expand_path('../../data/ruploy-base.sh', __FILE__)
+ template = File.read(ruploy_init)
+ config = config.dup
+
+ config[:ruploy_base] = independant ? File.read(ruploy_base) : %Q(. "#{ruploy_base}")
+
+ Mustache.render(template, config)
+ end
+ end
+end
@@ -0,0 +1,3 @@
+module Ruploy
+ VERSION = "0.0.1"
+end
@@ -0,0 +1,21 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "ruploy/version"
+
+Gem::Specification.new do |s|
+ s.name = "ruploy"
+ s.version = Ruploy::VERSION
+ s.authors = ["Simon COURTOIS"]
+ s.email = ["scourtois@cubyx.fr"]
+ s.homepage = ""
+ s.summary = %q{Ruploy generates init.d scripts to manage Rack apps using RVM}
+ s.description = %q{If you want to manage several Rack apps using different versions of Ruby via RVM, Ruploy can help you. It handles gemsets too !}
+
+ 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"]
+
+ s.add_dependency "commander"
+ s.add_dependency "mustache"
+end

0 comments on commit 1d26f40

Please sign in to comment.