upstart-exporter 1.0.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.8.7-p352
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ branches:
5
+ only:
6
+ - master
data/Gemfile CHANGED
@@ -1,11 +1,9 @@
1
1
  source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in upstart-exporter.gemspec
4
2
  gemspec
5
-
3
+
6
4
  gem 'rake'
7
5
  gem 'yard'
8
- gem 'redcarpet'
6
+ gem 'safe_yaml'
9
7
 
10
8
  gem 'rspec'
11
9
  gem 'fakefs', :require => 'fakefs/safe'
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem for exporting user-scripts as Upstart scripts
2
2
  ====================
3
3
 
4
- [![Build Status](https://secure.travis-ci.org/savonarola/upstart-exporter.png)](http://travis-ci.org/savonarola/upstart-exporter)
4
+ [![Build Status](https://secure.travis-ci.org/funbox/upstart-exporter.png)](http://travis-ci.org/funbox/upstart-exporter)
5
5
 
6
6
  Purpose
7
7
  -------
@@ -24,21 +24,21 @@ Configuration
24
24
  The export process is configured through the only config, /etc/upstart-exporter.yaml, which is a simple YAML file of the following format:
25
25
 
26
26
  ---
27
- run_user: www # The user under which all installed through upstart-exporter background jobs are run
27
+ run_user: www # The user under which all installed through upstart-exporter background jobs are run
28
28
  run_group: www # The group of run_user
29
29
  helper_dir: /var/helper_dir # Auxilary directory for scripts incapsulating background jobs
30
30
  upstart_dir: /var/upstart_dir # Directory where upstart scripts should be placed
31
31
  prefix: 'myupstartjobs-' # Prefix added to app's log folders and upstart scripts
32
32
 
33
33
  The config is not installed by default. If this config is absent, the default values are the following:
34
-
34
+
35
35
  helper_dir: /var/local/upstart_helpers/
36
36
  upstart_dir: /etc/init/
37
37
  run_user: service
38
38
  prefix: 'fb-'
39
39
 
40
- To give a certain user (i.e. deployuser) ability to use this script, one can place the following lines into sudoers file:
41
-
40
+ To give a certain user (i.e. deployuser) ability to use this script, you can place the following lines into sudoers file:
41
+
42
42
  # Commands required for manipulating jobs
43
43
  Cmnd_Alias UPSTART = /sbin/start, /sbin/stop, /sbin/restart
44
44
  Cmnd_Alias UPEXPORT = /usr/local/bin/upstart-export
@@ -50,27 +50,92 @@ To give a certain user (i.e. deployuser) ability to use this script, one can pla
50
50
 
51
51
  ...
52
52
 
53
- # Allow deploy user to manipulate jobs
53
+ # Allow deploy user to manipulate jobs
54
54
  deployuser ALL=(deployuser) NOPASSWD: ALL, (root) NOPASSWD: UPSTART, UPEXPORT
55
-
55
+
56
56
 
57
57
  Usage
58
58
  -----
59
59
 
60
- After upstart-exporter is installed and configured, one may export background jobs from an arbitrary Procfile-like file of the following format:
60
+ Gem is able to process two versions of Procfile's, format of the Procfile is
61
+ defined in the _version_ key. If the key is not present or is not equal to _2_
62
+ gem will try to parse it as Procfile v.1.
63
+
64
+ Procfile v.1
65
+ ------------
66
+
67
+ After upstart-exporter is installed and configured, you may export background jobs from an arbitrary Procfile-like file of the following format:
61
68
 
62
69
  cmdlabel1: cmd1
63
70
  cmdlabel2: cmd2
64
-
71
+
65
72
  i.e. a file ./myprocfile containing:
66
73
 
67
74
  my_tail_cmd: /usr/bin/tail -F /var/log/messages
68
75
  my_another_tail_cmd: /usr/bin/tail -F /var/log/messages
69
76
 
70
- For security purposes, command labels are allowed to contain only letters, digits and underscores.
77
+ For security purposes, command labels are allowed to contain only letters, digits, and underscores.
78
+
79
+ Procfile v.2
80
+ ------------
81
+
82
+ Another format of Procfile scripts is YAML config. A configuration script may
83
+ look like this:
84
+
85
+ version: 2
86
+ start_on_runlevel: "[2345]"
87
+ stop_on_runlevel: "[06]"
88
+ env:
89
+ RAILS_ENV: production
90
+ TEST: true
91
+ working_directory: /srv/projects/mpro/current
92
+ commands:
93
+ my_tail_cmd:
94
+ command: /usr/bin/tail -F /var/log/messages
95
+ respawn:
96
+ count: 5
97
+ interval: 10
98
+ env:
99
+ RAILS_ENV: staging # if needs to be redefined or extended
100
+ working_directory: '/var/...' # if needs to be redefined
101
+ my_another_tail_cmd:
102
+ command: /usr/bin/tail -F /var/log/messages
103
+ respawn: false # by default respawn option is enabled
104
+ my_one_another_tail_cmd:
105
+ command: /usr/bin/tail -F /var/log/messages
106
+ my_multi_tail_cmd:
107
+ command: /usr/bin/tail -F /var/log/messages
108
+ count: 2
109
+
110
+ *start_on_runlevel* and *stop_on_runlevel* are two global options that can't be
111
+ redefined. For more information on these options look into [upstart scripts documentation.]( http://upstart.ubuntu.com/cookbook/#start-on)
112
+
113
+ *working_directory* will generate the next line:
114
+
115
+ cd 'your/working/directory' && your_command
116
+
117
+ *env* params can be redefined and extended in per-command options. Note, that
118
+ you can't remove globally defined *env* variable.
119
+ For given earlier Procfile example the generated command will look like:
120
+
121
+ env RAILS_ENV=staging TEST=true your_command
122
+
123
+ *respawn* option controls restarting of scripts in case of their failure.
124
+ By default this option is enabled. For
125
+ more info look into [documentation](http://upstart.ubuntu.com/cookbook/#respawn)).
126
+
127
+ *respawn_limit* option controls how often job can fail. If the job restarts more
128
+ often than *count* times in *interval*, it won't be restarted anymore. For more
129
+ info look into [documentation](http://upstart.ubuntu.com/cookbook/#respawn-limit).
130
+
131
+ Options *working_directory*, *env*, *respawn* and *respawn_limit* can be
132
+ defined both as global and as per-command options.
133
+
134
+ Exporting
135
+ ---------
136
+
137
+ To export Procfile you should run
71
138
 
72
- To export this file one should run
73
-
74
139
  sudo upstart-export -p ./myprocfile -n myapp
75
140
 
76
141
  where _myapp_ is the application name. This name only affects the names of generated files. For security purposes, app name is also allowed to contain only letters, digits and underscores. Assuming that default options are used, the following files and folders will be generated:
@@ -94,16 +159,17 @@ Prefix 'fb-' (which can be customised through config) is added to avoid collisio
94
159
 
95
160
  sudo stop fb-myapp-my_tail_cmd
96
161
 
97
- It's stdout/stderr will be redirected to /var/log/fb-myapp/my\_tail\_cmd.log.
162
+ It's stdout/stderr will be redirected to /var/log/fb-myapp/my\_tail\_cmd.log.
163
+
164
+ To start/stop all application commands at once, you can run:
98
165
 
99
- To start/stop all application commands at once, one can run:
100
-
101
166
  sudo start fb-myapp
102
167
  ...
103
168
  sudo stop fb-myapp
104
169
 
105
- To remove upstart scripts and helpers for a particular application one can run
170
+ To remove upstart scripts and helpers for a particular application you can run
106
171
 
107
172
  sudo upstart-export -c -n myapp
108
173
 
109
174
  The logs are not cleared in this case. Also, all old application scripts are cleared before each export.
175
+
@@ -3,7 +3,7 @@ end
3
3
 
4
4
  module Upstart::Exporter::Errors
5
5
  def error(msg)
6
- raise Upstart::Exporter::Error, msg
6
+ raise Upstart::Exporter::Error, msg
7
7
  end
8
8
  end
9
9
 
@@ -0,0 +1,107 @@
1
+ class Upstart::Exporter
2
+ class ExpandedExporter
3
+ include ExporterHelpers
4
+ include Errors
5
+
6
+ def self.export(options)
7
+ new(options).export
8
+ end
9
+
10
+ def initialize(options)
11
+ @config = options[:commands]
12
+ @options = options
13
+ @commands = @config['commands']
14
+ @env = @config['env'] || {}
15
+ @dir = @config['working_directory'] || ''
16
+ end
17
+
18
+ def export
19
+ @commands.each do |command, value|
20
+ if count = value['count']
21
+ count.times do |counter|
22
+ export_cmd("#{command}_#{counter}", value)
23
+ end
24
+ else
25
+ export_cmd(command, value)
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def export_cmd(command, value)
33
+ script = value['command']
34
+ script = add_env_command(script, value)
35
+ script = add_dir_command(script, value)
36
+ export_cmd_helper(command, script)
37
+ export_cmd_upstart_conf(command, value)
38
+ end
39
+
40
+ def add_env_command(script, command)
41
+ vars = ''
42
+ env = @env.merge((command['env'] || {}))
43
+ env.each do |var, val|
44
+ vars += "#{var}=#{val} "
45
+ end
46
+ if vars.empty?
47
+ script
48
+ else
49
+ "env #{vars} #{script}"
50
+ end
51
+ end
52
+
53
+ def add_dir_command(script, command)
54
+ dir = command['working_directory'] || @dir
55
+ if dir.empty?
56
+ script
57
+ else
58
+ "cd '#{dir}' && #{script}"
59
+ end
60
+ end
61
+
62
+ def respawn_options(cmd_options)
63
+ if cmd_options.has_key?('respawn')
64
+ cmd_options['respawn']
65
+ elsif @config.has_key?('respawn')
66
+ @config['respawn']
67
+ else
68
+ {}
69
+ end
70
+ end
71
+
72
+ def respawn(cmd_options)
73
+ respawn_options(cmd_options) ? 'respawn' : ''
74
+ end
75
+
76
+ def respawn_limit(cmd_options)
77
+ limits = respawn_options(cmd_options)
78
+ return '' unless limits && limits['count'] && limits['interval']
79
+ "respawn limit #{limits['count'].to_i} #{limits['interval'].to_i}"
80
+ end
81
+
82
+ def start_on
83
+ "starting #{app_name}"
84
+ end
85
+
86
+ def stop_on
87
+ "stopping #{app_name}"
88
+ end
89
+
90
+ def export_cmd_upstart_conf(cmd_name, cmd_options)
91
+ cmd_upstart_conf_content = Templates.command(
92
+ :app_name => app_name,
93
+ :start_on => start_on,
94
+ :stop_on => stop_on,
95
+ :run_user => @options[:run_user],
96
+ :run_group => @options[:run_group],
97
+ :cmd_name => cmd_name,
98
+ :helper_cmd_conf => helper_cmd_conf(cmd_name),
99
+ :respawn => respawn(cmd_options),
100
+ :respawn_limit => respawn_limit(cmd_options)
101
+ )
102
+ File.open(upstart_cmd_conf(cmd_name), 'w') do |f|
103
+ f.write(cmd_upstart_conf_content)
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,26 @@
1
+ class Upstart::Exporter
2
+ module ExporterHelpers
3
+ def export_cmd_helper(cmd_name, cmd)
4
+ helper_script_cont = Templates.helper :cmd => cmd
5
+ File.open(helper_cmd_conf(cmd_name), 'w') do |f|
6
+ f.write(helper_script_cont)
7
+ end
8
+ end
9
+
10
+ def app_name
11
+ @options[:prefix] + @options[:app_name]
12
+ end
13
+
14
+ def app_cmd(cmd_name)
15
+ "#{app_name}-#{cmd_name}"
16
+ end
17
+
18
+ def upstart_cmd_conf(cmd_name)
19
+ File.join(@options[:upstart_dir], "#{app_cmd(cmd_name)}.conf")
20
+ end
21
+
22
+ def helper_cmd_conf(cmd_name)
23
+ File.join(@options[:helper_dir], "#{app_cmd(cmd_name)}.sh")
24
+ end
25
+ end
26
+ end
@@ -27,14 +27,20 @@ module Upstart::Exporter::Options
27
27
  elsif line =~ /^\s*$/
28
28
  # do nothing, empty
29
29
  else
30
- error "procfile lines should have the following format: 'some_label: command'"
30
+ break if commands['version'] && commands['version'].strip == '2'
31
+ error "procfile version 1 lines should have the following format: 'some_label: command'"
31
32
  end
32
33
  end
34
+ if commands['version'] && commands['version'].strip == '2'
35
+ commands = YAML.load(content)
36
+ error('procfile should include "commands" key') unless commands['commands']
37
+ error('command names should include only letters and/or underscores') if commands['commands'].keys.find { |k| k !~ /\A[A-z\d_]*?\z/ }
38
+ end
33
39
  commands
34
40
  end
35
41
 
36
42
  def process_appname(app_name)
37
- error "Application name should contain only letters (and underscore) and be nonempty, so #{app_name.inspect} is not suitable" unless app_name =~ /^\w+$/
43
+ error "Application name should contain only letters (and underscore) and be nonempty, so #{app_name.inspect} is not suitable" unless app_name =~ /^\w+$/
38
44
  app_name
39
45
  end
40
46
 
@@ -7,7 +7,9 @@ module Upstart::Exporter::Options
7
7
  'upstart_dir' => '/etc/init/',
8
8
  'run_user' => 'service',
9
9
  'run_group' => 'service',
10
- 'prefix' => 'fb-'
10
+ 'prefix' => 'fb-',
11
+ 'start_on_runlevel' => '[3]',
12
+ 'stop_on_runlevel' => '[3]'
11
13
  }
12
14
 
13
15
  CONF = '/etc/upstart-exporter.yaml'
@@ -1,16 +1,23 @@
1
1
  module Upstart
2
2
  class Exporter
3
3
  class Templates
4
+ extend Errors
4
5
 
5
6
  def self.helper(binds)
6
7
  interpolate(HELPER_TPL, binds)
7
8
  end
8
9
 
9
10
  def self.app(binds)
11
+ if error_val = binds.find { |v| v =~ /\A[A-z0-9_\- ]*?\z/ }
12
+ error("value #{error_val} is insecure and can't be accepted")
13
+ end
10
14
  interpolate(APP_TPL, binds)
11
15
  end
12
16
 
13
17
  def self.command(binds)
18
+ if error_val = binds.find { |v| v =~ /\A[A-z0-9_\- ]*?\z/ }
19
+ error("value #{error_val} is insecure and can't be accepted")
20
+ end
14
21
  interpolate(COMMAND_TPL, binds)
15
22
  end
16
23
 
@@ -25,6 +32,9 @@ fi
25
32
  HEREDOC
26
33
 
27
34
  APP_TPL = <<-HEREDOC
35
+ start on {{start_on}}
36
+ stop on {{stop_on}}
37
+
28
38
  pre-start script
29
39
 
30
40
  bash << "EOF"
@@ -38,9 +48,10 @@ end script
38
48
  HEREDOC
39
49
 
40
50
  COMMAND_TPL = <<-HEREDOC
41
- start on starting {{app_name}}
42
- stop on stopping {{app_name}}
43
- respawn
51
+ start on {{start_on}}
52
+ stop on {{stop_on}}
53
+ {{respawn}}
54
+ {{respawn_limit}}
44
55
 
45
56
  script
46
57
  touch /var/log/{{app_name}}/{{cmd_name}}.log
@@ -62,4 +73,3 @@ HEREDOC
62
73
  end
63
74
  end
64
75
  end
65
-
@@ -1,5 +1,5 @@
1
1
  module Upstart
2
2
  class Exporter
3
- VERSION = "1.0.1"
3
+ VERSION = "2.0.1"
4
4
  end
5
5
  end
@@ -1,15 +1,19 @@
1
- require "upstart-exporter/version"
2
- require "upstart-exporter/templates"
3
- require "upstart-exporter/errors"
4
- require "upstart-exporter/options/global"
5
- require "upstart-exporter/options/command_line"
1
+ require 'yaml'
2
+ require 'upstart-exporter/version'
3
+ require 'upstart-exporter/errors'
4
+ require 'upstart-exporter/templates'
5
+ require 'upstart-exporter/exporter_helpers'
6
+ require 'upstart-exporter/expanded_exporter'
7
+ require 'upstart-exporter/options/global'
8
+ require 'upstart-exporter/options/command_line'
6
9
 
7
10
  module Upstart
8
11
  class Exporter
9
12
  include Errors
13
+ include ExporterHelpers
10
14
 
11
15
  attr_reader :options
12
-
16
+
13
17
  def initialize(command_line_args)
14
18
  global_options = Options::Global.new
15
19
  command_line_options = Options::CommandLine.new(command_line_args)
@@ -20,8 +24,12 @@ module Upstart
20
24
  def export
21
25
  clear
22
26
  export_app
23
- options[:commands].each do |cmd_name, cmd|
24
- export_command(cmd_name, cmd)
27
+ if options[:commands]['version'] && options[:commands]['version'] == 2
28
+ ExpandedExporter.export(options)
29
+ else
30
+ options[:commands].each do |cmd_name, cmd|
31
+ export_command(cmd_name, cmd)
32
+ end
25
33
  end
26
34
  end
27
35
 
@@ -37,17 +45,29 @@ module Upstart
37
45
 
38
46
  protected
39
47
 
48
+ def start_on_runlevel
49
+ lvl = options[:commands]['start_on_runlevel'] || options[:start_on_runlevel]
50
+ "runlevel #{lvl}"
51
+ end
52
+
53
+ def stop_on_runlevel
54
+ lvl = options[:commands]['stop_on_runlevel'] || options[:stop_on_runlevel]
55
+ "runlevel #{lvl}"
56
+ end
57
+
40
58
  def ensure_dirs
41
59
  ensure_dir(options[:helper_dir])
42
60
  ensure_dir(options[:upstart_dir])
43
61
  end
44
62
 
45
- def app_name
46
- options[:prefix] + options[:app_name]
47
- end
48
-
49
63
  def export_app
50
- app_conf = Templates.app :app_name => app_name, :run_user => options[:run_user], :run_group => options[:run_group]
64
+ app_conf = Templates.app(
65
+ :app_name => app_name,
66
+ :run_user => options[:run_user],
67
+ :run_group => options[:run_group],
68
+ :start_on => start_on_runlevel,
69
+ :stop_on => stop_on_runlevel
70
+ )
51
71
  File.open(upstart_conf, 'w') do |f|
52
72
  f.write(app_conf)
53
73
  end
@@ -62,27 +82,18 @@ module Upstart
62
82
  File.join(options[:upstart_dir], "#{app_name}.conf")
63
83
  end
64
84
 
65
- def app_cmd(cmd_name)
66
- "#{app_name}-#{cmd_name}"
67
- end
68
-
69
- def upstart_cmd_conf(cmd_name)
70
- File.join(options[:upstart_dir], "#{app_cmd(cmd_name)}.conf")
71
- end
72
-
73
- def helper_cmd_conf(cmd_name)
74
- File.join(options[:helper_dir], "#{app_cmd(cmd_name)}.sh")
75
- end
76
-
77
- def export_cmd_helper(cmd_name, cmd)
78
- helper_script_cont = Templates.helper :cmd => cmd
79
- File.open(helper_cmd_conf(cmd_name), 'w') do |f|
80
- f.write(helper_script_cont)
81
- end
82
- end
83
-
84
85
  def export_cmd_upstart_conf(cmd_name)
85
- cmd_upstart_conf_content = Templates.command :app_name => app_name, :run_user => options[:run_user], :run_group => options[:run_group], :cmd_name => cmd_name, :helper_cmd_conf => helper_cmd_conf(cmd_name)
86
+ cmd_upstart_conf_content = Templates.command(
87
+ :app_name => app_name,
88
+ :start_on => "starting #{app_name}",
89
+ :stop_on => "stopping #{app_name}",
90
+ :respawn => 'respawn',
91
+ :respawn_limit => '',
92
+ :run_user => options[:run_user],
93
+ :run_group => options[:run_group],
94
+ :cmd_name => cmd_name,
95
+ :helper_cmd_conf => helper_cmd_conf(cmd_name)
96
+ )
86
97
  File.open(upstart_cmd_conf(cmd_name), 'w') do |f|
87
98
  f.write(cmd_upstart_conf_content)
88
99
  end
@@ -18,7 +18,6 @@ describe Upstart::Exporter::Errors do
18
18
  end
19
19
 
20
20
  lambda{ Foo.new.error("arrgh") }.should raise_exception(Upstart::Exporter::Error)
21
-
22
21
  end
23
22
  end
24
23
  end
@@ -0,0 +1,59 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Upstart::Exporter::ExpandedExporter do
4
+ before do
5
+ @defaults = {}
6
+ Upstart::Exporter::Options::Global::DEFAULTS.each do |key, value|
7
+ @defaults[key.to_sym] = value
8
+ end
9
+
10
+ File.stub(:open)
11
+ end
12
+
13
+ it 'calls template render exact amount of times' do
14
+ Upstart::Exporter::Templates.should_receive(:command).exactly(5).times
15
+ options = {
16
+ :commands => {
17
+ 'commands' => {
18
+ 'ls' => {
19
+ 'command' => 'ls',
20
+ 'count' => 3
21
+ },
22
+ 'ls2' => {
23
+ 'command' => 'ls',
24
+ 'count' => 2
25
+ }
26
+ }
27
+ },
28
+ :app_name => 'appname'
29
+ }.merge(@defaults)
30
+
31
+ described_class.export(options)
32
+ end
33
+
34
+ it 'merges env params in the right order' do
35
+ Upstart::Exporter::Templates.should_receive(:helper) do |options|
36
+ options[:cmd].should include('B=b')
37
+ options[:cmd].should include('T=t')
38
+ end
39
+ options = {
40
+ :commands => {
41
+ 'env' => {
42
+ 'T' => 't',
43
+ 'B' => 'a'
44
+ },
45
+ 'commands' => {
46
+ 'ls' => {
47
+ 'command' => 'ls',
48
+ 'env' => {
49
+ 'B' => 'b'
50
+ }
51
+ }
52
+ }
53
+ },
54
+ :app_name => 'appname'
55
+ }.merge(@defaults)
56
+
57
+ described_class.export(options)
58
+ end
59
+ end
@@ -6,25 +6,32 @@ describe Upstart::Exporter::Options::CommandLine do
6
6
  make_procfile('Procfile', 'ls_cmd: ls')
7
7
  described_class.new(:app_name => 'someappname', :procfile => 'Procfile').should respond_to('[]')
8
8
  end
9
-
9
+
10
10
  it "should parse procfile" do
11
11
  make_procfile('Procfile', 'ls_cmd: ls')
12
12
  options = described_class.new(:app_name => 'someappname', :procfile => 'Procfile')
13
13
  options[:commands].should == {'ls_cmd' => ' ls'}
14
14
  end
15
-
15
+
16
+ it 'should parse procfile v2' do
17
+ make_procfile('Procfile', "version: 2\ncommands:\n ls:\n command: ls -al")
18
+ options = described_class.new(:app_name => 'someappname', :procfile => 'Procfile')
19
+ options[:commands].should have_key('commands')
20
+ options[:commands]['commands'].should have_key('ls')
21
+ end
22
+
16
23
  it "should skip empty and commented lines in a procfile" do
17
24
  make_procfile('Procfile', "ls_cmd1: ls1\n\nls_cmd2: ls2\n # fooo baaar")
18
25
  options = described_class.new(:app_name => 'someappname', :procfile => 'Procfile')
19
26
  options[:commands].should == {'ls_cmd1' => ' ls1', 'ls_cmd2' => ' ls2'}
20
27
  end
21
-
28
+
22
29
  it "should store app_name" do
23
30
  make_procfile('Procfile', "ls_cmd1: ls1\n\nls_cmd2: ls2\n # fooo baaar")
24
31
  options = described_class.new(:app_name => 'someappname', :procfile => 'Procfile')
25
32
  options[:app_name].should == 'someappname'
26
33
  end
27
-
34
+
28
35
  it "should not process procfile if :clear arg is present" do
29
36
  make_procfile('Procfile', "bad procfile")
30
37
  options = described_class.new(:app_name => 'someappname', :procfile => 'Procfile', :clear => true)
@@ -41,7 +48,7 @@ describe Upstart::Exporter::Options::CommandLine do
41
48
  lambda{ described_class.new(:procfile => 'Procfile') }.should raise_exception
42
49
  end
43
50
  end
44
-
51
+
45
52
  context "when bad Procfile is passed" do
46
53
  it "should raise exception" do
47
54
  make_procfile('Procfile', 'ls cmd: ls')
@@ -51,7 +58,10 @@ describe Upstart::Exporter::Options::CommandLine do
51
58
  lambda{ described_class.new(:app_name => 'someappname', :procfile => 'Procfile') }.should raise_exception
52
59
 
53
60
  lambda{ described_class.new(:app_name => 'someappname', :procfile => '::') }.should raise_exception
54
-
61
+
62
+ make_procfile('Procfile', "version: 2\ncommands:\n ls cmd:\n command: ls")
63
+ lambda{ described_class.new(:app_name => 'someappname', :procfile => 'Procfile') }.should raise_exception
64
+
55
65
  lambda{ described_class.new(:app_name => 'someappname') }.should raise_exception
56
66
  end
57
67
  end
@@ -3,7 +3,7 @@ require 'spec/spec_helper'
3
3
  describe Upstart::Exporter::Options::Global do
4
4
  let(:defaults){ Upstart::Exporter::Options::Global::DEFAULTS }
5
5
  let(:conf){ Upstart::Exporter::Options::Global::CONF }
6
-
6
+
7
7
 
8
8
  it "should give access to options like a hash" do
9
9
  capture(:stderr) do
@@ -40,7 +40,7 @@ describe Upstart::Exporter::Options::Global do
40
40
  described_class.new[:run_user].should == 'wwwww'
41
41
  end
42
42
  end
43
-
43
+
44
44
  it "should preserve default values for options not specified in the config" do
45
45
  capture(:stderr) do
46
46
  make_global_config({'run_user' => 'wwwww'}.to_yaml)
@@ -3,8 +3,11 @@ require 'spec/spec_helper'
3
3
  describe Upstart::Exporter::Templates do
4
4
  describe ".app" do
5
5
  it "should generate a valid app config" do
6
-
6
+
7
7
  conf = <<-HEREDOC
8
+ start on 12
9
+ stop on 13
10
+
8
11
  pre-start script
9
12
 
10
13
  bash << "EOF"
@@ -17,13 +20,19 @@ EOF
17
20
  end script
18
21
  HEREDOC
19
22
 
20
- described_class.app(:run_user => 'SOMEUSER', :run_group => 'SOMEGROUP', :app_name => 'SOMEAPP').should == conf
23
+ described_class.app(
24
+ :run_user => 'SOMEUSER',
25
+ :run_group => 'SOMEGROUP',
26
+ :app_name => 'SOMEAPP',
27
+ :start_on => '12',
28
+ :stop_on => '13'
29
+ ).should == conf
21
30
  end
22
31
  end
23
32
 
24
33
  describe ".helper" do
25
34
  it "should generate a valid helper script" do
26
-
35
+
27
36
  conf = <<-HEREDOC
28
37
  #!/bin/bash
29
38
  if [ -f /etc/profile.d/rbenv.sh ]; then
@@ -39,11 +48,12 @@ HEREDOC
39
48
 
40
49
  describe ".helper" do
41
50
  it "should generate a valid upstart script for a single command" do
42
-
51
+
43
52
  conf = <<-HEREDOC
44
53
  start on starting SOMEAPP
45
54
  stop on stopping SOMEAPP
46
55
  respawn
56
+ respawn limit 5 10
47
57
 
48
58
  script
49
59
  touch /var/log/SOMEAPP/SOMECMD.log
@@ -54,7 +64,15 @@ script
54
64
  end script
55
65
  HEREDOC
56
66
 
57
- described_class.command(:run_user => 'SOMEUSER', :run_group => 'SOMEGROUP', :app_name => 'SOMEAPP', :cmd_name => 'SOMECMD', :helper_cmd_conf => 'HELPERPATH').should == conf
67
+ described_class.command(:run_user => 'SOMEUSER',
68
+ :run_group => 'SOMEGROUP',
69
+ :app_name => 'SOMEAPP',
70
+ :cmd_name => 'SOMECMD',
71
+ :respawn => 'respawn',
72
+ :respawn_limit => 'respawn limit 5 10',
73
+ :start_on => 'starting SOMEAPP',
74
+ :stop_on => 'stopping SOMEAPP',
75
+ :helper_cmd_conf => 'HELPERPATH').should == conf
58
76
  end
59
77
  end
60
78
 
@@ -9,7 +9,8 @@ describe Upstart::Exporter do
9
9
  'upstart_dir' => '/u',
10
10
  'run_user' => 'u',
11
11
  'run_group' => 'g',
12
- 'prefix' => 'p-'
12
+ 'prefix' => 'p-',
13
+ 'start_on_runlevel' => '[7]'
13
14
  }.to_yaml)
14
15
  make_procfile('Procfile', 'ls_cmd: ls')
15
16
  exporter = described_class.new({:app_name => 'app', :procfile => 'Procfile'})
@@ -27,13 +28,25 @@ describe Upstart::Exporter do
27
28
  FileTest.file?(f).should be_true
28
29
  end
29
30
  end
30
-
31
+
31
32
  it 'created scripts, folders and sh helpers should have valid content' do
32
33
  exporter.export
33
34
 
34
35
  File.read('/h/p-app-ls_cmd.sh').should == tpl.helper(:cmd => ' ls')
35
- File.read('/u/p-app.conf').should == tpl.app(:run_user => 'u', :run_group => 'g', :app_name => 'p-app')
36
- File.read('/u/p-app-ls_cmd.conf').should == tpl.command(:run_user => 'u', :run_group => 'g', :app_name => 'p-app', :cmd_name => 'ls_cmd', :helper_cmd_conf => '/h/p-app-ls_cmd.sh')
36
+ File.read('/u/p-app.conf').should == tpl.app(:run_user => 'u',
37
+ :run_group => 'g',
38
+ :app_name => 'p-app',
39
+ :start_on => 'runlevel [7]',
40
+ :stop_on => 'runlevel [3]')
41
+ File.read('/u/p-app-ls_cmd.conf').should == tpl.command(:run_user => 'u',
42
+ :run_group => 'g',
43
+ :app_name => 'p-app',
44
+ :cmd_name => 'ls_cmd',
45
+ :start_on => 'starting p-app',
46
+ :stop_on => 'stopping p-app',
47
+ :respawn => 'respawn',
48
+ :respawn_limit => '',
49
+ :helper_cmd_conf => '/h/p-app-ls_cmd.sh')
37
50
  end
38
51
  end
39
52
 
@@ -44,10 +57,10 @@ describe Upstart::Exporter do
44
57
  Dir['/h/*'].should be_empty
45
58
  Dir['/u/*'].should be_empty
46
59
  end
47
-
60
+
48
61
  it 'should keep files of other apps' do
49
62
  exporter.export
50
-
63
+
51
64
  make_procfile('Procfile1', 'ls_cmd: ls')
52
65
  other_exporter = described_class.new({:app_name => 'other_app', :procfile => 'Procfile1'})
53
66
  other_exporter.export
@@ -5,15 +5,14 @@ require "upstart-exporter/version"
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "upstart-exporter"
7
7
  s.version = Upstart::Exporter::VERSION
8
- s.authors = ["Ilya Averyanov"]
9
- s.email = ["ilya@averyanov.org"]
8
+ s.authors = ["Ilya Averyanov", "Egor Blinov"]
9
+ s.email = ["ilya@averyanov.org", "monshq@gmail.com"]
10
10
  s.homepage = ""
11
- s.summary = %q{Gem for converting Procfile-like files to upstart scripts}
12
- s.description = %q{Gem for converting Procfile-like files to upstart scripts}
11
+ s.summary = %q{Gem for converting extended Procfile-like files to upstart scripts}
12
+ s.description = %q{Gem for converting extended Procfile-like files to upstart scripts}
13
13
 
14
14
  s.files = `git ls-files`.split("\n")
15
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
17
  s.require_paths = ["lib"]
18
-
19
18
  end
metadata CHANGED
@@ -1,26 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upstart-exporter
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
- - 1
7
+ - 2
8
8
  - 0
9
9
  - 1
10
- version: 1.0.1
10
+ version: 2.0.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ilya Averyanov
14
+ - Egor Blinov
14
15
  autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2012-02-22 00:00:00 Z
19
+ date: 2014-01-21 00:00:00 +04:00
20
+ default_executable:
19
21
  dependencies: []
20
22
 
21
- description: Gem for converting Procfile-like files to upstart scripts
23
+ description: Gem for converting extended Procfile-like files to upstart scripts
22
24
  email:
23
25
  - ilya@averyanov.org
26
+ - monshq@gmail.com
24
27
  executables:
25
28
  - upstart-export
26
29
  extensions: []
@@ -31,6 +34,8 @@ files:
31
34
  - .gitignore
32
35
  - .rbenv-version
33
36
  - .rspec
37
+ - .ruby-version
38
+ - .travis.yml
34
39
  - .yardoc/checksums
35
40
  - .yardoc/objects/root.dat
36
41
  - .yardoc/proxy_types
@@ -63,11 +68,14 @@ files:
63
68
  - doc/top-level-namespace.html
64
69
  - lib/upstart-exporter.rb
65
70
  - lib/upstart-exporter/errors.rb
71
+ - lib/upstart-exporter/expanded_exporter.rb
72
+ - lib/upstart-exporter/exporter_helpers.rb
66
73
  - lib/upstart-exporter/options/command_line.rb
67
74
  - lib/upstart-exporter/options/global.rb
68
75
  - lib/upstart-exporter/templates.rb
69
76
  - lib/upstart-exporter/version.rb
70
77
  - spec/lib/upstart-exporter/errors_spec.rb
78
+ - spec/lib/upstart-exporter/expanded_exporter_spec.rb
71
79
  - spec/lib/upstart-exporter/options/command_line_spec.rb
72
80
  - spec/lib/upstart-exporter/options/global_spec.rb
73
81
  - spec/lib/upstart-exporter/templates_spec.rb
@@ -77,6 +85,7 @@ files:
77
85
  - spec/support/procfile.rb
78
86
  - spec/support/streams.rb
79
87
  - upstart-exporter.gemspec
88
+ has_rdoc: true
80
89
  homepage: ""
81
90
  licenses: []
82
91
 
@@ -106,12 +115,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
115
  requirements: []
107
116
 
108
117
  rubyforge_project:
109
- rubygems_version: 1.8.10
118
+ rubygems_version: 1.6.2
110
119
  signing_key:
111
120
  specification_version: 3
112
- summary: Gem for converting Procfile-like files to upstart scripts
121
+ summary: Gem for converting extended Procfile-like files to upstart scripts
113
122
  test_files:
114
123
  - spec/lib/upstart-exporter/errors_spec.rb
124
+ - spec/lib/upstart-exporter/expanded_exporter_spec.rb
115
125
  - spec/lib/upstart-exporter/options/command_line_spec.rb
116
126
  - spec/lib/upstart-exporter/options/global_spec.rb
117
127
  - spec/lib/upstart-exporter/templates_spec.rb
@@ -120,4 +130,3 @@ test_files:
120
130
  - spec/support/global_config.rb
121
131
  - spec/support/procfile.rb
122
132
  - spec/support/streams.rb
123
- has_rdoc: