doable 0.0.4 → 0.0.5
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 +4 -4
- data/README.md +59 -3
- data/lib/doable/helpers/linux.rb +3 -3
- data/lib/doable/helpers/password.rb +34 -6
- data/lib/doable/job.rb +7 -4
- data/lib/doable/step.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ae66f67c0262597b37425580b07c0bad85c71621
|
|
4
|
+
data.tar.gz: 45ad1f5d2df72887db40ec4c441591b5ff02fe02
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 36b6cff4e14a55d0e0f35a50aef0a7935c36c973ae5e5637270191b75254db61839706718543a356c9aa15eb529b8bbf33af061bd110e67ff1627014e199b977
|
|
7
|
+
data.tar.gz: a56729ec3909eb736ce770aae53dd97582bf8ddfb4418bcbb3790aab8e4eddc77f215f9f04c2c35323f6cec05fbc4bdac5bed9c9076b2df3f02a1063b98fff58
|
data/README.md
CHANGED
|
@@ -20,7 +20,7 @@ These goals are largely achieved through a small set of core features, with near
|
|
|
20
20
|
Building
|
|
21
21
|
-----
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
While it is recommended to simply install via a normal rubygems search via ` gem install doable` (or adding `gem "doable"` to your Gemfile), you can build and install the gem yourself. This can be done like so:
|
|
24
24
|
|
|
25
25
|
#!bash
|
|
26
26
|
# need Mercurial to clone the repo... or download it from https://bitbucket.org/jgnagy/doable/get/tip.zip
|
|
@@ -74,8 +74,64 @@ After this job runs, you should see output that looks something like:
|
|
|
74
74
|
[2015/01/29 00:10:36] Here's a password for you...
|
|
75
75
|
Password: ZwyIVH8LjHGYYzDX
|
|
76
76
|
[2015/01/29 00:10:36] All Job steps completed successfully!
|
|
77
|
+
|
|
78
|
+
Let's try something more realistic. Say the goal is to:
|
|
79
|
+
|
|
80
|
+
* check to make sure we have enough space to do things
|
|
81
|
+
* add a user (unless they already exist)
|
|
82
|
+
* unpack some software
|
|
83
|
+
* run it as our new user
|
|
84
|
+
|
|
85
|
+
Here is an example job:
|
|
86
|
+
|
|
87
|
+
#!ruby
|
|
88
|
+
require 'doable/helpers/linux'
|
|
89
|
+
|
|
90
|
+
class InstallCoolSoftware < Doable::Job
|
|
91
|
+
include Doable::Helpers::Linux
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
job3 = InstallCoolSoftware.plan do |j|
|
|
95
|
+
# make sure we have 500MB of space
|
|
96
|
+
j.before {
|
|
97
|
+
@app_dir = "/opt/coolsoft/server"
|
|
98
|
+
check_disk_space @app_dir, (500 * 1024 * 1024)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
j.step {
|
|
102
|
+
@user = "cooluser"
|
|
103
|
+
find_or_create_user @user, File.dirname(@app_dir)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
j.step {
|
|
107
|
+
find_or_create_directory @app_dir
|
|
108
|
+
|
|
109
|
+
FileUtils.cd(@app_dir) do
|
|
110
|
+
tee "tar -xf /opt/media/files/coolsoft-server-1.2.3.tgz --strip=1"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
chown @user, @user, @app_dir, :recursive => true
|
|
114
|
+
}.rollback {
|
|
115
|
+
remove(@app_dir)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
j.step {
|
|
119
|
+
run_as_user @user, File.join(@app_dir, "/bin", "start.sh")
|
|
120
|
+
}
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
job3.run
|
|
124
|
+
|
|
125
|
+
Hopefully this demonstrates how to get access to additional helper methods. Also, you may have noticed the `rollback` method added to the step for uncompressing the tarball. If things go wrong, rollbacks can be run to revert changes. To do so, just do this:
|
|
126
|
+
|
|
127
|
+
job3.rollback!
|
|
128
|
+
|
|
129
|
+
The `Job` instance also has many other methods available for accessing its internals.
|
|
130
|
+
|
|
131
|
+
RubyDoc
|
|
132
|
+
-------
|
|
77
133
|
|
|
78
|
-
|
|
134
|
+
The latest, published documentation can be seen on [RubyDoc](http://www.rubydoc.info/gems/doable/)
|
|
79
135
|
|
|
80
136
|
License
|
|
81
137
|
-------
|
|
@@ -85,4 +141,4 @@ Doable is distributed under the MIT License.
|
|
|
85
141
|
Contributing
|
|
86
142
|
------------
|
|
87
143
|
|
|
88
|
-
I welcome pull-requests. I may or may not use your code, but I encourage the growth of others too. If this project inspires you to contribute, feel free to fork my code and submit a pull request. In most cases, I'll probably recommend you package additions in an extension gem rather than including new files, etc, directly into the core codebase.
|
|
144
|
+
I welcome pull-requests. I may or may not use your code, but I encourage the growth of others too. If this project inspires you to contribute, feel free to fork my code and submit a pull request. In most cases, I'll probably recommend you package additions in an extension gem rather than including new files, etc, directly into the core codebase.
|
data/lib/doable/helpers/linux.rb
CHANGED
|
@@ -219,12 +219,12 @@ module Doable
|
|
|
219
219
|
end
|
|
220
220
|
|
|
221
221
|
# Finds the mount point for a directory, then checks it for a minimum number of kilobytes
|
|
222
|
-
# @param
|
|
222
|
+
# @param directory [String] Directory from which check starts
|
|
223
223
|
# @param min_space [Fixnum] Minumum amount of space required on mount-point discovered from install_dir
|
|
224
|
-
def check_disk_space(
|
|
224
|
+
def check_disk_space(directory, min_space)
|
|
225
225
|
all_filesystems = `df -PB 1024`.chomp.split("\n").collect {|fs| fs.split if fs.match(/^\/dev/) }.compact
|
|
226
226
|
best_fit = nil
|
|
227
|
-
current_test =
|
|
227
|
+
current_test = directory
|
|
228
228
|
until best_fit
|
|
229
229
|
matching_fs = all_filesystems.collect {|fs| fs if File.expand_path(fs[5]) == File.expand_path(current_test) }.compact
|
|
230
230
|
if matching_fs.size == 1
|
|
@@ -11,18 +11,46 @@ module Doable
|
|
|
11
11
|
(1..length).collect{|a| options[:characters][rand(options[:characters].size)] }.join
|
|
12
12
|
end # generate_password()
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
# Generates a digest hash of a string
|
|
15
|
+
# @param password [String] string to digest
|
|
16
|
+
# @param options [Hash] Options hash for digest details
|
|
17
|
+
# @return [String]
|
|
18
|
+
def password_hash(password, options = { algorithm: :sha1, salt: true } )
|
|
19
|
+
options[:algorithm] ||= :sha1
|
|
20
|
+
options[:salt] = true unless options.has_key?(:salt)
|
|
21
|
+
|
|
22
|
+
salt = if options[:salt]
|
|
23
|
+
if options[:salt].kind_of?(String)
|
|
24
|
+
if options[:salt].downcase.match(/^[0-9a-f]+$/)
|
|
25
|
+
options[:salt].downcase
|
|
26
|
+
else
|
|
27
|
+
# hex encode the non-hex salt... good way to keep input sanitized
|
|
28
|
+
options[:salt].downcase.unpack('H*').join
|
|
29
|
+
end
|
|
18
30
|
else
|
|
19
31
|
generate_password(16, characters: [*(0..9), *('a'..'f')])
|
|
20
32
|
end
|
|
21
33
|
else
|
|
22
34
|
''
|
|
23
35
|
end
|
|
24
|
-
|
|
25
|
-
|
|
36
|
+
|
|
37
|
+
case options[:algorithm].to_sym
|
|
38
|
+
when :sha1
|
|
39
|
+
Base64.strict_encode64(Digest::SHA1.digest(password + salt) + salt)
|
|
40
|
+
when :sha256, :sha2
|
|
41
|
+
Base64.strict_encode64(Digest::SHA256.digest(password + salt) + salt)
|
|
42
|
+
when :sha384
|
|
43
|
+
Base64.strict_encode64(Digest::SHA384.digest(password + salt) + salt)
|
|
44
|
+
when :sha512
|
|
45
|
+
Base64.strict_encode64(Digest::SHA512.digest(password + salt) + salt)
|
|
46
|
+
when :md5
|
|
47
|
+
Base64.strict_encode64(Digest::MD5.digest(password + salt) + salt)
|
|
48
|
+
when :ripe160, :ripemd, :rmd160
|
|
49
|
+
Base64.strict_encode64(Digest::RMD160.digest(password + salt) + salt)
|
|
50
|
+
else
|
|
51
|
+
raise InvalidInput, "Invalid Hashing Algorithm: #{options[:algorithm].to_sym}"
|
|
52
|
+
end
|
|
53
|
+
end # password_hash()
|
|
26
54
|
end
|
|
27
55
|
end
|
|
28
56
|
end
|
data/lib/doable/job.rb
CHANGED
|
@@ -37,6 +37,7 @@ module Doable
|
|
|
37
37
|
def on(hook, options = {}, &block)
|
|
38
38
|
@hooks[hook] ||= []
|
|
39
39
|
@hooks[hook] << Step.new(self, options, &block)
|
|
40
|
+
@hooks[hook].last # return the last step (the one we just defined)
|
|
40
41
|
end # on()
|
|
41
42
|
|
|
42
43
|
# Adds a step to the queue
|
|
@@ -45,6 +46,7 @@ module Doable
|
|
|
45
46
|
# @return [Step]
|
|
46
47
|
def step(options = {}, &block)
|
|
47
48
|
@steps << Step.new(self, options, &block)
|
|
49
|
+
@steps.last # return the last step (the one we just defined)
|
|
48
50
|
end # step()
|
|
49
51
|
|
|
50
52
|
# Registers an action to be performed before normal step execution
|
|
@@ -67,7 +69,7 @@ module Doable
|
|
|
67
69
|
# WARNING! Exception handlers are __not__ used with these steps, as they never actually raise exceptions
|
|
68
70
|
# @param options [Hash]
|
|
69
71
|
# @param block [Proc]
|
|
70
|
-
# @return [
|
|
72
|
+
# @return [Step] the step just create by this method
|
|
71
73
|
def attempt(options = {}, &block)
|
|
72
74
|
@steps << Step.new(self, options) do
|
|
73
75
|
begin
|
|
@@ -78,7 +80,7 @@ module Doable
|
|
|
78
80
|
log "Ignoring Exception in attempted step: #{colorize("#{e.class}: (#{e.message})", :red)}"
|
|
79
81
|
end
|
|
80
82
|
end
|
|
81
|
-
return
|
|
83
|
+
@steps.last # return the last step (the one we just defined)
|
|
82
84
|
end # attempt()
|
|
83
85
|
|
|
84
86
|
# Allow running steps in the background
|
|
@@ -89,6 +91,7 @@ module Doable
|
|
|
89
91
|
@steps << Step.new(self, options) do
|
|
90
92
|
@threads << Thread.new { block.call }
|
|
91
93
|
end
|
|
94
|
+
@steps.last # return the last step (the one we just defined)
|
|
92
95
|
end # background()
|
|
93
96
|
|
|
94
97
|
# Check if background steps are running
|
|
@@ -100,9 +103,9 @@ module Doable
|
|
|
100
103
|
# Trigger a rollback of the entire Job, based on calls to #rollback!() on each eligible Step
|
|
101
104
|
def rollback!
|
|
102
105
|
log "Rolling Back...", :warn
|
|
103
|
-
@hooks[:after].reverse.each {|s| s.rollback! if s.rollbackable? }
|
|
106
|
+
@hooks[:after].reverse.each {|s| s.rollback! if s.rollbackable? } if @hooks.has_key?(:after)
|
|
104
107
|
@steps.reverse.each {|s| s.rollback! if s.rollbackable? }
|
|
105
|
-
@hooks[:before].reverse.each {|s| s.rollback! if s.rollbackable? }
|
|
108
|
+
@hooks[:before].reverse.each {|s| s.rollback! if s.rollbackable? } if @hooks.has_key?(:before)
|
|
106
109
|
log "Rollback complete!", :warn
|
|
107
110
|
raise RolledBack
|
|
108
111
|
end # rollback!()
|
data/lib/doable/step.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: doable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jonathan Gnagy
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2015-
|
|
12
|
+
date: 2015-03-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies: []
|
|
14
14
|
description: A framework for automating tasks with ease
|
|
15
15
|
email: jonathan.gnagy@gmail.com
|