summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <john@johnkeiser.com>2016-01-13 13:58:43 -0800
committerJohn Keiser <john@johnkeiser.com>2016-01-15 09:37:43 -0800
commit7731eb6e1e93991af1712be35af476063ebcb4ee (patch)
tree8322d80e03e7e7cb0be0b5fb0f18800dbade4f23
parent4444eb70463a0e5f1090007300182a42a909f249 (diff)
downloadchef-7731eb6e1e93991af1712be35af476063ebcb4ee.tar.gz
Add server cookbook artifacts and list_spec
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb3
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/cookbook_artifact_dir.rb34
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb101
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb12
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb2
-rw-r--r--lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb12
-rw-r--r--lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb4
-rw-r--r--spec/integration/knife/list_spec.rb16
8 files changed, 173 insertions, 11 deletions
diff --git a/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb b/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb
index 4a45d218d1..969cea876e 100644
--- a/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb
@@ -21,6 +21,7 @@ require "chef/chef_fs/file_system/chef_server/acls_dir"
require "chef/chef_fs/file_system/base_fs_dir"
require "chef/chef_fs/file_system/chef_server/rest_list_dir"
require "chef/chef_fs/file_system/chef_server/cookbooks_dir"
+require "chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir"
require "chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir"
require "chef/chef_fs/file_system/chef_server/data_bags_dir"
require "chef/chef_fs/file_system/chef_server/nodes_dir"
@@ -158,6 +159,8 @@ class Chef
RestListDir.new("clients", self, nil, Chef::ChefFS::DataHandler::ClientDataHandler.new),
# /containers
RestListDir.new("containers", self, nil, Chef::ChefFS::DataHandler::ContainerDataHandler.new),
+ # /cookbook_artifacts
+ CookbookArtifactsDir.new("cookbook_artifacts", self),
# /groups
RestListDir.new("groups", self, nil, Chef::ChefFS::DataHandler::GroupDataHandler.new),
# /nodes
diff --git a/lib/chef/chef_fs/file_system/chef_server/cookbook_artifact_dir.rb b/lib/chef/chef_fs/file_system/chef_server/cookbook_artifact_dir.rb
new file mode 100644
index 0000000000..ad22b6a64c
--- /dev/null
+++ b/lib/chef/chef_fs/file_system/chef_server/cookbook_artifact_dir.rb
@@ -0,0 +1,34 @@
+#
+# Author:: John Keiser (<jkeiser@opscode.com>)
+# Copyright:: Copyright (c) 2012 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/chef_fs/file_system/chef_server/cookbook_dir'
+
+class Chef
+ module ChefFS
+ module FileSystem
+ module ChefServer
+ class CookbookArtifactDir < CookbookDir
+ def initialize(name, parent, options = {})
+ super(name, parent)
+ @cookbook_name, dash, @version = name.rpartition('-')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb b/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb
new file mode 100644
index 0000000000..adc7003013
--- /dev/null
+++ b/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb
@@ -0,0 +1,101 @@
+#
+# Author:: John Keiser (<jkeiser@opscode.com>)
+# Copyright:: Copyright (c) 2012 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/chef_fs/file_system/chef_server/cookbooks_dir'
+require 'chef/chef_fs/file_system/chef_server/cookbook_artifact_dir'
+
+class Chef
+ module ChefFS
+ module FileSystem
+ module ChefServer
+ #
+ # /cookbook_artifacts
+ #
+ # Example children of /cookbook_artifacts:
+ #
+ # - apache2-ab234098245908ddf324a
+ # - apache2-295387a9823745feff239
+ # - mysql-1a2b9e1298734dfe90444
+ #
+ class CookbookArtifactsDir < CookbooksDir
+
+ def make_child_entry(name)
+ result = @children.select { |child| child.name == name }.first if @children
+ result || CookbookArtifactDir.new(name, self)
+ end
+
+ def children
+ @children ||= begin
+ result = []
+ root.get_json("#{api_path}/?num_versions=all").each_pair do |cookbook_name, cookbooks|
+ cookbooks['versions'].each do |cookbook_version|
+ result << CookbookArtifactDir.new("#{cookbook_name}-#{cookbook_version['identifier']}", self)
+ end
+ end
+ result.sort_by(&:name)
+ end
+ end
+
+ # Knife currently does not understand versioned cookbooks
+ # Cookbook Version uploader also requires a lot of refactoring
+ # to make this work. So instead, we make a temporary cookbook
+ # symlinking back to real cookbook, and upload the proxy.
+ def upload_cookbook(other, options)
+ cookbook_name = Chef::ChefFS::FileSystem::Repository::ChefRepositoryFileSystemCookbookDir.canonical_cookbook_name(other.name)
+
+ Dir.mktmpdir do |temp_cookbooks_path|
+ proxy_cookbook_path = "#{temp_cookbooks_path}/#{cookbook_name}"
+
+ # Make a symlink
+ file_class.symlink other.file_path, proxy_cookbook_path
+
+ # Instantiate a proxy loader using the temporary symlink
+ proxy_loader = Chef::Cookbook::CookbookVersionLoader.new(proxy_cookbook_path, other.parent.chefignore)
+ proxy_loader.load_cookbooks
+
+ cookbook_to_upload = proxy_loader.cookbook_version
+ cookbook_to_upload.freeze_version if options[:freeze]
+
+ # Instantiate a new uploader based on the proxy loader
+ uploader = Chef::CookbookUploader.new(cookbook_to_upload, :force => options[:force], :rest => root.chef_rest)
+
+ with_actual_cookbooks_dir(temp_cookbooks_path) do
+ uploader.upload_cookbooks
+ end
+
+ #
+ # When the temporary directory is being deleted on
+ # windows, the contents of the symlink under that
+ # directory is also deleted. So explicitly remove
+ # the symlink without removing the original contents if we
+ # are running on windows
+ #
+ if Chef::Platform.windows?
+ Dir.rmdir proxy_cookbook_path
+ end
+ end
+ end
+
+ def can_have_child?(name, is_dir)
+ is_dir && name.include?('-')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb b/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb
index 660cc95734..ce74ac1a5c 100644
--- a/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb
@@ -29,15 +29,13 @@ class Chef
module ChefFS
module FileSystem
module ChefServer
- # cookbooks/
+ #
+ # /cookbooks
+ #
+ # Example children:
# apache2/
# mysql/
- # cookbook_artifacts/
- # apache2/
- # 1.0.0/
- # 1.0.1/
- # mysql/
- # 2.0.5/
+ #
class CookbooksDir < RestListDir
include Chef::Mixin::FileClass
diff --git a/lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb b/lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb
index ddc3e7a049..0ffd156577 100644
--- a/lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb
@@ -16,7 +16,7 @@
# limitations under the License.
#
-require "chef/chef_fs/file_system/chef_server/versioned_cookbook_dir"
+require "chef/chef_fs/file_system/chef_server/cookbook_dir"
class Chef
module ChefFS
diff --git a/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb b/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb
index c22723d1e2..6a987bd233 100644
--- a/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb
@@ -23,14 +23,21 @@ class Chef
module ChefFS
module FileSystem
module ChefServer
- # /cookbooks
#
- # Its children look like:
+ # /cookbooks or /cookbook_artifacts
+ #
+ # Example children of /cookbooks:
#
# - apache2-1.0.0
# - apache2-1.0.1
# - mysql-2.0.5
#
+ # Example children of /cookbook_artifacts:
+ #
+ # - apache2-ab234098245908ddf324a
+ # - apache2-295387a9823745feff239
+ # - mysql-1a2b9e1298734dfe90444
+ #
class VersionedCookbooksDir < CookbooksDir
def make_child_entry(name)
@@ -43,6 +50,7 @@ class Chef
result = []
root.get_json("#{api_path}/?num_versions=all").each_pair do |cookbook_name, cookbooks|
cookbooks["versions"].each do |cookbook_version|
+ puts cookbook_version
result << VersionedCookbookDir.new("#{cookbook_name}-#{cookbook_version['version']}", self)
end
end
diff --git a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb
index 6cd079120f..2add4072ea 100644
--- a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb
+++ b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb
@@ -162,12 +162,14 @@ class Chef
return NonexistentFSObject.new(name, self)
end
case name
- when "cookbooks", "cookbook_artifacts"
+ when "cookbooks"
if versioned_cookbooks
dirs = paths.map { |path| ChefRepositoryFileSystemVersionedCookbooksDir.new(name, self, path) }
else
dirs = paths.map { |path| ChefRepositoryFileSystemCookbooksDir.new(name, self, path) }
end
+ when 'cookbook_artifacts'
+ dirs = paths.map { |path| ChefRepositoryFileSystemVersionedCookbooksDir.new(name, self, path) }
when "data_bags"
dirs = paths.map { |path| ChefRepositoryFileSystemDataBagsDir.new(name, self, path) }
when "acls"
diff --git a/spec/integration/knife/list_spec.rb b/spec/integration/knife/list_spec.rb
index 32f5bb43f8..544842fe94 100644
--- a/spec/integration/knife/list_spec.rb
+++ b/spec/integration/knife/list_spec.rb
@@ -661,6 +661,7 @@ EOM
/acls
/clients
/containers
+/cookbook_artifacts
/cookbooks
/data_bags
/environments
@@ -681,6 +682,7 @@ EOM
acls
clients
containers
+cookbook_artifacts
cookbooks
data_bags
environments
@@ -753,6 +755,8 @@ policies.json
roles.json
sandboxes.json
+/cookbook_artifacts:
+
/cookbooks:
/data_bags:
@@ -783,6 +787,7 @@ EOM
acls
clients
containers
+cookbook_artifacts
cookbooks
data_bags
environments
@@ -855,6 +860,8 @@ policies.json
roles.json
sandboxes.json
+/cookbook_artifacts:
+
/cookbooks:
/data_bags:
@@ -886,6 +893,8 @@ EOM
container "container2", {}
cookbook "cookbook1", "1.0.0"
cookbook "cookbook2", "1.0.1", { "recipes" => { "default.rb" => "" } }
+ cookbook_artifact "cookbook_artifact1", "111"
+ cookbook_artifact "cookbook_artifact2", "222", { "recipes" => { "default.rb" => "" } }
data_bag "bag1", { "item1" => {}, "item2" => {} }
data_bag "bag2", { "item1" => {}, "item2" => {} }
environment "environment1", {}
@@ -970,6 +979,13 @@ EOM
/containers/policies.json
/containers/roles.json
/containers/sandboxes.json
+/cookbook_artifacts/
+/cookbook_artifacts/cookbook_artifact1-111/
+/cookbook_artifacts/cookbook_artifact1-111/metadata.rb
+/cookbook_artifacts/cookbook_artifact2-222/
+/cookbook_artifacts/cookbook_artifact2-222/metadata.rb
+/cookbook_artifacts/cookbook_artifact2-222/recipes/
+/cookbook_artifacts/cookbook_artifact2-222/recipes/default.rb
/cookbooks/
/cookbooks/cookbook1/
/cookbooks/cookbook1/metadata.rb