Skip to content

Commit

Permalink
Refactor resource to name "stow" and give all variables descriptive n…
Browse files Browse the repository at this point in the history
…ames.

Previously the resource was "stow_package" which was misleading since it
wasn't really a package, yet the older "stowify" name was a verb. The new
"stow" name more clearly indicates what's being done.

Previously many variables had terse names like "o", "s", "downloaded" or
"extracted". Now they have more descriptive names like "struct",
"downloaded_file" or "extracted_directory", which will hopefully be easier
to understand.

Added more documentation.
  • Loading branch information
igal committed Jun 19, 2012
1 parent da128d2 commit 9d0e041
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 107 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ Recipes
Resources and Providers
-----------------------

* [stow resource](http://github.com/igal/antipackaging/blob/master/cookbooks/stow_package/resources/default.rb) - A custom Chef resource to download, compile, install and stow applications.
* [stow provider](http://github.com/igal/antipackaging/blob/master/cookbooks/stow_package/providers/default.rb) - A custom Chef provider to implement the above resource.
* [stow resource](http://github.com/igal/antipackaging/blob/master/cookbooks/stow/resources/default.rb) - A custom Chef resource to download, compile, install and stow applications.
* [stow provider](http://github.com/igal/antipackaging/blob/master/cookbooks/stow/providers/default.rb) - A custom Chef provider to implement the above resource.

Running examples
----------------
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
desc "Regenerate cookbook metadata.json files"
task :metadata do
%w[antipackaging stow_package].each do |name|
%w[antipackaging stow].each do |name|
sh "knife cookbook metadata #{name} -o cookbooks"
end
end
30 changes: 15 additions & 15 deletions cookbooks/antipackaging/recipes/standalone.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
package "stow"

# Define stow directory
stow = "/usr/local/stow"
stow_directory = "/usr/local/stow"

# Create stow directory
directory stow
directory stow_directory

#=======================================================================

Expand All @@ -29,30 +29,30 @@
# NOT: url = "http://nginx.org/download/#{name_and_version}.tar.gz"

# Derived variables
cache = Chef::Config[:file_cache_path]
downloaded = ::File.join(cache, ::File.basename(url))
extracted = ::File.join(cache, name_and_version)
installed = ::File.join(stow, name_and_version)
check_installed = ::File.join(installed, check) # <- "/usr/local/stow/ngnix-1.3.1/sbin/ngnix"
check_stowed = ::File.join(stow, "..", check) # <- "/usr/local/sbin/nginx"
cache_directory = Chef::Config[:file_cache_path]
downloaded_file = ::File.join(cache_directory, ::File.basename(url))
extracted_directory = ::File.join(cache_directory, name_and_version)
installed_directory = ::File.join(stow_directory, name_and_version)
check_installed = ::File.join(installed_directory, check) # <- "/usr/local/stow/ngnix-1.3.1/sbin/ngnix"
check_stowed = ::File.join(stow_directory, "..", check) # <- "/usr/local/sbin/nginx"

# Ensure nginx
if (::File.stat(check_stowed).ino != ::File.stat(check_installed).ino rescue true)
# Download archive
remote_file downloaded do
remote_file downloaded_file do
source url
end

# Install nginx
bash "install_nginx" do
cwd cache
cwd cache_directory
code <<-HERE
set -e -x
(cd #{stow} && stow -D #{name}-*) || true
rm -rf #{installed}
rm -rf #{extracted}
dtrx -n #{downloaded}
(cd #{extracted} && ./configure --prefix=#{installed} && make && make install && cd #{stow} && stow #{name_and_version})
(cd #{stow_directory} && stow -D #{name}-*) || true
rm -rf #{installed_directory}
rm -rf #{extracted_directory}
dtrx -n #{downloaded_file}
(cd #{extracted_directory} && ./configure --prefix=#{installed_directory} && make && make install && cd #{stow_directory} && stow #{name_and_version})
HERE
end
end
4 changes: 2 additions & 2 deletions cookbooks/antipackaging/recipes/stow.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Same as `standalone.rb` recipe, but now using a custom resource.
stow_package "nginx" do
stow "nginx" do
version "1.3.1"
check "sbin/nginx"
url "https://s3.amazonaws.com/igalfiles/#{@name}-#{@version}.tar.gz"
Expand All @@ -10,7 +10,7 @@
end

# Same resource, but for different software with a trickier installation.
stow_package "ts" do
stow "ts" do
version "0.7.3"
check "bin/ts"
url "https://s3.amazonaws.com/igalfiles/#{@name}-#{@version}.tar.gz"
Expand Down
4 changes: 2 additions & 2 deletions cookbooks/antipackaging/recipes/uninstall.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
stow_package "nginx" do
stow "nginx" do
check "sbin/nginx"
action :uninstall
end

stow_package "ts" do
stow "ts" do
check "bin/ts"
action :uninstall
end
1 change: 1 addition & 0 deletions cookbooks/stow/attributes/default.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default['stow']['directory'] = '/usr/local/stow'
File renamed without changes.
File renamed without changes.
106 changes: 106 additions & 0 deletions cookbooks/stow/providers/default.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Structure representing paths and other properties of a stow resource, which
# can be reused by both the :install and :uninstall actions. See the actions
# definitions below to see how this is used.
StowStruct = Struct.new(:name, :version, :name_and_version, :separator, :url,
:install, :dependencies, :downloaded_file, :extracted_directory,
:installed_directory, :stow_directory, :cache_directory, :check,
:check_installed, :check_stowed, :placeholder) do

# Return new structure parsed from a +node+ and +new_resource+.
def self.parse(node, new_resource)
struct = self.new
struct.name = new_resource.name
struct.version = new_resource.version
struct.url = new_resource.url
struct.separator = new_resource.separator
struct.placeholder = new_resource.placeholder
struct.dependencies = new_resource.dependencies
struct.install = new_resource.install

struct.stow_directory = node.stow.directory
struct.cache_directory = Chef::Config[:file_cache_path]
struct.name_and_version = [struct.name, struct.separator, struct.version].join if struct.version
struct.downloaded_file = ::File.join(struct.cache_directory, ::File.basename(struct.url)) if struct.url
struct.extracted_directory = ::File.join(struct.cache_directory, struct.name_and_version) if struct.version
struct.installed_directory = ::File.join(struct.stow_directory, struct.name_and_version) if struct.version
struct.check = new_resource.check
struct.check_installed = ::File.join(struct.installed_directory, struct.check) if struct.installed_directory
struct.check_stowed = ::File.join(struct.stow_directory, "..", struct.check)
return struct
end
end

action :install do
# Ensure all required arguments were specified
%w[version check url install].each do |name|
unless new_resource.send(name)
raise ArgumentError, "stow: '#{name}' must be specified"
end
end

struct = StowStruct.parse(node, new_resource)

# Install tools needed for extracting and stowing
package "dtrx"
package "stow"
directory struct.stow_directory

# Only build new software if it's not already present
if (::File.stat(struct.check_installed).ino != ::File.stat(struct.check_stowed).ino rescue true)
# Download source
remote_file struct.downloaded_file do
source struct.url
end

# Install dependencies
if struct.dependencies
struct.dependencies.each do |name|
package name
end
end

# Install software
bash "install_#{struct.name_and_version}" do
# Figure out what commands to run to install the software
installer =
case struct.install
when String
# When given a string, substitute the placeholder ("@@PREFIX@@") with name of install directory.
struct.install.gsub(/#{struct.placeholder}/, struct.installed_directory)
when Proc
# When given a proc, call it with the name of the install directory.
struct.install.call(struct.installed_directory)
else
raise ArgumentError, "stow: 'install' must be a String or Proc, not: #{struct.install.class}"
end

# Go into directory with the downloaded file
cwd struct.cache_directory

code <<-HERE
set -e -x
(cd #{struct.stow_directory} && stow -D #{struct.name}#{struct.separator}*) || true
rm -rf #{struct.installed_directory}
rm -rf #{struct.extracted_directory}
dtrx -n #{struct.downloaded_file}
(cd #{struct.extracted_directory} && #{installer} && cd #{struct.stow_directory} && stow #{struct.name_and_version})
HERE
end
end
end

action :uninstall do
struct = StowStruct.parse(node, new_resource)

execute "uninstall_#{struct.name}" do
only_if { ::File.exist?(struct.check_stowed) }

cwd struct.stow_directory

if struct.name_and_version
command "stow -D #{struct.name_and_version}"
else
command "stow -D #{struct.name}#{struct.separator}*"
end
end
end
File renamed without changes.
1 change: 0 additions & 1 deletion cookbooks/stow_package/attributes/default.rb

This file was deleted.

84 changes: 0 additions & 84 deletions cookbooks/stow_package/providers/default.rb

This file was deleted.

0 comments on commit 9d0e041

Please sign in to comment.