foreman_debian 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 76b0b3acb35867ef39245b8394af15290e1a1e93
4
+ data.tar.gz: 48d391bb79c4d5ade86fbb8d30f3db1219387b98
5
+ SHA512:
6
+ metadata.gz: 614bdf1172273fdd06922df80f32d23fd4b913d5357295689f576984ae029c97578036097f531bff2336bedd268e42673046930f6e547d4b1edb5339116cbfcc
7
+ data.tar.gz: 9ebe98efc2153d891704c1b3353c9a5b77e922f3c3025a37b22f49e9b44a80db3b0c9174f18d40f59dc3b30feba01eaae75b53983a995635ea61967a91b2e021
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
4
+ require 'foreman_debian'
5
+
6
+ ForemanDebian::CommandManager.run
@@ -0,0 +1,59 @@
1
+ module ForemanDebian
2
+ class Command::Install < Command
3
+
4
+ option %w(-f --procfile), '<path>', 'alternative Procfile',
5
+ :attribute_name => :procfile_path_relative
6
+
7
+ option %w(-c --concurrency), '<encoded_hash>', 'concurrency (job1=0,job2=1)',
8
+ :attribute_name => :concurrency_encoded,
9
+ :default => 'all=1'
10
+
11
+ option %w(-d --root), '<path>', 'working dir',
12
+ :attribute_name => :working_dir,
13
+ :default => Dir.getwd
14
+
15
+ def execute
16
+ jobs = {}
17
+ procfile.entries do |name, command|
18
+ jobs[name] = expand_procfile_command(command)
19
+ end
20
+ concurrency = decode_concurrency(concurrency_encoded)
21
+ get_engine.install(jobs, concurrency)
22
+ end
23
+
24
+ def expand_procfile_command(command)
25
+ args = Shellwords.split(command)
26
+ args[0] = Pathname.new(args[0]).expand_path(dir_root)
27
+ Shellwords.join(args)
28
+ end
29
+
30
+ # @return [Pathname]
31
+ def procfile_path
32
+ path_relative = procfile_path_relative || "#{working_dir}/Procfile"
33
+ Pathname.new(path_relative).expand_path(Dir.getwd)
34
+ end
35
+
36
+ # @return [Foreman::Procfile]
37
+ def procfile
38
+ raise "Procfile `#{procfile_path.to_s}` does not exist" unless procfile_path.file?
39
+ Foreman::Procfile.new(procfile_path)
40
+ end
41
+
42
+ # @return [Pathname]
43
+ def dir_root
44
+ Pathname.new(working_dir)
45
+ end
46
+
47
+ def decode_concurrency(concurrency_encoded)
48
+ concurrency_hash = {}
49
+ concurrency_encoded.split(',').each do |entry|
50
+ parts = entry.split('=')
51
+ raise 'Invalid concurrency option' unless parts.size == 2
52
+ name, concurrency = parts
53
+ concurrency_hash[name] = concurrency.to_i
54
+ end
55
+ concurrency_hash
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,8 @@
1
+ module ForemanDebian
2
+ class Command::Start < Command
3
+
4
+ def execute
5
+ get_engine.start
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module ForemanDebian
2
+ class Command::Stop < Command
3
+
4
+ def execute
5
+ get_engine.stop
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module ForemanDebian
2
+ class Command::Uninstall < Command
3
+
4
+ def execute
5
+ get_engine.uninstall
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ require 'foreman/procfile'
2
+
3
+ module ForemanDebian
4
+ class Command < Clamp::Command
5
+
6
+ option %w(-a --app), '<name>', 'application name',
7
+ :attribute_name => :app_name,
8
+ :default => 'app'
9
+ option %w(-u --user), '<user>', 'Specify the user the application should be run as',
10
+ :attribute_name => :app_user,
11
+ :default => 'root'
12
+
13
+ # @return [ForemanDebian::Engine]
14
+ def get_engine
15
+ ForemanDebian::Engine.new(app_name, app_user)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ module ForemanDebian
2
+ class CommandManager < Clamp::Command
3
+
4
+ subcommand 'install', 'Install', Command::Install
5
+ subcommand 'uninstall', 'Uninstall', Command::Uninstall
6
+ subcommand 'start', 'Start', Command::Start
7
+ subcommand 'stop', 'Stop', Command::Stop
8
+ end
9
+ end
@@ -0,0 +1,43 @@
1
+ module ForemanDebian
2
+ class Engine
3
+
4
+ def initialize(app, user)
5
+ @app = app
6
+ @user = user
7
+ @initd_engine = Initd::Engine.new(@app, @user)
8
+ @monit_engine = Monit::Engine.new(@app, @user)
9
+ end
10
+
11
+ def install(jobs, concurrency)
12
+ jobs.each do |name, command|
13
+ if job_concurrency(concurrency, name) > 0
14
+ script = @initd_engine.create_script(name, command)
15
+ @initd_engine.install(script)
16
+ @monit_engine.install(name, script)
17
+ end
18
+ end
19
+ @initd_engine.cleanup
20
+ @monit_engine.cleanup
21
+ end
22
+
23
+ def uninstall
24
+ install({}, {})
25
+ end
26
+
27
+ def start
28
+ @initd_engine.start
29
+ end
30
+
31
+ def stop
32
+ @initd_engine.stop
33
+ end
34
+
35
+ def job_concurrency(concurrency, name)
36
+ c = (concurrency['all'] || 0).to_i
37
+ if concurrency.has_key?(name)
38
+ c = concurrency[name].to_i
39
+ end
40
+ c
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,49 @@
1
+ module ForemanDebian
2
+ module EngineHelper
3
+
4
+ def setup
5
+ @exported = []
6
+ @output = ForemanDebian::logger
7
+ end
8
+
9
+ def pidfile(name)
10
+ name = "#{@app}-#{name}"
11
+ Pathname.new('/var/run').join(name).join(name + '.pid')
12
+ end
13
+
14
+ def cleanup
15
+ each_file do |path|
16
+ next if @exported.include? path
17
+ remove_file path
18
+ end
19
+ end
20
+
21
+ def export_file(path)
22
+ @exported.push(path)
23
+ @output.info " create #{path.to_s} "
24
+ end
25
+
26
+ def remove_file(path)
27
+ File.unlink path
28
+ @output.info " remove #{path.to_s}"
29
+ end
30
+
31
+ def each_file(&block)
32
+ Dir.glob @export_path.join("#{@app}-*") do |path|
33
+ path = Pathname.new(path)
34
+ next unless path.read.match(/# Autogenerated by foreman/)
35
+ block.call(path)
36
+ end
37
+ end
38
+
39
+ def exec_command(command)
40
+ Open3.popen3(command) do |i, o, e, w|
41
+ i.close
42
+ out, err, wait = o.read, e.read, w
43
+ s = wait ? wait.value : $?
44
+ s.success? or raise "Command `#{command}` failed: #{err}"
45
+ out
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,63 @@
1
+ module ForemanDebian
2
+ module Initd
3
+ class Engine
4
+
5
+ include ForemanDebian::EngineHelper
6
+
7
+ def initialize(app, user, export_path = nil)
8
+ @app = app
9
+ @user = user
10
+ @export_path = Pathname.new(export_path || '/etc/init.d')
11
+ @system_export_path = Pathname.new('/etc/init.d')
12
+ setup
13
+ end
14
+
15
+ def create_script(name, command)
16
+ pidfile = pidfile(name)
17
+ args = Shellwords.split(command)
18
+ script = args.shift
19
+ name = "#{@app}-#{name}"
20
+ script_path = @export_path.join(name)
21
+ Script.new(script_path, name, name, @user, script, args, pidfile)
22
+ end
23
+
24
+ def install(script)
25
+ FileUtils.mkdir_p(script.path.dirname)
26
+ File.open(script.path, 'w') do |file|
27
+ file.puts(script.render)
28
+ file.chmod(0755)
29
+ export_file(script.path)
30
+ end
31
+ end
32
+
33
+ def start
34
+ each_file do |path|
35
+ start_file(path)
36
+ end
37
+ end
38
+
39
+ def stop
40
+ each_file do |path|
41
+ stop_file(path)
42
+ end
43
+ end
44
+
45
+ def start_file(path)
46
+ exec_command("#{path.to_s} start")
47
+ @output.info " start #{path.to_s}"
48
+ exec_command("update-rc.d #{path.basename} defaults") if path.dirname.eql? @system_export_path
49
+ end
50
+
51
+ def stop_file(path)
52
+ exec_command("#{path.to_s} stop")
53
+ @output.info " stop #{path.to_s}"
54
+ exec_command("update-rc.d #{path.basename} remove") if path.dirname.eql? @system_export_path
55
+ end
56
+
57
+ def remove_file(path)
58
+ stop_file(path)
59
+ super(path)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,22 @@
1
+ module ForemanDebian
2
+ module Initd
3
+ class Script < Template::Storage
4
+
5
+ attr_reader :path, :name, :description, :user, :script, :arguments, :pidfile
6
+
7
+ def initialize(path, name, description, user, script, arguments, pidfile)
8
+ @path = path
9
+ @name = name
10
+ @description = description
11
+ @user = user
12
+ @script = script
13
+ @arguments = arguments
14
+ @pidfile = pidfile
15
+ end
16
+
17
+ def render
18
+ super('initd_script')
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ module ForemanDebian
2
+ module Monit
3
+ class Engine
4
+
5
+ include ForemanDebian::EngineHelper
6
+
7
+ def initialize(app, user, export_path = nil)
8
+ @app = app
9
+ @user = user
10
+ @export_path = Pathname.new(export_path || '/etc/monit/conf.d')
11
+ setup
12
+ end
13
+
14
+ def install(name, script)
15
+ name = "#{@app}-#{name}"
16
+
17
+ FileUtils.mkdir_p(@export_path)
18
+ template = Template.new('monit_config')
19
+ output = template.render({
20
+ :app => @app,
21
+ :name => name,
22
+ :script_pidfile => script.pidfile,
23
+ :script_path => script.path,
24
+ })
25
+ config_path = @export_path.join(name)
26
+ File.open(config_path, 'w') do |file|
27
+ file.puts(output)
28
+ export_file(config_path)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ module ForemanDebian
2
+ class Template
3
+ class Storage < OpenStruct
4
+
5
+ def render(template_name)
6
+ templates_dir = Pathname.new(__FILE__).dirname.dirname.dirname.join('templates')
7
+ template = templates_dir.join("#{template_name}.erb")
8
+ ERB.new(template.read).result(binding)
9
+ end
10
+ end
11
+
12
+ def initialize(template_name)
13
+ @template_name = template_name
14
+ end
15
+
16
+ def render(hash)
17
+ Storage.new(hash).render(@template_name)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,32 @@
1
+ module ForemanDebian
2
+ require 'clamp'
3
+ require 'io/console'
4
+ require 'json'
5
+ require 'pathname'
6
+ require 'shellwords'
7
+ require 'erb'
8
+ require 'ostruct'
9
+ require 'fileutils'
10
+ require 'logger'
11
+ require 'open3'
12
+ require 'foreman_debian/template'
13
+ require 'foreman_debian/engine'
14
+ require 'foreman_debian/engine_helper'
15
+ require 'foreman_debian/initd/engine'
16
+ require 'foreman_debian/initd/script'
17
+ require 'foreman_debian/monit/engine'
18
+ require 'foreman_debian/command'
19
+ require 'foreman_debian/command/install'
20
+ require 'foreman_debian/command/uninstall'
21
+ require 'foreman_debian/command/start'
22
+ require 'foreman_debian/command/stop'
23
+ require 'foreman_debian/command_manager'
24
+
25
+ def self.logger
26
+ @logger ||= Logger.new(STDOUT)
27
+ end
28
+
29
+ def self.logger=(logger)
30
+ @logger = logger
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: foreman_debian
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - cargomedia
8
+ - tomaszdurka
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-06-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: clamp
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0.5'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0.5'
28
+ - !ruby/object:Gem::Dependency
29
+ name: foreman
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 0.63.0
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 0.63.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '2.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '2.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: fakefs
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 0.4.3
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 0.4.3
84
+ description: Wrapper around foreman and Procfile concept. It implements basic exporting,
85
+ installing and uninstalling of initd scripts and monit configs for debian.
86
+ email: hello@cargomedia.ch
87
+ executables:
88
+ - foreman-debian
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - bin/foreman-debian
93
+ - lib/foreman_debian.rb
94
+ - lib/foreman_debian/command.rb
95
+ - lib/foreman_debian/command/install.rb
96
+ - lib/foreman_debian/command/start.rb
97
+ - lib/foreman_debian/command/stop.rb
98
+ - lib/foreman_debian/command/uninstall.rb
99
+ - lib/foreman_debian/command_manager.rb
100
+ - lib/foreman_debian/engine.rb
101
+ - lib/foreman_debian/engine_helper.rb
102
+ - lib/foreman_debian/initd/engine.rb
103
+ - lib/foreman_debian/initd/script.rb
104
+ - lib/foreman_debian/monit/engine.rb
105
+ - lib/foreman_debian/template.rb
106
+ homepage: https://github.com/cargomedia/foreman-debian
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.2.2
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Foreman wrapper for debian
130
+ test_files: []