foreman_debian 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []