automateit 0.71021 → 0.71030

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.
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,13 @@
1
+ 0.71030:
2
+ Date: Tue, 30 Oct 2007 01:43:02 -0700
3
+ Desc:
4
+ - (%) Fixed bug in AddressManager#add_user when called with multiple groups. Improved AddressManager spec.
5
+ - (+) Added documentation to Project explaining how to partition recipes, and run recipes from other recipes.
6
+ - (+) Added AddressManager::POSIX which provides support for Linux and SunOS, and eliminated the OS-specific drivers for these.
7
+ - Added AddressManager::NSCD by extracting methods from old OS-specific drivers.
8
+ - Added AddressManager::PasswdExpect which uses Expect for much more reliable password changes.
9
+ - Improved AddressManager::PasswdPty by adding retry capability.
10
+
1
11
  0.71021:
2
12
  Date: Sun, 21 Oct 2007 04:58:01 -0700
3
13
  Desc:
data/Hoe.rake CHANGED
@@ -18,17 +18,19 @@ task :manifest do
18
18
  end
19
19
 
20
20
  Hoe.new("AutomateIt", AutomateIt::VERSION.to_s) do |s|
21
+ slogan = "AutomateIt is an open source tool for automating the setup and maintenance of servers, applications and their dependencies."
22
+ title = "AutomateIt: Open source server automation"
21
23
  s.author = "Igal Koshevoy"
22
24
  s.changes = s.paragraphs_of('CHANGES.txt', 0).join("\n")
23
- s.description = "AutomateIt is an open-source tool for automating the setup and maintenance of UNIX-like systems"
25
+ s.description = slogan
24
26
  s.email = "igal@pragmaticraft.com"
25
27
  s.extra_deps = [["activesupport", ">= 1.4"], ["open4", ">= 0.9"]]
26
28
  s.name = "automateit"
27
- s.summary = "AutomateIt is an open-source tool for automating the setup and maintenance of UNIX-like systems"
29
+ s.summary = slogan
28
30
  s.url = "http://automateit.org/"
29
31
  s.spec_extras = {
30
32
  :platform => Gem::Platform::RUBY,
31
- :rdoc_options => %w(--main README.txt --promiscuous --accessor class_inheritable_accessor=R --title) << 'AutomateIt is an open-source tool for automating the setup and maintenance of UNIX-like systems.' << %w(lib docs),
33
+ :rdoc_options => %w(--main README.txt --promiscuous --accessor class_inheritable_accessor=R --title) << title << %w(lib docs),
32
34
  :extra_rdoc_files => FileList[%w(README.txt TUTORIAL.txt TESTING.txt), "docs/*.txt"],
33
35
  }
34
36
  s.spec_extras.merge!(HoeInclude)
data/README.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  == AutomateIt
2
2
 
3
- <em>AutomateIt is an open-source tool for automating the setup and maintenance of servers.</em>
3
+ <em>AutomateIt is an open source tool for automating the setup and maintenance of servers, applications and their dependencies.</em>
4
4
 
5
5
  Information about AutomateIt is best read in the following order:
6
6
  1. http://AutomateIt.org -- website explaining what it is and why it's useful
data/Rakefile CHANGED
@@ -159,6 +159,13 @@ task :now do
159
159
  puts time.to_s(:rfc822)
160
160
  end
161
161
 
162
+ desc "RFC-822 time for yesterday"
163
+ task :yesterday do
164
+ require 'active_support'
165
+ time = Time.now - 1.day
166
+ puts time.to_s(:rfc822)
167
+ end
168
+
162
169
  namespace :gem do
163
170
  desc "View Gem metadata"
164
171
  task :metadata do
@@ -226,7 +233,7 @@ namespace :rdoc do
226
233
  desc "Generate documentation"
227
234
  task :make do
228
235
  # Uses Jamis Buck's RDoc template from http://weblog.jamisbuck.org/2005/4/8/rdoc-template
229
- sh "rdoc --template=jamis --main README.txt --promiscuous --accessor class_inheritable_accessor=R --title 'AutomateIt is an open-source tool for automating the setup and maintenance of UNIX-like systems.' lib docs/*.txt README.txt TUTORIAL.txt TESTING.txt"
236
+ sh "rdoc --template=jamis --main README.txt --promiscuous --accessor class_inheritable_accessor=R --title 'AutomateIt: Open source server automation' lib docs/*.txt README.txt TUTORIAL.txt TESTING.txt"
230
237
  # Create a tutorial index
231
238
  File.open("doc/tutorial.html", "w+") do |writer|
232
239
  writer.write(File.read("doc/index.html").sub(/README_txt.html/, 'TUTORIAL_txt.html'))
@@ -274,7 +281,7 @@ namespace :rdoc do
274
281
  puts "checking %s" % File.mtime(target)
275
282
  puts "different" if different
276
283
 
277
- sh "rdoc --template=jamis --promiscuous --accessor class_inheritable_accessor=R --title 'AutomateIt is an open-source tool for automating the setup and maintenance of UNIX-like systems.' %s" % sources_and_targets.values.join(" ") if different
284
+ sh "rdoc --template=jamis --promiscuous --accessor class_inheritable_accessor=R --title 'AutomateIt: Open source server automation' %s" % sources_and_targets.values.join(" ") if different
278
285
  sleep 1
279
286
  end
280
287
  end
@@ -304,8 +311,11 @@ task :chown do
304
311
  end
305
312
  end
306
313
 
314
+ desc "Link to local rdoc stash"
307
315
  task :rdoclink do
308
316
  automateit.ln_s("/home/lagi/stash/automateit_rdoc", "doc")
309
317
  end
310
318
 
319
+ task :after => [:rdoclink, :rdoc, :regem]
320
+
311
321
  #===[ fin ]=============================================================
data/TODO.txt CHANGED
@@ -2,22 +2,27 @@ KEY: Important? Urgent? Easy? 1=yes, 0=no
2
2
 
3
3
  #===[ App ]=============================================================
4
4
 
5
- Solaris 10
6
- - Create AccountManager::SunOS
7
- - Create ServiceManager::SMF
8
- - Create PackageManager::Blastwave
9
- - Create PackageManager::SunPkg
5
+ BUGS
6
+ - does service_manager.start_and_enable work as expected?
10
7
 
11
- 111 Shell -- Write #su(user, *command)
12
- 100 Shell -- Expand glob patterns, e.g. chown_R(500, 500, "*")
8
+ 111 aissh or aion -- Write command for running stuff against servers with ssh, e.g., "aissh rails_servers ls", which is basically a wrapper over "for t in aitag -w rails_servers; do echo $t; ssh $t "ls"; done"
9
+ 111 Shell -- Write #su(user, *command) as a wrapper around #sh
10
+ 101 Shell -- Expand glob patterns, e.g. chown_R(500, 500, "*")
13
11
 
14
12
  100 Edit -- Display summary of edits, return with :details as [rv, list]
15
13
  100 Shell -- Incorporate which.cmd so #which can work on Windows
16
14
  100 Interpreter#invoke and HelpfulERB -- Extract error context code into class
17
15
 
16
+ 001 CPAN -- Write driver for PackageManager::CPAN
17
+ 001 FreeBSD -- Write driver for PackageManager::FreeBSD_Ports (or generic ::Ports?) and FreeBSD_Pkg
18
+ 000 Darwin -- Write drivers, e.g. PackageManager for Fink and MacPorts (or generic ::Ports?)
18
19
  000 Shell#chperm -- With symbolic mode, wrap `chmod -v` as temporary workaround?
19
- 000 FreeBSD -- Write driver for PackageManager::Ports
20
- 000 Darwin -- Write drivers, e.g. PackageManager for Fink, MacPorts, Pkgsrc
20
+ 000 PackageManager -- Provide a way to specify desired versions and upgrade via recipes
21
+
22
+ Solaris 10
23
+ 000 Create ServiceManager::SMF
24
+ 000 Create PackageManager::Blastwave
25
+ 000 Create PackageManager::SunOS_Pkg
21
26
 
22
27
  ??? Shell -- Return false or list, never single item?
23
28
  ??? Driver -- How to determine if a manager or driver method is available? Manager#available?, Manager#available and Driver#suitable? only say if it should be a default.
@@ -1,6 +1,6 @@
1
1
  == A hands-on tutorial for learning AutomateIt
2
2
 
3
- <em>AutomateIt is an open-source tool for automating the setup and maintenance of servers.</em>
3
+ <em>AutomateIt is an open source tool for automating the setup and maintenance of servers, applications and their dependencies.</em>
4
4
 
5
5
  This hands-on guide will teach you to use AutomateIt and explain where to find more detailed instructions.
6
6
 
@@ -0,0 +1,65 @@
1
+ # == Dependencies
2
+
3
+ # Standard libraries
4
+ require 'etc'
5
+ require 'fileutils'
6
+ require 'find'
7
+ require 'logger'
8
+ require 'open3'
9
+ require 'pp'
10
+ require 'pathname'
11
+ require 'resolv'
12
+ require 'set'
13
+ require 'socket'
14
+ require 'yaml'
15
+ require 'erb'
16
+
17
+ # Load ActiveSupport pieces individually to save ~0.5s
18
+ ### require 'active_support'
19
+ gem 'activesupport'
20
+ require 'active_support/core_ext/array' # [].extract_options, new in AS 1.4.4
21
+ require 'active_support/core_ext/blank' # foo.blank?
22
+ require 'active_support/core_ext/class/attribute_accessors' # cattr_accessor
23
+ require 'active_support/core_ext/class/inheritable_attributes' # inheritable_cattr_accessor
24
+ require 'active_support/core_ext/module/aliasing' # alias_method_chain
25
+ require 'active_support/core_ext/string' # "asdf".demodulize.underscore
26
+ require 'active_support/clean_logger' # cleans up Logger output
27
+ require 'active_support/core_ext/symbol' # [:foo, :bar].map(&:to_s)
28
+
29
+ # Handle ActiveSupport includes
30
+ require 'active_support/core_ext/hash/keys' # {:foo => :bar}.stringify_keys
31
+ Hash.module_eval{include ActiveSupport::CoreExtensions::Hash::Keys}
32
+
33
+ # Extensions
34
+ require 'ext/object.rb'
35
+ require 'ext/metaclass.rb'
36
+
37
+ # Helpers
38
+ require 'hashcache'
39
+ require 'queued_logger'
40
+ require 'tempster'
41
+ require 'helpful_erb'
42
+ require 'nested_error'
43
+
44
+ # Core
45
+ require 'automateit/root'
46
+ require 'automateit/constants'
47
+ require 'automateit/error'
48
+ require 'automateit/common'
49
+ require 'automateit/interpreter'
50
+ require 'automateit/plugin'
51
+ require 'automateit/cli'
52
+ require 'automateit/project'
53
+
54
+ # Plugins which must be loaded early
55
+ require 'automateit/shell_manager'
56
+ require 'automateit/platform_manager' # requires shell
57
+ require 'automateit/address_manager' # requires shell
58
+ require 'automateit/tag_manager' # requires address, platform
59
+ require 'automateit/field_manager' # requires shell
60
+ require 'automateit/service_manager' # requires shell
61
+ require 'automateit/package_manager' # requires shell
62
+ require 'automateit/template_manager'
63
+ require 'automateit/edit_manager'
64
+ require 'automateit/account_manager'
65
+ require 'automateit/download_manager'
@@ -3,6 +3,17 @@
3
3
  # The AccountManager provides a way of managing system accounts, such as Unix
4
4
  # users and groups.
5
5
  class AutomateIt::AccountManager < AutomateIt::Plugin::Manager
6
+ # Invalidate system cache for +database+. The +database+ can be either :users
7
+ # or :groups. This is necessary on operating systems that lack logic to
8
+ # notify their caching system that an entry changed. If the OS doesn't need
9
+ # invalidation, will do nothing and return false.
10
+ #
11
+ # This method is primarily for the sake of driver authors, recipe authors
12
+ # will probably never need to use this.
13
+ def invalidate(database) dispatch_safely(database) end
14
+
15
+ #-----------------------------------------------------------------------
16
+
6
17
  # Find a user account. Method returns a query helper which takes a
7
18
  # +username+ as an index argument and returns a Struct::Passwd entry as
8
19
  # described in Etc::getpwent if the user exists or a nil if not.
@@ -50,7 +61,7 @@ class AutomateIt::AccountManager < AutomateIt::Plugin::Manager
50
61
  def remove_groups_from_user(groups, user) dispatch(groups, user) end
51
62
 
52
63
  # Change the +password+ for the +user+.
53
- def passwd(user, password) dispatch(user, password) end
64
+ def passwd(user, password, opts={}) dispatch(user, password, opts) end
54
65
 
55
66
  #.......................................................................
56
67
 
@@ -94,13 +105,10 @@ class AutomateIt::AccountManager < AutomateIt::Plugin::Manager
94
105
  def users_to_groups() dispatch() end
95
106
  end # class AccountManager
96
107
 
97
- # == AccountManager::BaseDriver
98
- #
99
- # Base class for all AccountManager drivers.
100
- class ::AutomateIt::AccountManager::BaseDriver < AutomateIt::Plugin::Driver
101
- end
102
-
103
108
  # Drivers
104
- require 'automateit/account_manager/portable'
105
- require 'automateit/account_manager/linux'
106
- require 'automateit/account_manager/passwd'
109
+ require 'automateit/account_manager/base'
110
+ require 'automateit/account_manager/passwd_pty'
111
+ require 'automateit/account_manager/passwd_expect'
112
+ require 'automateit/account_manager/nscd'
113
+ require 'automateit/account_manager/etc'
114
+ require 'automateit/account_manager/posix'
@@ -0,0 +1,133 @@
1
+ # == AccountManager::BaseDriver
2
+ #
3
+ # Base class for all AccountManager drivers.
4
+ class ::AutomateIt::AccountManager::BaseDriver < ::AutomateIt::Plugin::Driver
5
+ protected
6
+
7
+ def _passwd_helper(user, password, opts={}, &block)
8
+ users = manager.users
9
+
10
+ unless users[user]
11
+ if preview?
12
+ log.info(PNOTE+"Setting password for user: #{user}")
13
+ return true
14
+ else
15
+ raise ArgumentError.new("No such user: #{user}")
16
+ end
17
+ end
18
+
19
+ case user
20
+ when Symbol: user = user.to_s
21
+ when Integer: user = users[user]
22
+ when String: # leave it alone
23
+ else raise TypeError.new("Unknown user type: #{user.class}")
24
+ end
25
+
26
+ return block.call(user, password, opts)
27
+ end
28
+
29
+ def _add_user_helper(username, opts={}, &block)
30
+ return false if has_user?(username)
31
+
32
+ # Create group first, then the user. Necessary because some OSes can't add users with non-existent groups.
33
+
34
+ if opts[:personal_group].nil? and not opts[:group] and not opts[:gid]
35
+ opts[:personal_group] = true
36
+ end
37
+
38
+ # FIXME how to default personal_group to false?
39
+ # FIXME what if want to add user to a specific group, rather than creating?
40
+ # FIXME what if want or not want to crease user group?
41
+ # FIXME how to find an unused gid/uid combo?
42
+
43
+ unless opts[:group] == false
44
+ groupname = opts[:group] || username
45
+ unless has_group?(groupname)
46
+ if not opts[:uid] and not opts[:gid] and group = add_group(groupname, opts)
47
+ opts[:uid] = opts[:gid] = group.gid
48
+ end
49
+ end
50
+ end
51
+
52
+ block.call(username, opts)
53
+
54
+ passwd_opts = {:quiet => opts[:quiet]}
55
+ manager.passwd(username, opts[:passwd], passwd_opts) if opts[:passwd]
56
+
57
+ manager.invalidate(:passwd)
58
+ return users[username]
59
+ end
60
+
61
+ def _remove_user_helper(username, opts={}, &block)
62
+ return false unless has_user?(username)
63
+
64
+ block.call(username, opts)
65
+ manager.invalidate(:passwd)
66
+ remove_group(username) if has_group?(username)
67
+
68
+ return true
69
+ end
70
+
71
+ def _add_groups_to_user_helper(groups, username, &block)
72
+ groups = [groups].flatten
73
+ present = groups_for_user(username)
74
+ missing = groups - present
75
+ return false if missing.empty?
76
+
77
+ block.call(missing, username)
78
+ manager.invalidate(:group)
79
+
80
+ return missing
81
+ end
82
+
83
+ def _remove_groups_from_user_helper(groups, username, &block)
84
+ groups = [groups].flatten
85
+ matched = groups_for_user(username)
86
+ present = groups & matched
87
+ return false if present.empty?
88
+
89
+ block.call(present, username)
90
+ manager.invalidate(:group)
91
+
92
+ return present
93
+ end
94
+
95
+ def _add_users_to_group_helper(users, groupname, &block)
96
+ users = [users].flatten
97
+ # XXX Include pwent.gid?
98
+ grent = groups[groupname]
99
+ missing = \
100
+ if writing? and not grent
101
+ raise ArgumentError.new("no such group: #{groupname}")
102
+ elsif writing? or grent
103
+ users - grent.mem
104
+ else
105
+ users
106
+ end
107
+ return false if missing.empty?
108
+
109
+ block.call(missing, groupname)
110
+ manager.invalidate(:groups)
111
+
112
+ return missing
113
+ end
114
+
115
+ def _remove_users_from_group_helper(users, groupname, &block)
116
+ users = [users].flatten
117
+ grent = groups[groupname]
118
+ present = \
119
+ if writing? and not grent
120
+ raise ArgumentError.new("no such group: #{groupname}")
121
+ elsif writing? or grent
122
+ grent.mem & users
123
+ else
124
+ users
125
+ end
126
+ return false if present.empty?
127
+
128
+ block.call(present, groupname)
129
+ manager.invalidate(:groups)
130
+
131
+ return present
132
+ end
133
+ end
@@ -1,10 +1,11 @@
1
- # == AccountManager::Portable
1
+ # == AccountManager::Etc
2
2
  #
3
- # A pure-Ruby, portable driver for the AccountManager. It is only suitable
4
- # for doing queries and lacks methods such as +add_user+. Platform-specific
5
- # drivers inherit from this class and provide these methods.
6
- class ::AutomateIt::AccountManager::Portable < ::AutomateIt::AccountManager::BaseDriver
7
- depends_on :callbacks => [lambda{AutomateIt::AccountManager::Portable.has_etc?}]
3
+ # An AccountManager driver for Unix-like OSes that have the Ruby Etc module. It
4
+ # is only suitable for doing queries and lacks methods that perform
5
+ # modifications, such as +add_user+. Platform-specific drivers inherit from
6
+ # this class and provide methods that perform modifications.
7
+ class ::AutomateIt::AccountManager::Etc< ::AutomateIt::AccountManager::BaseDriver
8
+ depends_on :callbacks => [lambda{AutomateIt::AccountManager::Etc.has_etc?}]
8
9
 
9
10
  def suitability(method, *args) # :nodoc:
10
11
  return 1
@@ -14,14 +15,14 @@ class ::AutomateIt::AccountManager::Portable < ::AutomateIt::AccountManager::Bas
14
15
  # the 'etc' module?
15
16
  def self.has_etc?
16
17
  begin
17
- require 'etc'
18
+ require './spec/integration/account_manager_spec.rb:1etc'
18
19
  return defined?(Etc)
19
20
  rescue LoadError
20
21
  return false
21
22
  end
22
23
  end
23
24
 
24
- # Alias for AccountManager::Portable.has_etc?
25
+ # Alias for AccountManager::Etc.has_etc?
25
26
  def has_etc?
26
27
  self.has_etc?
27
28
  end
@@ -0,0 +1,28 @@
1
+ # == AccountManager::NSCD
2
+ #
3
+ # AccountManager driver for invalidating records stored in the NSCD, Name
4
+ # Service Cache Daemon, found on Unix-like systems.
5
+ class ::AutomateIt::AccountManager::NSCD < ::AutomateIt::AccountManager::BaseDriver
6
+ depends_on :programs => %w(nscd ps),
7
+ :callbacks => [lambda{`ps -ef`.match(%r{/usr/sbin/nscd$})}]
8
+
9
+ def suitability(method, *args) # :nodoc:
10
+ # Level must be higher than Portable
11
+ return available? ? 5 : 0
12
+ end
13
+
14
+ def invalidate(database)
15
+ return false unless available?
16
+
17
+ name = \
18
+ case database.to_sym
19
+ when :user, :users, :passwd
20
+ :passwd
21
+ when :group, :groups
22
+ :group
23
+ else
24
+ raise ArgumentError.new("Unknown cache database: #{database}")
25
+ end
26
+ interpreter.sh("nscd -i #{name}")
27
+ end
28
+ end