automateit 0.71017 → 0.71021
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGES.txt +9 -1
- data/TODO.txt +1 -5
- data/lib/automateit/address_manager.rb +3 -0
- data/lib/automateit/address_manager/base.rb +35 -12
- data/lib/automateit/address_manager/bsd.rb +28 -0
- data/lib/automateit/address_manager/freebsd.rb +56 -0
- data/lib/automateit/address_manager/openbsd.rb +63 -0
- data/lib/automateit/address_manager/sunos.rb +0 -13
- data/lib/automateit/platform_manager.rb +1 -0
- data/lib/automateit/platform_manager/openbsd.rb +28 -0
- data/lib/automateit/root.rb +1 -1
- data/lib/ext/metaclass.rb +1 -1
- data/spec/integration/address_manager_spec.rb +42 -37
- data/spec/integration/package_manager_spec.rb +1 -1
- metadata +6 -2
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGES.txt
CHANGED
@@ -1,7 +1,15 @@
|
|
1
|
+
0.71021:
|
2
|
+
Date: Sun, 21 Oct 2007 04:58:01 -0700
|
3
|
+
Desc:
|
4
|
+
- Added PlatformManager::OpenBSD.
|
5
|
+
- Added AddressManager::OpenBSD.
|
6
|
+
- Added AddressManager::FreeBSD.
|
7
|
+
- Added AddressManager::BSD which assists SunOS, FreeBSD and OpenBSD.
|
8
|
+
|
1
9
|
0.71017:
|
2
10
|
Date: Wed, 17 Oct 2007 00:24:24 -0700
|
3
11
|
Desc:
|
4
|
-
- (%) Fixed, created workaround so AutomateIt can run using the newly-released ActiveSupport 1.4.4 (part of Rails 2.0 PR1), because
|
12
|
+
- (%) Fixed, created workaround so AutomateIt can run using the newly-released ActiveSupport 1.4.4 (part of Rails 2.0 PR1), because this new library breaks backwards compatibility by depending on new #extract_options method.
|
5
13
|
|
6
14
|
0.71012:
|
7
15
|
Date: Fri, 12 Oct 2007 03:54:30 -0700
|
data/TODO.txt
CHANGED
@@ -2,12 +2,8 @@ KEY: Important? Urgent? Easy? 1=yes, 0=no
|
|
2
2
|
|
3
3
|
#===[ App ]=============================================================
|
4
4
|
|
5
|
-
f=finished
|
6
|
-
d=disabled
|
7
|
-
|
8
5
|
Solaris 10
|
9
|
-
|
10
|
-
d Create AccountManager::SunOS and prevent ::Linux from being used because it has the same commands but with different args
|
6
|
+
- Create AccountManager::SunOS
|
11
7
|
- Create ServiceManager::SMF
|
12
8
|
- Create PackageManager::Blastwave
|
13
9
|
- Create PackageManager::SunPkg
|
@@ -81,5 +81,8 @@ end
|
|
81
81
|
# Drivers
|
82
82
|
require 'automateit/address_manager/base'
|
83
83
|
require 'automateit/address_manager/portable'
|
84
|
+
require 'automateit/address_manager/bsd'
|
84
85
|
require 'automateit/address_manager/linux'
|
85
86
|
require 'automateit/address_manager/sunos'
|
87
|
+
require 'automateit/address_manager/openbsd'
|
88
|
+
require 'automateit/address_manager/freebsd'
|
@@ -7,7 +7,7 @@ class AutomateIt::AddressManager::BaseDriver< AutomateIt::Plugin::Driver
|
|
7
7
|
# See AddressManager#hostnames
|
8
8
|
def hostnames()
|
9
9
|
# NOTE: depends on driver's implementation of addresses
|
10
|
-
names = addresses.inject(Set.new) do |sum, address|
|
10
|
+
names = manager.addresses.inject(Set.new) do |sum, address|
|
11
11
|
# Some addresses can't be resolved, bummer.
|
12
12
|
sum.merge(Resolv.getnames(address)) rescue Resolv::ResolvError; sum
|
13
13
|
end
|
@@ -33,9 +33,9 @@ class AutomateIt::AddressManager::BaseDriver< AutomateIt::Plugin::Driver
|
|
33
33
|
def has?(opts)
|
34
34
|
raise ArgumentError.new(":device or :address must be specified") unless opts[:device] or opts[:address]
|
35
35
|
result = true
|
36
|
-
result &= interfaces.include?(opts[:device]) if opts[:device] and not opts[:label]
|
37
|
-
result &= interfaces.include?(opts[:device]+":"+opts[:label]) if opts[:device] and opts[:label]
|
38
|
-
result &= addresses.include?(opts[:address]) if opts[:address]
|
36
|
+
result &= manager.interfaces.include?(opts[:device]) if opts[:device] and not opts[:label]
|
37
|
+
result &= manager.interfaces.include?(opts[:device]+":"+opts[:label]) if opts[:device] and opts[:label]
|
38
|
+
result &= manager.addresses.include?(opts[:address]) if opts[:address]
|
39
39
|
return result
|
40
40
|
end
|
41
41
|
|
@@ -88,14 +88,14 @@ class AutomateIt::AddressManager::BaseDriver< AutomateIt::Plugin::Driver
|
|
88
88
|
opts[:announcements] = opts[:announcements].to_i || AutomateIt::AddressManager::DEFAULT_ANNOUNCEMENTS
|
89
89
|
raise SecurityError.new("you must be root") unless superuser?
|
90
90
|
raise ArgumentError.new(":device and :address must be specified") unless opts[:device] and opts[:address]
|
91
|
-
return false if has?(opts)
|
91
|
+
return false if manager.has?(opts)
|
92
92
|
block.call(opts)
|
93
93
|
return true
|
94
94
|
end
|
95
95
|
|
96
96
|
# Helper for #remove method.
|
97
97
|
def _remove_helper(opts, &block)
|
98
|
-
return false unless has?(opts)
|
98
|
+
return false unless manager.has?(opts)
|
99
99
|
raise SecurityError.new("you must be root") unless superuser?
|
100
100
|
raise ArgumentError.new(":device and :address must be specified") unless opts[:device] and opts[:address]
|
101
101
|
return block.call(opts)
|
@@ -128,21 +128,44 @@ class AutomateIt::AddressManager::BaseDriver< AutomateIt::Plugin::Driver
|
|
128
128
|
)
|
129
129
|
end
|
130
130
|
|
131
|
-
|
131
|
+
# Returns a string used to construct an ifconfig command, e.g.
|
132
|
+
# ifconfig hme0 192.9.2.106 netmask 255.255.255.0 up
|
133
|
+
# ifconfig hme0:1 172.40.30.4 netmask 255.255.0.0 up
|
134
|
+
#
|
135
|
+
# Options:
|
136
|
+
# * :device -- Interface, e.g., "eth0". String.
|
137
|
+
# * :label -- Alias label, e.g., "1". String.
|
138
|
+
# * :address -- IP address, e.g., "127.0.0.1". String.
|
139
|
+
# * :mask -- Netmask, e.g., "255.255.255.0" or 24. String or Fixnum.
|
140
|
+
#
|
141
|
+
# Helper options:
|
142
|
+
# * :append -- Array of strings to append to end of command, e.g., ["-alias"].
|
143
|
+
# * :prepend -- Array of strings to prepend to string, adding them after after "ifconfig", e.g., ["inet"].
|
144
|
+
# * :state -- Whether to list "up" and "down" in command. Defaults to true.
|
145
|
+
def _ifconfig_helper(action, opts, helper_opts={})
|
132
146
|
_raise_unless_available
|
147
|
+
|
148
|
+
# Translate common names
|
133
149
|
action = :del if action.to_sym == :remove
|
134
150
|
|
151
|
+
# Defaults
|
135
152
|
_normalize_opts(opts)
|
136
|
-
|
137
|
-
### ifconfig hme0 192.9.2.106 netmask 255.255.255.0 up
|
138
|
-
### ifconfig hme0:1 172.40.30.4 netmask 255.255.0.0 up
|
153
|
+
helper_opts[:state] = true unless helper_opts[:state] == false
|
139
154
|
|
140
155
|
ipcmd = "ifconfig"
|
141
156
|
ipcmd << " " << _interface_and_label(opts)
|
157
|
+
if helper_opts[:prepend]
|
158
|
+
ipcmd << " " << helper_opts[:prepend].join(" ")
|
159
|
+
end
|
142
160
|
ipcmd << " %s" % opts[:address]
|
143
161
|
ipcmd << " netmask %s" % opts[:mask] if opts[:mask]
|
144
|
-
|
145
|
-
|
162
|
+
if helper_opts[:state]
|
163
|
+
ipcmd << " up" if action == :add
|
164
|
+
ipcmd << " down" if action == :del
|
165
|
+
end
|
166
|
+
if helper_opts[:append]
|
167
|
+
ipcmd << " " << helper_opts[:append].join(" ")
|
168
|
+
end
|
146
169
|
return ipcmd
|
147
170
|
end
|
148
171
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# == AddressManager::BSD
|
2
|
+
#
|
3
|
+
# An AddressManager driver for operating systems using a BSD-like ifconfig.
|
4
|
+
# Driver provides querying addresses and interfaces.
|
5
|
+
class AutomateIt::AddressManager::BSD < AutomateIt::AddressManager::BaseDriver
|
6
|
+
def self.token
|
7
|
+
:bsd
|
8
|
+
end
|
9
|
+
|
10
|
+
depends_on :programs => %w(ifconfig uname),
|
11
|
+
:callbacks => lambda{`uname -s`.match(/openbsd|freebsd|sunos/i)}
|
12
|
+
|
13
|
+
def suitability(method, *args) # :nodoc:
|
14
|
+
available? ? 2 : 0
|
15
|
+
end
|
16
|
+
|
17
|
+
# See AddressManager#interfaces
|
18
|
+
def interfaces()
|
19
|
+
_raise_unless_available
|
20
|
+
return `ifconfig -a`.scan(/^([^\s]+):\s+/s).flatten
|
21
|
+
end
|
22
|
+
|
23
|
+
# See AddressManager#addresses
|
24
|
+
def addresses()
|
25
|
+
_raise_unless_available
|
26
|
+
return `ifconfig -a`.scan(/\s+inet\s+([^\s]+)\s+/).flatten
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# == AddressManager::FreeBSD
|
2
|
+
#
|
3
|
+
# A FreeBSD-specific driver for the AddressManager provides complete support for
|
4
|
+
# querying, adding and removing addresses.
|
5
|
+
class AutomateIt::AddressManager::FreeBSD < AutomateIt::AddressManager::BaseDriver
|
6
|
+
def self.token
|
7
|
+
:freebsd
|
8
|
+
end
|
9
|
+
|
10
|
+
depends_on :programs => %w(ifconfig uname),
|
11
|
+
:callbacks => lambda{`uname -s`.match(/freebsd/i)}
|
12
|
+
|
13
|
+
def suitability(method, *args) # :nodoc:
|
14
|
+
# Must be higher than ::BSD
|
15
|
+
available? ? 3 : 0
|
16
|
+
end
|
17
|
+
|
18
|
+
# See AddressManager#add
|
19
|
+
def add(opts)
|
20
|
+
_add_helper(opts) do |opts|
|
21
|
+
interpreter.sh(_freebsd_ifconfig_helper(:add, opts))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# See AddressManager#remove
|
26
|
+
def remove(opts)
|
27
|
+
_remove_helper(opts) do |opts|
|
28
|
+
interpreter.sh(_freebsd_ifconfig_helper(:remove, opts))
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# See AddressManager#has?
|
34
|
+
def has?(opts)
|
35
|
+
opts2 = opts.clone
|
36
|
+
is_alias = opts2.delete(:label)
|
37
|
+
return super(opts2)
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
# ifconfig fxp0 inet 172.16.1.3 netmask 255.255.255.255 alias
|
43
|
+
def _freebsd_ifconfig_helper(action, opts)
|
44
|
+
helper_opts = {:state => false, :prepend => %w(inet)}
|
45
|
+
opts2 = opts.clone
|
46
|
+
if opts2.delete(:label)
|
47
|
+
helper_opts[:append] = \
|
48
|
+
case action
|
49
|
+
when :add: %w(alias)
|
50
|
+
when :remove, :del: %w(-alias)
|
51
|
+
else ArgumentError.new("Unknown action: #{action}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
return _ifconfig_helper(action, opts2, helper_opts)
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# == AddressManager::OpenBSD
|
2
|
+
#
|
3
|
+
# A OpenBSD-specific driver for the AddressManager provides complete support for
|
4
|
+
# querying, adding and removing addresses.
|
5
|
+
class AutomateIt::AddressManager::OpenBSD < AutomateIt::AddressManager::BaseDriver
|
6
|
+
def self.token
|
7
|
+
:openbsd
|
8
|
+
end
|
9
|
+
|
10
|
+
depends_on :programs => %w(ifconfig uname),
|
11
|
+
:callbacks => lambda{`uname -s`.match(/openbsd/i)}
|
12
|
+
|
13
|
+
def suitability(method, *args) # :nodoc:
|
14
|
+
# Must be higher than ::BSD
|
15
|
+
available? ? 3 : 0
|
16
|
+
end
|
17
|
+
|
18
|
+
# See AddressManager#add
|
19
|
+
def add(opts)
|
20
|
+
_add_helper(opts) do |opts|
|
21
|
+
interpreter.sh(_openbsd_ifconfig_helper(:add, opts))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# See AddressManager#remove
|
26
|
+
def remove(opts)
|
27
|
+
_remove_helper(opts) do |opts|
|
28
|
+
interpreter.sh(_openbsd_ifconfig_helper(:remove, opts))
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# See AddressManager#addresses
|
34
|
+
def addresses()
|
35
|
+
_raise_unless_available
|
36
|
+
# OpenBSD requires an "-A" to display aliases, not the usual "-a"
|
37
|
+
return `ifconfig -A`.scan(/\s+inet\s+([^\s]+)\s+/).flatten
|
38
|
+
end
|
39
|
+
|
40
|
+
# See AddressManager#has?
|
41
|
+
def has?(opts)
|
42
|
+
opts2 = opts.clone
|
43
|
+
is_alias = opts2.delete(:label)
|
44
|
+
return super(opts2)
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
# ifconfig dc0 inet alias 192.168.0.3 netmask 255.255.255.255
|
50
|
+
def _openbsd_ifconfig_helper(action, opts)
|
51
|
+
helper_opts = {:state => false, :prepend => %w(inet)}
|
52
|
+
opts2 = opts.clone
|
53
|
+
if opts2.delete(:label)
|
54
|
+
helper_opts[:prepend] << \
|
55
|
+
case action
|
56
|
+
when :add: "alias"
|
57
|
+
when :remove, :del: "delete"
|
58
|
+
else ArgumentError.new("Unknown action: #{action}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
return _ifconfig_helper(action, opts2, helper_opts)
|
62
|
+
end
|
63
|
+
end
|
@@ -30,17 +30,4 @@ class AutomateIt::AddressManager::SunOS < AutomateIt::AddressManager::BaseDriver
|
|
30
30
|
true
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
34
|
-
# See AddressManager#interfaces
|
35
|
-
def interfaces()
|
36
|
-
_raise_unless_available
|
37
|
-
return `ifconfig -a`.scan(/^([^ ]+):\s+/s).flatten
|
38
|
-
end
|
39
|
-
|
40
|
-
# See AddressManager#addresses
|
41
|
-
def addresses()
|
42
|
-
_raise_unless_available
|
43
|
-
return `ifconfig -a`.scan(/\s+inet\s+([^\s]+)\s+/).flatten
|
44
|
-
end
|
45
33
|
end
|
46
|
-
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# == PlatformManager::OpenBSD
|
2
|
+
#
|
3
|
+
# A PlatformManager driver for OpenBSD.
|
4
|
+
class AutomateIt::PlatformManager::OpenBSD < AutomateIt::PlatformManager::Uname
|
5
|
+
def self.token
|
6
|
+
:openbsd
|
7
|
+
end
|
8
|
+
|
9
|
+
depends_on :files => %w(/obsd /bsd /bsd.rd), :directories => %w(/altroot /stand)
|
10
|
+
|
11
|
+
def suitability(method, *args) # :nodoc:
|
12
|
+
# Must be higher than PlatformManager::Struct
|
13
|
+
return available? ? 3 : 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def _prepare
|
17
|
+
return if @struct[:distro]
|
18
|
+
@struct[:distro] = `uname -s`.strip.downcase
|
19
|
+
@struct[:release] = `uname -r`.strip.downcase
|
20
|
+
@struct
|
21
|
+
end
|
22
|
+
private :_prepare
|
23
|
+
|
24
|
+
def query(search)
|
25
|
+
_prepare
|
26
|
+
super(search)
|
27
|
+
end
|
28
|
+
end
|
data/lib/automateit/root.rb
CHANGED
data/lib/ext/metaclass.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
class Object
|
4
4
|
# The hidden singleton lurks behind everyone
|
5
5
|
def metaclass; class << self; self; end; end
|
6
|
-
def meta_eval
|
6
|
+
def meta_eval(&blk); metaclass.instance_eval(&blk); end
|
7
7
|
|
8
8
|
# Adds methods to a metaclass
|
9
9
|
def meta_def name, &blk
|
@@ -47,7 +47,7 @@ else
|
|
47
47
|
it "should find added interface" do
|
48
48
|
@m.add(@properties).should be_true if @independent
|
49
49
|
|
50
|
-
@m.interfaces.should include(@device_and_label)
|
50
|
+
@m.interfaces.should include(@has_named_aliases ? @device_and_label : @device)
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should find added IP address" do
|
@@ -116,44 +116,49 @@ else
|
|
116
116
|
|
117
117
|
#---[ Targets ]---------------------------------------------------------
|
118
118
|
|
119
|
-
|
120
|
-
|
121
|
-
driver = INTERPRETER.address_manager
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
}
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
119
|
+
begin
|
120
|
+
# Raises exception if no driver is available, which is caught later
|
121
|
+
driver = INTERPRETER.address_manager.driver_for(:add)
|
122
|
+
driver_token = driver.token
|
123
|
+
|
124
|
+
describe driver.class.to_s do
|
125
|
+
it_should_behave_like "AutomateIt::AddressManager"
|
126
|
+
|
127
|
+
before(:all) do
|
128
|
+
@driver_token = driver_token
|
129
|
+
|
130
|
+
# Defaults
|
131
|
+
@has_named_aliases = true
|
132
|
+
@properties = {
|
133
|
+
:device => @m.interfaces.reject{|t| t =~ /^lo\d+$/}.first,
|
134
|
+
:label => "1",
|
135
|
+
:address => "10.0.0.249",
|
136
|
+
:mask => "24",
|
137
|
+
}
|
138
|
+
|
139
|
+
# Platform specifics
|
140
|
+
case driver_token
|
141
|
+
when :sunos
|
142
|
+
# Accept defaults
|
143
|
+
when :openbsd, :freebsd
|
144
|
+
@has_named_aliases = false
|
145
|
+
when :linux
|
146
|
+
@properties[:label] = "atst"
|
147
|
+
@properties[:announcements] = 1
|
148
|
+
else
|
149
|
+
raise ArgumentError.new("Unknown defaults for AddressManager driver: #{driver_token}")
|
150
|
+
end
|
151
|
+
|
152
|
+
@device = @properties[:device]
|
153
|
+
@device_and_label = @properties[:device]+":"+@properties[:label]
|
154
|
+
|
155
|
+
if @m.interfaces.include?(@device_and_label) \
|
156
|
+
or @m.addresses.include?(@properties[:address])
|
157
|
+
raise "ERROR: This computer already has the device/address used for testing! Either disable #{@device_and_label} and #{@properties[:address]}, or change the spec to test using different properties."
|
153
158
|
end
|
154
159
|
end
|
155
|
-
else
|
156
|
-
puts %{NOTE: Can't check %s on this platform, #{__FILE__}} % driver.class
|
157
160
|
end
|
161
|
+
rescue NotImplementedError
|
162
|
+
puts "Can't find AddressManager for this platform, #{__FILE__}"
|
158
163
|
end
|
159
164
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "/../spec_helper.rb")
|
2
2
|
|
3
3
|
PACKAGE_FOUND_ERROR = %q{ERROR: Found the '%s' package installed for %s. You're probably not using this obscure package and should remove it so that this test can run. In the unlikely event that you actually rely on this package, change the spec to test with another unused package.}
|
4
|
-
PACKAGE_DRIVER_MISSING_ERROR =
|
4
|
+
PACKAGE_DRIVER_MISSING_ERROR = "NOTE: Can't check %s on this platform, #{__FILE__}"
|
5
5
|
|
6
6
|
if not INTERPRETER.euid?
|
7
7
|
puts "NOTE: Can't check 'euid' on this platform, #{__FILE__}"
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: automateit
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "0.
|
7
|
-
date: 2007-10-
|
6
|
+
version: "0.71021"
|
7
|
+
date: 2007-10-22 00:00:00 -07:00
|
8
8
|
summary: AutomateIt is an open-source tool for automating the setup and maintenance of UNIX-like systems
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -123,14 +123,18 @@ files:
|
|
123
123
|
- lib/automateit/platform_manager/windows.rb
|
124
124
|
- lib/automateit/platform_manager/uname.rb
|
125
125
|
- lib/automateit/platform_manager/lsb.rb
|
126
|
+
- lib/automateit/platform_manager/openbsd.rb
|
126
127
|
- lib/automateit/platform_manager/gentoo.rb
|
127
128
|
- lib/automateit/platform_manager/darwin.rb
|
128
129
|
- lib/automateit/platform_manager/freebsd.rb
|
129
130
|
- lib/automateit/platform_manager/sunos.rb
|
131
|
+
- lib/automateit/address_manager/openbsd.rb
|
130
132
|
- lib/automateit/address_manager/portable.rb
|
131
133
|
- lib/automateit/address_manager/sunos.rb
|
132
134
|
- lib/automateit/address_manager/linux.rb
|
133
135
|
- lib/automateit/address_manager/base.rb
|
136
|
+
- lib/automateit/address_manager/bsd.rb
|
137
|
+
- lib/automateit/address_manager/freebsd.rb
|
134
138
|
- lib/automateit/shell_manager/portable.rb
|
135
139
|
- lib/automateit/shell_manager/which.rb
|
136
140
|
- lib/automateit/shell_manager/symlink.rb
|
metadata.gz.sig
CHANGED
Binary file
|