Class: Cookbooks

Inherits:
Application show all
Includes:
Chef::Mixin::Checksum, Merb::CookbookVersionHelper, Merb::TarballHelper
Defined in:
app/controllers/cookbooks.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Merb::TarballHelper

#cookbook_base, #cookbook_location, #expand_tarball_and_put_in_repository, #get_or_create_cookbook_tarball_location, #sandbox_base, #sandbox_checksum_location, #sandbox_location, #validate_file_parameter

Methods included from Merb::CookbookVersionHelper

#expand_cookbook_urls, #num_versions!

Methods inherited from Application

#access_denied, #admin_or_requesting_node, #authenticate_every, #display, #get_available_recipes, #is_admin, #is_admin_or_validator, #redirect_back_or_default, #store_location

Instance Attribute Details

#cookbook_nameObject

Returns the value of attribute cookbook_name.



35
36
37
# File 'app/controllers/cookbooks.rb', line 35

def cookbook_name
  @cookbook_name
end

#cookbook_versionObject

Returns the value of attribute cookbook_version.



35
36
37
# File 'app/controllers/cookbooks.rb', line 35

def cookbook_version
  @cookbook_version
end

Instance Method Details

#destroyObject



202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'app/controllers/cookbooks.rb', line 202

def destroy
  begin
    cookbook = get_cookbook_version(cookbook_name, cookbook_version)
  rescue ArgumentError => e
    raise NotFound, "Cannot find a cookbook named #{cookbook_name} with version #{cookbook_version}"
  end

  if params["purge"] == "true"
    display cookbook.purge
  else
    display cookbook.cdb_destroy
  end
end

#indexObject



45
46
47
48
49
50
51
# File 'app/controllers/cookbooks.rb', line 45

def index
  if request.env['HTTP_X_CHEF_VERSION'] =~ /0\.9/
    index_09
  else
    index_010
  end
end

#index_010Object

GET /cookbooks returns data in the format of: => {

  :url => "http://url",
  :versions => [{:url => "http://url/1.0.0", :version => "1.0.0", => "http://url/0.0.1", :version=>"0.0.1"]
}

}



60
61
62
63
64
65
66
67
68
69
# File 'app/controllers/cookbooks.rb', line 60

def index_010
  cookbook_list = Chef::CookbookVersion.cdb_list
  # cookbook_list is in the format of {"apache2" => [0.0.1, 0.0.0]} where the version numbers are DepSelector::Version objects
  num_versions = num_versions!
  display(cookbook_list.inject({}) {|res, (cookbook_name, versions)|
    versions = versions.map{ |x| DepSelector::Version.new(x) }.sort.reverse.map{ |x| x.to_s }
    res[cookbook_name] = expand_cookbook_urls(cookbook_name, versions, num_versions)
    res
  })
end

#index_09Object

GET /cookbooks

returns data in the format of:

"apache2" => "http://url/apache2",
"python" => "http://url/python"



78
79
80
81
82
83
84
85
# File 'app/controllers/cookbooks.rb', line 78

def index_09
  cookbook_list = Chef::CookbookVersion.cdb_list_latest(false).keys.sort
  response = Hash.new
  cookbook_list.map! do |cookbook_name|
    response[cookbook_name] = absolute_url(:cookbook, :cookbook_name => cookbook_name)
  end
  display response
end

#index_recipesObject



87
88
89
90
91
92
93
94
# File 'app/controllers/cookbooks.rb', line 87

def index_recipes
  recipes_with_versions = Chef::CookbookVersion.cdb_list(true).inject({}) do|memo, f|
    memo[f.name] ||= {}
    memo[f.name][f.version] = f.recipe_filenames_by_name.keys
    memo
  end
  display recipes_with_versions
end

#params_helperObject



37
38
39
40
# File 'app/controllers/cookbooks.rb', line 37

def params_helper
  self.cookbook_name = params[:cookbook_name]
  self.cookbook_version = params[:cookbook_version]
end

#showObject



131
132
133
134
# File 'app/controllers/cookbooks.rb', line 131

def show
  cookbook = get_cookbook_version(cookbook_name, cookbook_version)
  display cookbook.generate_manifest_with_urls { |opts| absolute_url(:cookbook_file, opts) }
end

#show_fileObject

Raises:

  • (NotFound)


136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'app/controllers/cookbooks.rb', line 136

def show_file
  cookbook = get_cookbook_version(cookbook_name, cookbook_version)

  checksum = params[:checksum]
  raise NotFound, "Cookbook #{cookbook_name} version #{cookbook_version} does not contain a file with checksum #{checksum}" unless cookbook.checksums.keys.include?(checksum)

  begin
    filename = Chef::Checksum.new(checksum).storage.file_location

    send_file(filename)
  rescue Errno::ENOENT => e
    raise InternalServerError, "File with checksum #{checksum} not found in the repository (this should not happen)"
  end
end

#show_versionsObject



96
97
98
99
100
101
102
# File 'app/controllers/cookbooks.rb', line 96

def show_versions
  if request.env['HTTP_X_CHEF_VERSION'] =~ /0\.9/
    show_versions_09
  else
    show_versions_010
  end
end

#show_versions_010Object

GET /cookbooks/:cookbook_name

returns data in the format of: => {

  :url => "http://url",
  :versions => [{:url => "http://url/1.0.0", :version => "1.0.0", => "http://url/0.0.1", :version=>"0.0.1"]
}

}

Raises:

  • (NotFound)


112
113
114
115
116
117
118
# File 'app/controllers/cookbooks.rb', line 112

def show_versions_010
  versions = Chef::CookbookVersion.cdb_by_name(cookbook_name)
  raise NotFound, "Cannot find a cookbook named #{cookbook_name}" unless versions && versions.size > 0
  num_versions = num_versions!("all")
  cb_versions = versions[cookbook_name].map{ |x| DepSelector::Version.new(x) }.sort.reverse.map{ |x| x.to_s }
  display({ cookbook_name => expand_cookbook_urls(cookbook_name, cb_versions, num_versions) })
end

#show_versions_09Object

GET /cookbooks/:cookbook_name

returns data in the format of: => [“1.0.0”, “0.0.1”]

Raises:

  • (NotFound)


124
125
126
127
128
129
# File 'app/controllers/cookbooks.rb', line 124

def show_versions_09
  versions = Chef::CookbookVersion.cdb_by_name(cookbook_name)
  raise NotFound, "Cannot find a cookbook named #{requested_cookbook_name}" unless versions && versions.size > 0

  display versions
end

#updateObject

Raises:

  • (BadRequest)


151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'app/controllers/cookbooks.rb', line 151

def update
  raise(BadRequest, "You didn't pass me a valid object!") unless params.has_key?('inflated_object')
  raise(BadRequest, "You didn't pass me a Chef::CookbookVersion object!") unless params['inflated_object'].kind_of?(Chef::CookbookVersion)
  unless params["inflated_object"].name == cookbook_name
    raise(BadRequest, "You said the cookbook was named #{params['inflated_object'].name}, but the URL says it should be #{cookbook_name}.")
  end

  unless params["inflated_object"].version == cookbook_version
    raise(BadRequest, "You said the cookbook was version #{params['inflated_object'].version}, but the URL says it should be #{cookbook_version}.")
  end

  begin
    cookbook = Chef::CookbookVersion.cdb_load(cookbook_name, cookbook_version)
    cookbook.manifest = params['inflated_object'].manifest
    new_cookbook = false
  rescue Chef::Exceptions::CouchDBNotFound => e
    Chef::Log.debug("Cookbook #{cookbook_name} version #{cookbook_version} does not exist")
    cookbook = params['inflated_object']
    new_cookbook = true
  end

  unless new_cookbook
    if cookbook.frozen_version? && params[:force].nil?
      raise Conflict, "The cookbook #{cookbook.name} at version #{cookbook.version} is frozen. Use the 'force' option to override."
    end
  end

  cookbook.freeze_version if params["inflated_object"].frozen_version?

  # ensure that all checksums referred to by the manifest have been uploaded.
  Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
    next unless cookbook.manifest[segment]
    cookbook.manifest[segment].each do |manifest_record|
      checksum = manifest_record[:checksum]
      path = manifest_record[:path]

      begin
        checksum_obj = Chef::Checksum.cdb_load(checksum)
      rescue Chef::Exceptions::CouchDBNotFound => cdbx
        checksum_obj = nil
      end

      raise BadRequest, "Manifest has checksum #{checksum} (path #{path}) but it hasn't yet been uploaded" unless checksum_obj
    end
  end

  raise InternalServerError, "Error saving cookbook" unless cookbook.cdb_save

  display cookbook
end