Revert "Revert "Merge branch 'docker_vuln'""

This reverts commit 50a8a91c71.
This commit is contained in:
James Barnett 2017-07-12 18:15:48 -05:00
parent c283cc68fd
commit 126949ce19
No known key found for this signature in database
GPG Key ID: 647983861A4EC5EA
193 changed files with 18194 additions and 2 deletions

4
Vagrantfile vendored
View File

@ -48,7 +48,7 @@ Vagrant.configure("2") do |config|
chef.json = { 'metasploitable' => {
# Customizations here
}
}
}
chef.add_recipe "metasploitable::mysql"
@ -69,4 +69,4 @@ Vagrant.configure("2") do |config|
chef.add_recipe "metasploitable::drupal"
end
end
end
end

View File

@ -0,0 +1,48 @@
# compat_resource Cookbook CHANGELOG
This file is used to list changes made in each version of the compat_resource cookbook.
## 12.16.2 (2016-11-09)
- Sync chef-client changes from Chef 12.16.42
## 12.16.1 (2016-10-20)
- add delayed_action helper
## 12.16.0 (2016-10-19)
- Sync chef-client changes from Chef 12.16.14
## 12.14.7 (2016-09-26)
- Update to 12.14.89 Chef
- Fix autoload by applying fix from #106
## 12.14.6 (2016-09-20)
- Update backported codebase to Chef 12.14.77 which brings in yum_repository updates and why-run enabled by default in custom resources
## 12.14.5 (2016-09-19)
- Prevent spamming messages in Chefspec runs for cookbooks that depend on compat_resource
## 12.14.4 (2016-09-19)
- Fix delayed notifications cloning
## 12.14.3 (2016-09-12)
- Fix subscribes notifications
## 12.14.2 (2016-09-09)
- Improve documentation
- keep ChefCompat::Resource defined even if we don't load
## 12.14.1 (2016-09-07)
- add yum_repository resource from Chef 12.14
- Update the minimum chef version in the metadata to 12.1
- Added maintainers files
- suppress constant redef warnings when running chefspec

View File

@ -0,0 +1,2 @@
Please refer to
https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD

View File

@ -0,0 +1,16 @@
<!-- This is a generated file. Please do not edit directly -->
# Maintainers
This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead.
Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead.
# Project Maintainer
* [Lamont Granquist](https://github.com/lamont-granquist)
# Maintainers
* [Jennifer Davis](https://github.com/sigje)
* [Tim Smith](https://github.com/tas50)
* [Thom May](https://github.com/thommay)
* [Lamont Granquist](https://github.com/lamont-granquist)

View File

@ -0,0 +1,60 @@
# compat_resource cookbook
[![Build Status](https://travis-ci.org/chef-cookbooks/compat_resource.svg?branch=master)](https://travis-ci.org/chef-cookbooks/compat_resource) [![Cookbook Version](https://img.shields.io/cookbook/v/compat_resource.svg)](https://supermarket.chef.io/cookbooks/compat_resource)
This cookbook backports functionality introduced in the latest chef-client releases to any chef-client from 12.1 onwards. This includes [Custom Resource](https://docs.chef.io/custom_resources.html) functionality, notification improvements, as well as new resources added to core chef. It allows for the usage of these new resources in cookbooks without requiring the very latest Chef client release.
## Backported functionality
- [Custom Resources](https://docs.chef.io/custom_resources.html)
- [apt_repository](https://docs.chef.io/resource_apt_repository.html)
- [apt_update](https://docs.chef.io/resource_apt_update.html)
- [systemd_unit](https://docs.chef.io/resource_systemd_unit.html)
- [yum_repository](https://docs.chef.io/resource_yum_repository.html)
- [:before notifications](https://docs.chef.io/resources.html#timers)
## Requirements
### Platforms
- All platforms supported by Chef
### Chef
- Chef 12.1+
### Cookbooks
- none
## Usage
To use this cookbook, put `depends 'compat_resource'` in the metadata.rb of your cookbook. Once this is done, you can use all the new custom resource features to define resources. It Just Works.
## Custom Resources?
Curious about how to use custom resources?
- Docs: <https://docs.chef.io/custom_resources.html>
- Slides: <https://docs.chef.io/decks/custom_resources.html>
## License & Authors
- Author:: Lamont Granquist ([lamont@chef.io](mailto:lamont@chef.io))
- Author:: John Keiser ([jkeiser@chef.io](mailto:jkeiser@chef.io))
```text
Copyright:: 2015-2016 Chef Software, Inc.
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.
```

View File

@ -0,0 +1,29 @@
module ChefCompat
module CopiedFromChef
def self.extend_chef_module(chef_module, target)
target.instance_eval do
include chef_module
@chef_module = chef_module
def self.method_missing(name, *args, &block)
@chef_module.send(name, *args, &block)
end
def self.const_missing(name)
@chef_module.const_get(name)
end
end
end
# This patch to CopiedFromChef's ActionClass is necessary for the include to work
require 'chef/resource'
class Chef < ::Chef
class Resource < ::Chef::Resource
module ActionClass
def self.use_inline_resources
end
def self.include_resource_dsl(include_resource_dsl)
end
end
end
end
end
end

View File

@ -0,0 +1,47 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/constants'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: John Keiser <jkeiser@chef.io>
# Copyright:: Copyright 2015-2016, Chef Software 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.
class Chef < (defined?(::Chef) ? ::Chef : Object)
NOT_PASSED = Object.new
def NOT_PASSED.to_s
"NOT_PASSED"
end
def NOT_PASSED.inspect
to_s
end
NOT_PASSED.freeze
end
end
end
end

View File

@ -0,0 +1,40 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/delayed_evaluator'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: John Keiser <jkeiser@chef.io>
# Copyright:: Copyright 2015-2016, Chef Software 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.
class Chef < (defined?(::Chef) ? ::Chef : Object)
class DelayedEvaluator < (defined?(::Chef::DelayedEvaluator) ? ::Chef::DelayedEvaluator : Proc)
end
end
end
end
end

View File

@ -0,0 +1,73 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/dsl/core'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#--
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
# Copyright:: Copyright 2008-2016 Chef Software, 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_compat/copied_from_chef/chef/dsl/declare_resource"
require "chef_compat/copied_from_chef/chef/dsl/universal"
require "chef_compat/copied_from_chef/chef/mixin/notifying_block"
require "chef_compat/copied_from_chef/chef/mixin/lazy_module_include"
class Chef < (defined?(::Chef) ? ::Chef : Object)
module DSL
CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL)
# Part of a family of DSL mixins.
#
# Chef::DSL::Recipe mixes into Recipes and LWRP Providers.
# - this does not target core chef resources and providers.
# - this is restricted to recipe/resource/provider context where a resource collection exists.
# - cookbook authors should typically include modules into here.
#
# Chef::DSL::Core mixes into Recipes, LWRP Providers and Core Providers
# - this adds cores providers on top of the Recipe DSL.
# - this is restricted to recipe/resource/provider context where a resource collection exists.
# - core chef authors should typically include modules into here.
#
# Chef::DSL::Universal mixes into Recipes, LWRP Resources+Providers, Core Resources+Providers, and Attributes files.
# - this adds resources and attributes files.
# - do not add helpers which manipulate the resource collection.
# - this is for general-purpose stuff that is useful nearly everywhere.
# - it also pollutes the namespace of nearly every context, watch out.
#
module Core
CopiedFromChef.extend_chef_module(::Chef::DSL::Core, self) if defined?(::Chef::DSL::Core)
include Chef::DSL::Universal
include Chef::DSL::DeclareResource
include Chef::Mixin::NotifyingBlock
extend Chef::Mixin::LazyModuleInclude
end
end
end
end
end
end

View File

@ -0,0 +1,315 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/dsl/declare_resource'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#--
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters
# Copyright:: Copyright 2008-2016 Chef Software, 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.
#
class Chef < (defined?(::Chef) ? ::Chef : Object)
module DSL
CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL)
module DeclareResource
CopiedFromChef.extend_chef_module(::Chef::DSL::DeclareResource, self) if defined?(::Chef::DSL::DeclareResource)
# Helper for switching run_contexts. Allows for using :parent or :root in place of
# passing the run_context. Executes the block in the run_context. Returns the return
# value of the passed block.
#
# @param rc [Chef::RunContext,Symbol] Either :root, :parent or a Chef::RunContext
#
# @return return value of the block
#
# @example
# # creates/returns a 'service[foo]' resource in the root run_context
# resource = with_run_context(:root)
# edit_resource(:service, "foo") do
# action :nothing
# end
# end
#
def with_run_context(rc)
raise ArgumentError, "with_run_context is useless without a block" unless block_given?
old_run_context = @run_context
@run_context =
case rc
when Chef::RunContext
rc
when :root
run_context.root_run_context
when :parent
run_context.parent_run_context
else
raise ArgumentError, "bad argument to run_context helper, must be :root, :parent, or a Chef::RunContext"
end
yield
ensure
@run_context = old_run_context
end
# Lookup a resource in the resource collection by name and delete it. This
# will raise Chef::Exceptions::ResourceNotFound if the resource is not found.
#
# @param type [Symbol] The type of resource (e.g. `:file` or `:package`)
# @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2')
# @param run_context [Chef::RunContext] the run_context of the resource collection to operate on
#
# @return [Chef::Resource] The resource
#
# @example
# delete_resource!(:template, '/x/y.txy')
#
def delete_resource!(type, name, run_context: self.run_context)
run_context.resource_collection.delete("#{type}[#{name}]").tap do |resource|
# Purge any pending notifications too. This will not raise an exception
# if there are no notifications.
if resource
run_context.before_notification_collection.delete(resource.declared_key)
run_context.immediate_notification_collection.delete(resource.declared_key)
run_context.delayed_notification_collection.delete(resource.declared_key)
end
end
end
# Lookup a resource in the resource collection by name and delete it. Returns
# nil if the resource is not found and should not fail.
#
# @param type [Symbol] The type of resource (e.g. `:file` or `:package`)
# @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2')
# @param run_context [Chef::RunContext] the run_context of the resource collection to operate on
#
# @return [Chef::Resource] The resource
#
# @example
# delete_resource(:template, '/x/y.txy')
#
def delete_resource(type, name, run_context: self.run_context)
delete_resource!(type, name, run_context: run_context)
rescue Chef::Exceptions::ResourceNotFound
nil
end
# Lookup a resource in the resource collection by name and edit the resource. If the resource is not
# found this will raise Chef::Exceptions::ResourceNotFound. This is the correct API to use for
# "chef_rewind" functionality.
#
# @param type [Symbol] The type of resource (e.g. `:file` or `:package`)
# @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2')
# @param run_context [Chef::RunContext] the run_context of the resource collection to operate on
# @param resource_attrs_block A block that lets you set attributes of the
# resource (it is instance_eval'd on the resource instance).
#
# @return [Chef::Resource] The updated resource
#
# @example
# edit_resource!(:template, '/x/y.txy') do
# cookbook_name: cookbook_name
# end
#
def edit_resource!(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block)
resource = find_resource!(type, name, run_context: run_context)
if resource_attrs_block
if defined?(new_resource)
resource.instance_exec(new_resource, &resource_attrs_block)
else
resource.instance_exec(&resource_attrs_block)
end
end
resource
end
# Lookup a resource in the resource collection by name. If it exists,
# return it. If it does not exist, create it. This is a useful function
# for accumulator patterns. In CRUD terminology this is an "upsert" operation and is
# used to assert that the resource must exist with the specified properties.
#
# @param type [Symbol] The type of resource (e.g. `:file` or `:package`)
# @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2')
# @param created_at [String] The caller of the resource. Use `caller[0]`
# to get the caller of your function. Defaults to the caller of this
# function.
# @param run_context [Chef::RunContext] the run_context of the resource collection to operate on
# @param resource_attrs_block A block that lets you set attributes of the
# resource (it is instance_eval'd on the resource instance).
#
# @return [Chef::Resource] The updated or created resource
#
# @example
# resource = edit_resource(:template, '/x/y.txy') do
# source "y.txy.erb"
# variables {}
# end
# resource.variables.merge!({ home: "/home/klowns" })
#
def edit_resource(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block)
edit_resource!(type, name, created_at, run_context: run_context, &resource_attrs_block)
rescue Chef::Exceptions::ResourceNotFound
declare_resource(type, name, created_at, run_context: run_context, &resource_attrs_block)
end
# Lookup a resource in the resource collection by name. If the resource is not
# found this will raise Chef::Exceptions::ResourceNotFound. This API is identical to the
# resources() call and while it is a synonym it is not intended to deprecate that call.
#
# @param type [Symbol] The type of resource (e.g. `:file` or `:package`)
# @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2')
# @param run_context [Chef::RunContext] the run_context of the resource collection to operate on
#
# @return [Chef::Resource] The updated resource
#
# @example
# resource = find_resource!(:template, '/x/y.txy')
#
def find_resource!(type, name, run_context: self.run_context)
raise ArgumentError, "find_resource! does not take a block" if block_given?
run_context.resource_collection.find(type => name)
end
# Lookup a resource in the resource collection by name. If the resource is not found
# the will be no exception raised and the call will return nil. If a block is given and
# no resource is found it will create the resource using the block, if the resource is
# found then the block will not be applied. The block version is similar to create_if_missing
#
# @param type [Symbol] The type of resource (e.g. `:file` or `:package`)
# @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2')
# @param run_context [Chef::RunContext] the run_context of the resource collection to operate on
#
# @return [Chef::Resource] The updated resource
#
# @example
# if ( find_resource(:template, '/x/y.txy') )
# # do something
# else
# # don't worry about the error
# end
#
# @example
# # this API can be used to return a resource from an outer run context, and will only create
# # an action :nothing service if one does not already exist.
# resource = with_run_context(:root) do
# find_resource(:service, 'whatever') do
# action :nothing
# end
# end
#
def find_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block)
find_resource!(type, name, run_context: run_context)
rescue Chef::Exceptions::ResourceNotFound
if resource_attrs_block
declare_resource(type, name, created_at, run_context: run_context, &resource_attrs_block)
end # returns nil otherwise
end
# Instantiates a resource (via #build_resource), then adds it to the
# resource collection. Note that resource classes are looked up directly,
# so this will create the resource you intended even if the method name
# corresponding to that resource has been overridden.
#
# @param type [Symbol] The type of resource (e.g. `:file` or `:package`)
# @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2')
# @param created_at [String] The caller of the resource. Use `caller[0]`
# to get the caller of your function. Defaults to the caller of this
# function.
# @param run_context [Chef::RunContext] the run_context of the resource collection to operate on
# @param resource_attrs_block A block that lets you set attributes of the
# resource (it is instance_eval'd on the resource instance).
#
# @return [Chef::Resource] The new resource.
#
# @example
# declare_resource(:file, '/x/y.txy', caller[0]) do
# action :delete
# end
# # Equivalent to
# file '/x/y.txt' do
# action :delete
# end
#
def declare_resource(type, name, created_at = nil, run_context: self.run_context, create_if_missing: false, &resource_attrs_block)
created_at ||= caller[0]
if create_if_missing
Chef::Log.deprecation "build_resource with a create_if_missing flag is deprecated, use edit_resource instead"
# midly goofy since we call edit_resource only to re-call ourselves, but that's why its deprecated...
return edit_resource(type, name, created_at, run_context: run_context, &resource_attrs_block)
end
resource = build_resource(type, name, created_at, &resource_attrs_block)
run_context.resource_collection.insert(resource, resource_type: type, instance_name: name)
resource
end
# Instantiate a resource of the given +type+ with the given +name+ and
# attributes as given in the +resource_attrs_block+.
#
# The resource is NOT added to the resource collection.
#
# @param type [Symbol] The type of resource (e.g. `:file` or `:package`)
# @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2')
# @param created_at [String] The caller of the resource. Use `caller[0]`
# to get the caller of your function. Defaults to the caller of this
# function.
# @param run_context [Chef::RunContext] the run_context of the resource collection to operate on
# @param resource_attrs_block A block that lets you set attributes of the
# resource (it is instance_eval'd on the resource instance).
#
# @return [Chef::Resource] The new resource.
#
# @example
# build_resource(:file, '/x/y.txy', caller[0]) do
# action :delete
# end
#
def build_resource(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block)
created_at ||= caller[0]
# this needs to be lazy in order to avoid circular dependencies since ResourceBuilder
# will requires the entire provider+resolver universe
require "chef_compat/copied_from_chef/chef/resource_builder" unless defined?(Chef::ResourceBuilder)
Chef::ResourceBuilder.new(
type: type,
name: name,
created_at: created_at,
params: @params,
run_context: run_context,
cookbook_name: cookbook_name,
recipe_name: recipe_name,
enclosing_provider: self.is_a?(Chef::Provider) ? self : nil
).build(&resource_attrs_block)
end
end
end
end
end
end
end

View File

@ -0,0 +1,292 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/dsl/platform_introspection'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Adam Jacob (<adam@chef.io>)
# Copyright:: Copyright 2008-2016, Chef Software 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.
#
class Chef < (defined?(::Chef) ? ::Chef : Object)
module DSL
CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL)
# == Chef::DSL::PlatformIntrospection
# Provides the DSL for platform-dependent switch logic, such as
# #value_for_platform.
module PlatformIntrospection
CopiedFromChef.extend_chef_module(::Chef::DSL::PlatformIntrospection, self) if defined?(::Chef::DSL::PlatformIntrospection)
# Implementation class for determining platform dependent values
class PlatformDependentValue < (defined?(::Chef::DSL::PlatformIntrospection::PlatformDependentValue) ? ::Chef::DSL::PlatformIntrospection::PlatformDependentValue : Object)
# Create a platform dependent value object.
# === Arguments
# platform_hash (Hash) a hash of the same structure as Chef::Platform,
# like this:
# {
# :debian => {:default => 'the value for all debian'}
# [:centos, :redhat, :fedora] => {:default => "value for all EL variants"}
# :ubuntu => { :default => "default for ubuntu", '10.04' => "value for 10.04 only"},
# :default => "the default when nothing else matches"
# }
# * platforms can be specified as Symbols or Strings
# * multiple platforms can be grouped by using an Array as the key
# * values for platforms need to be Hashes of the form:
# {platform_version => value_for_that_version}
# * the exception to the above is the default value, which is given as
# :default => default_value
def initialize(platform_hash)
super if defined?(::Chef::DSL::PlatformIntrospection::PlatformDependentValue)
@values = {}
platform_hash.each { |platforms, value| set(platforms, value) }
end
def value_for_node(node)
platform, version = node[:platform].to_s, node[:platform_version].to_s
# Check if we match a version constraint via Chef::VersionConstraint::Platform and Chef::Version::Platform
matched_value = match_versions(node)
if @values.key?(platform) && @values[platform].key?(version)
@values[platform][version]
elsif matched_value
matched_value
elsif @values.key?(platform) && @values[platform].key?("default")
@values[platform]["default"]
elsif @values.key?("default")
@values["default"]
else
nil
end
end
private
def match_versions(node)
begin
platform, version = node[:platform].to_s, node[:platform_version].to_s
return nil unless @values.key?(platform)
node_version = Chef::Version::Platform.new(version)
key_matches = []
keys = @values[platform].keys
keys.each do |k|
begin
if Chef::VersionConstraint::Platform.new(k).include?(node_version)
key_matches << k
end
rescue Chef::Exceptions::InvalidVersionConstraint => e
Chef::Log.debug "Caught InvalidVersionConstraint. This means that a key in value_for_platform cannot be interpreted as a Chef::VersionConstraint::Platform."
Chef::Log.debug(e)
end
end
return @values[platform][version] if key_matches.include?(version)
case key_matches.length
when 0
return nil
when 1
return @values[platform][key_matches.first]
else
raise "Multiple matches detected for #{platform} with values #{@values}. The matches are: #{key_matches}"
end
rescue Chef::Exceptions::InvalidCookbookVersion => e
# Lets not break because someone passes a weird string like 'default' :)
Chef::Log.debug(e)
Chef::Log.debug "InvalidCookbookVersion exceptions are common and expected here: the generic constraint matcher attempted to match something which is not a constraint. Moving on to next version or constraint"
return nil
rescue Chef::Exceptions::InvalidPlatformVersion => e
Chef::Log.debug "Caught InvalidPlatformVersion, this means that Chef::Version::Platform does not know how to turn #{node_version} into an x.y.z format"
Chef::Log.debug(e)
return nil
end
end
def set(platforms, value)
if platforms.to_s == "default"
@values["default"] = value
else
assert_valid_platform_values!(platforms, value)
Array(platforms).each { |platform| @values[platform.to_s] = normalize_keys(value) }
value
end
end
def normalize_keys(hash)
hash.inject({}) do |h, key_value|
keys, value = *key_value
Array(keys).each do |key|
h[key.to_s] = value
end
h
end
end
def assert_valid_platform_values!(platforms, value)
unless value.kind_of?(Hash)
msg = "platform dependent values must be specified in the format :platform => {:version => value} "
msg << "you gave a value #{value.inspect} for platform(s) #{platforms}"
raise ArgumentError, msg
end
end
end
# Given a hash similar to the one we use for Platforms, select a value from the hash. Supports
# per platform defaults, along with a single base default. Arrays may be passed as hash keys and
# will be expanded.
#
# === Parameters
# platform_hash:: A platform-style hash.
#
# === Returns
# value:: Whatever the most specific value of the hash is.
def value_for_platform(platform_hash)
PlatformDependentValue.new(platform_hash).value_for_node(node)
end
# Given a list of platforms, returns true if the current recipe is being run on a node with
# that platform, false otherwise.
#
# === Parameters
# args:: A list of platforms. Each platform can be in string or symbol format.
#
# === Returns
# true:: If the current platform is in the list
# false:: If the current platform is not in the list
def platform?(*args)
has_platform = false
args.flatten.each do |platform|
has_platform = true if platform.to_s == node[:platform]
end
has_platform
end
# Implementation class for determining platform family dependent values
class PlatformFamilyDependentValue < (defined?(::Chef::DSL::PlatformIntrospection::PlatformFamilyDependentValue) ? ::Chef::DSL::PlatformIntrospection::PlatformFamilyDependentValue : Object)
# Create a platform family dependent value object.
# === Arguments
# platform_family_hash (Hash) a map of platform families to values.
# like this:
# {
# :rhel => "value for all EL variants"
# :fedora => "value for fedora variants fedora and amazon" ,
# [:fedora, :rhel] => "value for all known redhat variants"
# :debian => "value for debian variants including debian, ubuntu, mint" ,
# :default => "the default when nothing else matches"
# }
# * platform families can be specified as Symbols or Strings
# * multiple platform families can be grouped by using an Array as the key
# * values for platform families can be any object, with no restrictions. Some examples:
# - [:stop, :start]
# - "mysql-devel"
# - { :key => "value" }
def initialize(platform_family_hash)
super if defined?(::Chef::DSL::PlatformIntrospection::PlatformFamilyDependentValue)
@values = {}
@values["default"] = nil
platform_family_hash.each { |platform_families, value| set(platform_families, value) }
end
def value_for_node(node)
if node.key?(:platform_family)
platform_family = node[:platform_family].to_s
if @values.key?(platform_family)
@values[platform_family]
else
@values["default"]
end
else
@values["default"]
end
end
private
def set(platform_family, value)
if platform_family.to_s == "default"
@values["default"] = value
else
Array(platform_family).each { |family| @values[family.to_s] = value }
value
end
end
end
# Given a hash mapping platform families to values, select a value from the hash. Supports a single
# base default if platform family is not in the map. Arrays may be passed as hash keys and will be
# expanded
#
# === Parameters
# platform_family_hash:: A hash in the form { platform_family_name => value }
#
# === Returns
# value:: Whatever the most specific value of the hash is.
def value_for_platform_family(platform_family_hash)
PlatformFamilyDependentValue.new(platform_family_hash).value_for_node(node)
end
# Given a list of platform families, returns true if the current recipe is being run on a
# node within that platform family, false otherwise.
#
# === Parameters
# args:: A list of platform families. Each platform family can be in string or symbol format.
#
# === Returns
# true:: if the current node platform family is in the list.
# false:: if the current node platform family is not in the list.
def platform_family?(*args)
args.flatten.any? do |platform_family|
platform_family.to_s == node[:platform_family]
end
end
# Shamelessly stolen from https://github.com/sethvargo/chef-sugar/blob/master/lib/chef/sugar/docker.rb
# Given a node object, returns whether the node is a docker container.
#
# === Parameters
# node:: [Chef::Node] The node to check.
#
# === Returns
# true:: if the current node is a docker container
# false:: if the current node is not a docker container
def docker?(node = run_context.nil? ? nil : run_context.node)
# Using "File.exist?('/.dockerinit') || File.exist?('/.dockerenv')" makes Travis sad,
# and that makes us sad too.
node && node[:virtualization] && node[:virtualization][:systems] &&
node[:virtualization][:systems][:docker] && node[:virtualization][:systems][:docker] == "guest"
end
end
end
end
# **DEPRECATED**
# This used to be part of chef/mixin/language. Load the file to activate the deprecation code.
end
end
end

View File

@ -0,0 +1,37 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/dsl/recipe'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
require "chef_compat/copied_from_chef/chef/dsl/core"
require "chef_compat/copied_from_chef/chef/mixin/lazy_module_include"
class Chef < (defined?(::Chef) ? ::Chef : Object)
module DSL
CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL)
module Recipe
CopiedFromChef.extend_chef_module(::Chef::DSL::Recipe, self) if defined?(::Chef::DSL::Recipe)
include Chef::DSL::Core
extend Chef::Mixin::LazyModuleInclude
module FullDSL
CopiedFromChef.extend_chef_module(::Chef::DSL::Recipe::FullDSL, self) if defined?(::Chef::DSL::Recipe::FullDSL)
include Chef::DSL::Recipe
extend Chef::Mixin::LazyModuleInclude
end
end
end
end
require "chef_compat/copied_from_chef/chef/resource"
end
end
end

View File

@ -0,0 +1,70 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/dsl/universal'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#--
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
# Copyright:: Copyright 2008-2016 Chef Software, 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_compat/copied_from_chef/chef/dsl/platform_introspection"
require "chef_compat/copied_from_chef/chef/mixin/powershell_out"
class Chef < (defined?(::Chef) ? ::Chef : Object)
module DSL
CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL)
# Part of a family of DSL mixins.
#
# Chef::DSL::Recipe mixes into Recipes and LWRP Providers.
# - this does not target core chef resources and providers.
# - this is restricted to recipe/resource/provider context where a resource collection exists.
# - cookbook authors should typically include modules into here.
#
# Chef::DSL::Core mixes into Recipes, LWRP Providers and Core Providers
# - this adds cores providers on top of the Recipe DSL.
# - this is restricted to recipe/resource/provider context where a resource collection exists.
# - core chef authors should typically include modules into here.
#
# Chef::DSL::Universal mixes into Recipes, LWRP Resources+Providers, Core Resources+Providers, and Attributes files.
# - this adds resources and attributes files.
# - do not add helpers which manipulate the resource collection.
# - this is for general-purpose stuff that is useful nearly everywhere.
# - it also pollutes the namespace of nearly every context, watch out.
#
module Universal
CopiedFromChef.extend_chef_module(::Chef::DSL::Universal, self) if defined?(::Chef::DSL::Universal)
include Chef::DSL::PlatformIntrospection
include Chef::Mixin::PowershellOut
include Chef::Mixin::ShellOut
end
end
end
end
end
end

View File

@ -0,0 +1,98 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/mixin/lazy_module_include'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Copyright:: Copyright 2011-2016, Chef Software 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.
#
class Chef < (defined?(::Chef) ? ::Chef : Object)
module Mixin
CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin)
# If you have:
#
# module A
# extend LazyModuleInclude
# end
#
# module B
# include A
# end
#
# module C
# include B
# end
#
# module Monkeypatches
# def monkey
# puts "monkey!"
# end
# end
#
# A.send(:include, Monkeypatches)
#
# Then B and C and any classes that they're included in will also get the #monkey method patched into them.
#
module LazyModuleInclude
CopiedFromChef.extend_chef_module(::Chef::Mixin::LazyModuleInclude, self) if defined?(::Chef::Mixin::LazyModuleInclude)
# Most of the magick is in this hook which creates a closure over the parent class and then builds an
# "infector" module which infects all descendants and which is responsible for updating the list of
# descendants in the parent class.
def included(klass)
super
parent_klass = self
infector = Module.new do
define_method(:included) do |subklass|
super(subklass)
subklass.extend(infector)
parent_klass.descendants.push(subklass)
end
end
klass.extend(infector)
parent_klass.descendants.push(klass)
end
def descendants
@descendants ||= []
end
def include(*classes)
super
classes.each do |klass|
descendants.each do |descendant|
descendant.send(:include, klass)
end
end
end
end
end
end
end
end
end

View File

@ -0,0 +1,74 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/mixin/notifying_block'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#--
# Author:: Lamont Granquist <lamont@chef.io>
# Copyright:: Copyright 2010-2016, Chef Software 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.
class Chef < (defined?(::Chef) ? ::Chef : Object)
module Mixin
CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin)
module NotifyingBlock
CopiedFromChef.extend_chef_module(::Chef::Mixin::NotifyingBlock, self) if defined?(::Chef::Mixin::NotifyingBlock)
def notifying_block(&block)
begin
subcontext = subcontext_block(&block)
Chef::Runner.new(subcontext).converge
ensure
# recipes don't have a new_resource
if respond_to?(:new_resource)
if subcontext && subcontext.resource_collection.any?(&:updated?)
new_resource.updated_by_last_action(true)
end
end
end
end
def subcontext_block(parent_context = nil, &block)
parent_context ||= @run_context
sub_run_context = parent_context.create_child
begin
outer_run_context = @run_context
@run_context = sub_run_context
instance_eval(&block)
ensure
@run_context = outer_run_context
end
sub_run_context
end
end
end
end
end
end
end

View File

@ -0,0 +1,510 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/mixin/params_validate'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Adam Jacob (<adam@chef.io>)
# Copyright:: Copyright 2008-2016, Chef Software 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_compat/copied_from_chef/chef/constants"
require "chef_compat/copied_from_chef/chef/property"
require "chef_compat/copied_from_chef/chef/delayed_evaluator"
class Chef < (defined?(::Chef) ? ::Chef : Object)
module Mixin
CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin)
module ParamsValidate
CopiedFromChef.extend_chef_module(::Chef::Mixin::ParamsValidate, self) if defined?(::Chef::Mixin::ParamsValidate)
# Takes a hash of options, along with a map to validate them. Returns the original
# options hash, plus any changes that might have been made (through things like setting
# default values in the validation map)
#
# For example:
#
# validate({ :one => "neat" }, { :one => { :kind_of => String }})
#
# Would raise an exception if the value of :one above is not a kind_of? string. Valid
# map options are:
#
# @param opts [Hash<Symbol,Object>] Validation opts.
# @option opts [Object,Array] :is An object, or list of
# objects, that must match the value using Ruby's `===` operator
# (`opts[:is].any? { |v| v === value }`). (See #_pv_is.)
# @option opts [Object,Array] :equal_to An object, or list
# of objects, that must be equal to the value using Ruby's `==`
# operator (`opts[:is].any? { |v| v == value }`) (See #_pv_equal_to.)
# @option opts [Regexp,Array<Regexp>] :regex An object, or
# list of objects, that must match the value with `regex.match(value)`.
# (See #_pv_regex)
# @option opts [Class,Array<Class>] :kind_of A class, or
# list of classes, that the value must be an instance of. (See
# #_pv_kind_of.)
# @option opts [Hash<String,Proc>] :callbacks A hash of
# messages -> procs, all of which match the value. The proc must
# return a truthy or falsey value (true means it matches). (See
# #_pv_callbacks.)
# @option opts [Symbol,Array<Symbol>] :respond_to A method
# name, or list of method names, the value must respond to. (See
# #_pv_respond_to.)
# @option opts [Symbol,Array<Symbol>] :cannot_be A property,
# or a list of properties, that the value cannot have (such as `:nil` or
# `:empty`). The method with a questionmark at the end is called on the
# value (e.g. `value.empty?`). If the value does not have this method,
# it is considered valid (i.e. if you don't respond to `empty?` we
# assume you are not empty). (See #_pv_cannot_be.)
# @option opts [Proc] :coerce A proc which will be called to
# transform the user input to canonical form. The value is passed in,
# and the transformed value returned as output. Lazy values will *not*
# be passed to this method until after they are evaluated. Called in the
# context of the resource (meaning you can access other properties).
# (See #_pv_coerce.) (See #_pv_coerce.)
# @option opts [Boolean] :required `true` if this property
# must be present and not `nil`; `false` otherwise. This is checked
# after the resource is fully initialized. (See #_pv_required.)
# @option opts [Boolean] :name_property `true` if this
# property defaults to the same value as `name`. Equivalent to
# `default: lazy { name }`, except that #property_is_set? will
# return `true` if the property is set *or* if `name` is set. (See
# #_pv_name_property.)
# @option opts [Boolean] :name_attribute Same as `name_property`.
# @option opts [Object] :default The value this property
# will return if the user does not set one. If this is `lazy`, it will
# be run in the context of the instance (and able to access other
# properties). (See #_pv_default.)
#
def validate(opts, map)
map = map.validation_options if map.is_a?(Property)
#--
# validate works by taking the keys in the validation map, assuming it's a hash, and
# looking for _pv_:symbol as methods. Assuming it find them, it calls the right
# one.
#++
raise ArgumentError, "Options must be a hash" unless opts.kind_of?(Hash)
raise ArgumentError, "Validation Map must be a hash" unless map.kind_of?(Hash)
map.each do |key, validation|
unless key.kind_of?(Symbol) || key.kind_of?(String)
raise ArgumentError, "Validation map keys must be symbols or strings!"
end
case validation
when true
_pv_required(opts, key)
when false
true
when Hash
validation.each do |check, carg|
check_method = "_pv_#{check}"
if self.respond_to?(check_method, true)
self.send(check_method, opts, key, carg)
else
raise ArgumentError, "Validation map has unknown check: #{check}"
end
end
end
end
opts
end
def lazy(&block)
DelayedEvaluator.new(&block)
end
def set_or_return(symbol, value, validation)
property = SetOrReturnProperty.new(name: symbol, **validation)
property.call(self, value)
end
private
def explicitly_allows_nil?(key, validation)
validation.has_key?(:is) && _pv_is({ key => nil }, key, validation[:is], raise_error: false)
end
# Return the value of a parameter, or nil if it doesn't exist.
def _pv_opts_lookup(opts, key)
if opts.has_key?(key.to_s)
opts[key.to_s]
elsif opts.has_key?(key.to_sym)
opts[key.to_sym]
else
nil
end
end
# Raise an exception if the parameter is not found.
def _pv_required(opts, key, is_required = true, explicitly_allows_nil = false)
if is_required
return true if opts.has_key?(key.to_s) && (explicitly_allows_nil || !opts[key.to_s].nil?)
return true if opts.has_key?(key.to_sym) && (explicitly_allows_nil || !opts[key.to_sym].nil?)
raise Exceptions::ValidationFailed, "Required argument #{key.inspect} is missing!"
end
true
end
#
# List of things values must be equal to.
#
# Uses Ruby's `==` to evaluate (equal_to == value). At least one must
# match for the value to be valid.
#
# `nil` passes this validation automatically.
#
# @return [Array,nil] List of things values must be equal to, or nil if
# equal_to is unspecified.
#
def _pv_equal_to(opts, key, to_be)
value = _pv_opts_lookup(opts, key)
unless value.nil?
to_be = Array(to_be)
to_be.each do |tb|
return true if value == tb
end
raise Exceptions::ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}."
end
end
#
# List of things values must be instances of.
#
# Uses value.kind_of?(kind_of) to evaluate. At least one must match for
# the value to be valid.
#
# `nil` automatically passes this validation.
#
def _pv_kind_of(opts, key, to_be)
value = _pv_opts_lookup(opts, key)
unless value.nil?
to_be = Array(to_be)
to_be.each do |tb|
return true if value.kind_of?(tb)
end
raise Exceptions::ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}."
end
end
#
# List of method names values must respond to.
#
# Uses value.respond_to?(respond_to) to evaluate. At least one must match
# for the value to be valid.
#
def _pv_respond_to(opts, key, method_name_list)
value = _pv_opts_lookup(opts, key)
unless value.nil?
Array(method_name_list).each do |method_name|
unless value.respond_to?(method_name)
raise Exceptions::ValidationFailed, "Option #{key} must have a #{method_name} method!"
end
end
end
end
#
# List of things that must not be true about the value.
#
# Calls `value.<thing>?` All responses must be false for the value to be
# valid.
# Values which do not respond to <thing>? are considered valid (because if
# a value doesn't respond to `:readable?`, then it probably isn't
# readable.)
#
# @example
# ```ruby
# property :x, cannot_be: [ :nil, :empty ]
# x [ 1, 2 ] #=> valid
# x 1 #=> valid
# x [] #=> invalid
# x nil #=> invalid
# ```
#
def _pv_cannot_be(opts, key, predicate_method_base_name)
value = _pv_opts_lookup(opts, key)
if !value.nil?
Array(predicate_method_base_name).each do |method_name|
predicate_method = :"#{method_name}?"
if value.respond_to?(predicate_method)
if value.send(predicate_method)
raise Exceptions::ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}"
end
end
end
end
end
#
# The default value for a property.
#
# When the property is not assigned, this will be used.
#
# If this is a lazy value, it will either be passed the resource as a value,
# or if the lazy proc does not take parameters, it will be run in the
# context of the instance with instance_eval.
#
# @example
# ```ruby
# property :x, default: 10
# ```
#
# @example
# ```ruby
# property :x
# property :y, default: lazy { x+2 }
# ```
#
# @example
# ```ruby
# property :x
# property :y, default: lazy { |r| r.x+2 }
# ```
#
def _pv_default(opts, key, default_value)
value = _pv_opts_lookup(opts, key)
if value.nil?
default_value = default_value.freeze if !default_value.is_a?(DelayedEvaluator)
opts[key] = default_value
end
end
#
# List of regexes values that must match.
#
# Uses regex.match() to evaluate. At least one must match for the value to
# be valid.
#
# `nil` passes regex validation automatically.
#
# @example
# ```ruby
# property :x, regex: [ /abc/, /xyz/ ]
# ```
#
def _pv_regex(opts, key, regex)
value = _pv_opts_lookup(opts, key)
if !value.nil?
Array(regex).flatten.each do |r|
return true if r.match(value.to_s)
end
raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}"
end
end
#
# List of procs we pass the value to.
#
# All procs must return true for the value to be valid. If any procs do
# not return true, the key will be used for the message: `"Property x's
# value :y <message>"`.
#
# @example
# ```ruby
# property :x, callbacks: { "is bigger than 10" => proc { |v| v <= 10 }, "is not awesome" => proc { |v| !v.awesome }}
# ```
#
def _pv_callbacks(opts, key, callbacks)
raise ArgumentError, "Callback list must be a hash!" unless callbacks.kind_of?(Hash)
value = _pv_opts_lookup(opts, key)
if !value.nil?
callbacks.each do |message, zeproc|
unless zeproc.call(value)
raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} #{message}!"
end
end
end
end
#
# Allows a parameter to default to the value of the resource name.
#
# @example
# ```ruby
# property :x, name_property: true
# ```
#
def _pv_name_property(opts, key, is_name_property = true)
if is_name_property
if opts[key].nil?
raise CannotValidateStaticallyError, "name_property cannot be evaluated without a resource." if self == Chef::Mixin::ParamsValidate
opts[key] = self.instance_variable_get(:"@name")
end
end
end
alias :_pv_name_attribute :_pv_name_property
#
# List of valid things values can be.
#
# Uses Ruby's `===` to evaluate (is === value). At least one must match
# for the value to be valid.
#
# If a proc is passed, it is instance_eval'd in the resource, passed the
# value, and must return a truthy or falsey value.
#
# @example Class
# ```ruby
# property :x, String
# x 'valid' #=> valid
# x 1 #=> invalid
# x nil #=> invalid
#
# @example Value
# ```ruby
# property :x, [ :a, :b, :c, nil ]
# x :a #=> valid
# x nil #=> valid
# ```
#
# @example Regex
# ```ruby
# property :x, /bar/
# x 'foobar' #=> valid
# x 'foo' #=> invalid
# x nil #=> invalid
# ```
#
# @example Proc
# ```ruby
# property :x, proc { |x| x > y }
# property :y, default: 2
# x 3 #=> valid
# x 1 #=> invalid
# ```
#
# @example Property
# ```ruby
# type = Property.new(is: String)
# property :x, type
# x 'foo' #=> valid
# x 1 #=> invalid
# x nil #=> invalid
# ```
#
# @example RSpec Matcher
# ```ruby
# include RSpec::Matchers
# property :x, a_string_matching /bar/
# x 'foobar' #=> valid
# x 'foo' #=> invalid
# x nil #=> invalid
# ```
#
def _pv_is(opts, key, to_be, raise_error: true)
return true if !opts.has_key?(key.to_s) && !opts.has_key?(key.to_sym)
value = _pv_opts_lookup(opts, key)
to_be = [ to_be ].flatten(1)
errors = []
passed = to_be.any? do |tb|
case tb
when Proc
raise CannotValidateStaticallyError, "is: proc { } must be evaluated once for each resource" if self == Chef::Mixin::ParamsValidate
instance_exec(value, &tb)
when Property
begin
validate(opts, { key => tb.validation_options })
true
rescue Exceptions::ValidationFailed
# re-raise immediately if there is only one "is" so we get a better stack
raise if to_be.size == 1
errors << $!
false
end
else
tb === value
end
end
if passed
true
else
message = "Property #{key} must be one of: #{to_be.map { |v| v.inspect }.join(", ")}! You passed #{value.inspect}."
unless errors.empty?
message << " Errors:\n#{errors.map { |m| "- #{m}" }.join("\n")}"
end
raise Exceptions::ValidationFailed, message
end
end
#
# Method to mess with a value before it is validated and stored.
#
# Allows you to transform values into a canonical form that is easy to
# work with.
#
# This is passed the value to transform, and is run in the context of the
# instance (so it has access to other resource properties). It must return
# the value that will be stored in the instance.
#
# @example
# ```ruby
# property :x, Integer, coerce: { |v| v.to_i }
# ```
#
def _pv_coerce(opts, key, coercer)
if opts.has_key?(key.to_s)
raise CannotValidateStaticallyError, "coerce must be evaluated for each resource." if self == Chef::Mixin::ParamsValidate
opts[key.to_s] = instance_exec(opts[key], &coercer)
elsif opts.has_key?(key.to_sym)
raise CannotValidateStaticallyError, "coerce must be evaluated for each resource." if self == Chef::Mixin::ParamsValidate
opts[key.to_sym] = instance_exec(opts[key], &coercer)
end
end
# We allow Chef::Mixin::ParamsValidate.validate(), but we will raise an
# error if you try to do anything requiring there to be an actual resource.
# This way, you can statically validate things if you have constant validation
# (which is the norm).
extend self
# Used by #set_or_return to avoid emitting a deprecation warning for
# "value nil" and to keep default stickiness working exactly the same
# @api private
class SetOrReturnProperty < (defined?(::Chef::Mixin::ParamsValidate::SetOrReturnProperty) ? ::Chef::Mixin::ParamsValidate::SetOrReturnProperty : Chef::Property)
def get(resource, nil_set: false)
value = super
# All values are sticky, frozen or not
if !is_set?(resource)
set_value(resource, value)
end
value
end
def call(resource, value = NOT_PASSED)
# setting to nil does a get
if value.nil? && !explicitly_accepts_nil?(resource)
get(resource, nil_set: true)
else
super
end
end
end
end
end
end
end
end
end

View File

@ -0,0 +1,117 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/mixin/powershell_out'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#--
# Copyright:: Copyright 2015-2016, Chef Software, 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.
class Chef < (defined?(::Chef) ? ::Chef : Object)
module Mixin
CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin)
module PowershellOut
CopiedFromChef.extend_chef_module(::Chef::Mixin::PowershellOut, self) if defined?(::Chef::Mixin::PowershellOut)
include Chef::Mixin::ShellOut
include Chef::Mixin::WindowsArchitectureHelper
# Run a command under powershell with the same API as shell_out. The
# options hash is extended to take an "architecture" flag which
# can be set to :i386 or :x86_64 to force the windows architecture.
#
# @param script [String] script to run
# @param options [Hash] options hash
# @return [Mixlib::Shellout] mixlib-shellout object
def powershell_out(*command_args)
script = command_args.first
options = command_args.last.is_a?(Hash) ? command_args.last : nil
run_command_with_os_architecture(script, options)
end
# Run a command under powershell with the same API as shell_out!
# (raises exceptions on errors)
#
# @param script [String] script to run
# @param options [Hash] options hash
# @return [Mixlib::Shellout] mixlib-shellout object
def powershell_out!(*command_args)
cmd = powershell_out(*command_args)
cmd.error!
cmd
end
private
# Helper function to run shell_out and wrap it with the correct
# flags to possibly disable WOW64 redirection (which we often need
# because chef-client runs as a 32-bit app on 64-bit windows).
#
# @param script [String] script to run
# @param options [Hash] options hash
# @return [Mixlib::Shellout] mixlib-shellout object
def run_command_with_os_architecture(script, options)
options ||= {}
options = options.dup
arch = options.delete(:architecture)
with_os_architecture(nil, architecture: arch) do
shell_out(
build_powershell_command(script),
options
)
end
end
# Helper to build a powershell command around the script to run.
#
# @param script [String] script to run
# @retrurn [String] powershell command to execute
def build_powershell_command(script)
flags = [
# Hides the copyright banner at startup.
"-NoLogo",
# Does not present an interactive prompt to the user.
"-NonInteractive",
# Does not load the Windows PowerShell profile.
"-NoProfile",
# always set the ExecutionPolicy flag
# see http://technet.microsoft.com/en-us/library/ee176961.aspx
"-ExecutionPolicy Unrestricted",
# Powershell will hang if STDIN is redirected
# http://connect.microsoft.com/PowerShell/feedback/details/572313/powershell-exe-can-hang-if-stdin-is-redirected
"-InputFormat None",
]
"powershell.exe #{flags.join(' ')} -Command \"#{script.gsub('"', '\"')}\""
end
end
end
end
end
end
end

View File

@ -0,0 +1,328 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/mixin/properties'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
require "chef_compat/copied_from_chef/chef/delayed_evaluator"
require "chef_compat/copied_from_chef/chef/mixin/params_validate"
require "chef_compat/copied_from_chef/chef/property"
class Chef < (defined?(::Chef) ? ::Chef : Object)
module Mixin
CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin)
module Properties
CopiedFromChef.extend_chef_module(::Chef::Mixin::Properties, self) if defined?(::Chef::Mixin::Properties)
module ClassMethods
CopiedFromChef.extend_chef_module(::Chef::Mixin::Properties::ClassMethods, self) if defined?(::Chef::Mixin::Properties::ClassMethods)
#
# The list of properties defined on this resource.
#
# Everything defined with `property` is in this list.
#
# @param include_superclass [Boolean] `true` to include properties defined
# on superclasses; `false` or `nil` to return the list of properties
# directly on this class.
#
# @return [Hash<Symbol,Property>] The list of property names and types.
#
def properties(include_superclass = true)
if include_superclass
result = {}
ancestors.reverse_each { |c| result.merge!(c.properties(false)) if c.respond_to?(:properties) }
result
else
@properties ||= {}
end
end
#
# Create a property on this resource class.
#
# If a superclass has this property, or if this property has already been
# defined by this resource, this will *override* the previous value.
#
# @param name [Symbol] The name of the property.
# @param type [Object,Array<Object>] The type(s) of this property.
# If present, this is prepended to the `is` validation option.
# @param options [Hash<Symbol,Object>] Validation options.
# @option options [Object,Array] :is An object, or list of
# objects, that must match the value using Ruby's `===` operator
# (`options[:is].any? { |v| v === value }`).
# @option options [Object,Array] :equal_to An object, or list
# of objects, that must be equal to the value using Ruby's `==`
# operator (`options[:is].any? { |v| v == value }`)
# @option options [Regexp,Array<Regexp>] :regex An object, or
# list of objects, that must match the value with `regex.match(value)`.
# @option options [Class,Array<Class>] :kind_of A class, or
# list of classes, that the value must be an instance of.
# @option options [Hash<String,Proc>] :callbacks A hash of
# messages -> procs, all of which match the value. The proc must
# return a truthy or falsey value (true means it matches).
# @option options [Symbol,Array<Symbol>] :respond_to A method
# name, or list of method names, the value must respond to.
# @option options [Symbol,Array<Symbol>] :cannot_be A property,
# or a list of properties, that the value cannot have (such as `:nil` or
# `:empty`). The method with a questionmark at the end is called on the
# value (e.g. `value.empty?`). If the value does not have this method,
# it is considered valid (i.e. if you don't respond to `empty?` we
# assume you are not empty).
# @option options [Proc] :coerce A proc which will be called to
# transform the user input to canonical form. The value is passed in,
# and the transformed value returned as output. Lazy values will *not*
# be passed to this method until after they are evaluated. Called in the
# context of the resource (meaning you can access other properties).
# @option options [Boolean] :required `true` if this property
# must be present; `false` otherwise. This is checked after the resource
# is fully initialized.
# @option options [Boolean] :name_property `true` if this
# property defaults to the same value as `name`. Equivalent to
# `default: lazy { name }`, except that #property_is_set? will
# return `true` if the property is set *or* if `name` is set.
# @option options [Boolean] :name_attribute Same as `name_property`.
# @option options [Object] :default The value this property
# will return if the user does not set one. If this is `lazy`, it will
# be run in the context of the instance (and able to access other
# properties).
# @option options [Boolean] :desired_state `true` if this property is
# part of desired state. Defaults to `true`.
# @option options [Boolean] :identity `true` if this property
# is part of object identity. Defaults to `false`.
# @option options [Boolean] :sensitive `true` if this property could
# contain sensitive information and whose value should be redacted
# in any resource reporting / auditing output. Defaults to `false`.
#
# @example Bare property
# property :x
#
# @example With just a type
# property :x, String
#
# @example With just options
# property :x, default: 'hi'
#
# @example With type and options
# property :x, String, default: 'hi'
#
def property(name, type = NOT_PASSED, **options)
name = name.to_sym
options = options.inject({}) { |memo, (key, value)| memo[key.to_sym] = value; memo }
options[:instance_variable_name] = :"@#{name}" if !options.has_key?(:instance_variable_name)
options[:name] = name
options[:declared_in] = self
if type == NOT_PASSED
# If a type is not passed, the property derives from the
# superclass property (if any)
if properties.has_key?(name)
property = properties[name].derive(**options)
else
property = property_type(**options)
end
# If a Property is specified, derive a new one from that.
elsif type.is_a?(Property) || (type.is_a?(Class) && type <= Property)
property = type.derive(**options)
# If a primitive type was passed, combine it with "is"
else
if options[:is]
options[:is] = ([ type ] + [ options[:is] ]).flatten(1)
else
options[:is] = type
end
property = property_type(**options)
end
local_properties = properties(false)
local_properties[name] = property
property.emit_dsl
end
#
# Create a reusable property type that can be used in multiple properties
# in different resources.
#
# @param options [Hash<Symbol,Object>] Validation options. see #property for
# the list of options.
#
# @example
# property_type(default: 'hi')
#
def property_type(**options)
Property.derive(**options)
end
#
# Create a lazy value for assignment to a default value.
#
# @param block The block to run when the value is retrieved.
#
# @return [Chef::DelayedEvaluator] The lazy value
#
def lazy(&block)
DelayedEvaluator.new(&block)
end
#
# Get or set the list of desired state properties for this resource.
#
# State properties are properties that describe the desired state
# of the system, such as file permissions or ownership.
# In general, state properties are properties that could be populated by
# examining the state of the system (e.g., File.stat can tell you the
# permissions on an existing file). Contrarily, properties that are not
# "state properties" usually modify the way Chef itself behaves, for example
# by providing additional options for a package manager to use when
# installing a package.
#
# This list is used by the Chef client auditing system to extract
# information from resources to describe changes made to the system.
#
# This method is unnecessary when declaring properties with `property`;
# properties are added to state_properties by default, and can be turned off
# with `desired_state: false`.
#
# ```ruby
# property :x # part of desired state
# property :y, desired_state: false # not part of desired state
# ```
#
# @param names [Array<Symbol>] A list of property names to set as desired
# state.
#
# @return [Array<Property>] All properties in desired state.
#
def state_properties(*names)
if !names.empty?
names = names.map { |name| name.to_sym }.uniq
local_properties = properties(false)
# Add new properties to the list.
names.each do |name|
property = properties[name]
if !property
self.property name, instance_variable_name: false, desired_state: true
elsif !property.desired_state?
self.property name, desired_state: true
end
end
# If state_attrs *excludes* something which is currently desired state,
# mark it as desired_state: false.
local_properties.each do |name, property|
if property.desired_state? && !names.include?(name)
self.property name, desired_state: false
end
end
end
properties.values.select { |property| property.desired_state? }
end
#
# Set the identity of this resource to a particular set of properties.
#
# This drives #identity, which returns data that uniquely refers to a given
# resource on the given node (in such a way that it can be correlated
# across Chef runs).
#
# This method is unnecessary when declaring properties with `property`;
# properties can be added to identity during declaration with
# `identity: true`.
#
# ```ruby
# property :x, identity: true # part of identity
# property :y # not part of identity
# ```
#
# If no properties are marked as identity, "name" is considered the identity.
#
# @param names [Array<Symbol>] A list of property names to set as the identity.
#
# @return [Array<Property>] All identity properties.
#
def identity_properties(*names)
if !names.empty?
names = names.map { |name| name.to_sym }
# Add or change properties that are not part of the identity.
names.each do |name|
property = properties[name]
if !property
self.property name, instance_variable_name: false, identity: true
elsif !property.identity?
self.property name, identity: true
end
end
# If identity_properties *excludes* something which is currently part of
# the identity, mark it as identity: false.
properties.each do |name, property|
if property.identity? && !names.include?(name)
self.property name, identity: false
end
end
end
result = properties.values.select { |property| property.identity? }
result = [ properties[:name] ] if result.empty?
result
end
def included(other)
other.extend ClassMethods
end
end
def self.included(other)
other.extend ClassMethods
end
include Chef::Mixin::ParamsValidate
#
# Whether this property has been set (or whether it has a default that has
# been retrieved).
#
# @param name [Symbol] The name of the property.
# @return [Boolean] `true` if the property has been set.
#
def property_is_set?(name)
property = self.class.properties[name.to_sym]
raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property
property.is_set?(self)
end
#
# Clear this property as if it had never been set. It will thereafter return
# the default.
# been retrieved).
#
# @param name [Symbol] The name of the property.
#
def reset_property(name)
property = self.class.properties[name.to_sym]
raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property
property.reset(self)
end
end
end
end
end
end
end

View File

@ -0,0 +1,713 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/property'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: John Keiser <jkeiser@chef.io>
# Copyright:: Copyright 2015-2016, John Keiser.
# 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_compat/copied_from_chef/chef/delayed_evaluator"
class Chef < (defined?(::Chef) ? ::Chef : Object)
#
# Type and validation information for a property on a resource.
#
# A property named "x" manipulates the "@x" instance variable on a
# resource. The *presence* of the variable (`instance_variable_defined?(@x)`)
# tells whether the variable is defined; it may have any actual value,
# constrained only by validation.
#
# Properties may have validation, defaults, and coercion, and have full
# support for lazy values.
#
# @see Chef::Resource.property
# @see Chef::DelayedEvaluator
#
class Property < (defined?(::Chef::Property) ? ::Chef::Property : Object)
#
# Create a reusable property type that can be used in multiple properties
# in different resources.
#
# @param options [Hash<Symbol,Object>] Validation options. See Chef::Resource.property for
# the list of options.
#
# @example
# Property.derive(default: 'hi')
#
def self.derive(**options)
new(**options)
end
#
# Create a new property.
#
# @param options [Hash<Symbol,Object>] Property options, including
# control options here, as well as validation options (see
# Chef::Mixin::ParamsValidate#validate for a description of validation
# options).
# @option options [Symbol] :name The name of this property.
# @option options [Class] :declared_in The class this property comes from.
# @option options [Symbol] :instance_variable_name The instance variable
# tied to this property. Must include a leading `@`. Defaults to `@<name>`.
# `nil` means the property is opaque and not tied to a specific instance
# variable.
# @option options [Boolean] :desired_state `true` if this property is part of desired
# state. Defaults to `true`.
# @option options [Boolean] :identity `true` if this property is part of object
# identity. Defaults to `false`.
# @option options [Boolean] :name_property `true` if this
# property defaults to the same value as `name`. Equivalent to
# `default: lazy { name }`, except that #property_is_set? will
# return `true` if the property is set *or* if `name` is set.
# @option options [Boolean] :nillable `true` opt-in to Chef-13 style behavior where
# attempting to set a nil value will really set a nil value instead of issuing
# a warning and operating like a getter
# @option options [Object] :default The value this property
# will return if the user does not set one. If this is `lazy`, it will
# be run in the context of the instance (and able to access other
# properties) and cached. If not, the value will be frozen with Object#freeze
# to prevent users from modifying it in an instance.
# @option options [Proc] :coerce A proc which will be called to
# transform the user input to canonical form. The value is passed in,
# and the transformed value returned as output. Lazy values will *not*
# be passed to this method until after they are evaluated. Called in the
# context of the resource (meaning you can access other properties).
# @option options [Boolean] :required `true` if this property
# must be present; `false` otherwise. This is checked after the resource
# is fully initialized.
#
def initialize(**options)
super if defined?(::Chef::Property)
options = options.inject({}) { |memo, (key, value)| memo[key.to_sym] = value; memo }
@options = options
options[:name] = options[:name].to_sym if options[:name]
options[:instance_variable_name] = options[:instance_variable_name].to_sym if options[:instance_variable_name]
# Replace name_attribute with name_property
if options.has_key?(:name_attribute)
# If we have both name_attribute and name_property and they differ, raise an error
if options.has_key?(:name_property)
raise ArgumentError, "Cannot specify both name_property and name_attribute together on property #{self}."
end
# replace name_property with name_attribute in place
options = Hash[options.map { |k, v| k == :name_attribute ? [ :name_property, v ] : [ k, v ] }]
@options = options
end
# Only pick the first of :default, :name_property and :name_attribute if
# more than one is specified.
if options.has_key?(:default) && options[:name_property]
if options[:default].nil? || options.keys.index(:name_property) < options.keys.index(:default)
options.delete(:default)
preferred_default = :name_property
else
options.delete(:name_property)
preferred_default = :default
end
Chef.log_deprecation("Cannot specify both default and name_property together on property #{self}. Only one (#{preferred_default}) will be obeyed. In Chef 13, this will become an error. Please remove one or the other from the property.")
end
# Validate the default early, so the user gets a good error message, and
# cache it so we don't do it again if so
begin
# If we can validate it all the way to output, do it.
@stored_default = input_to_stored_value(nil, default, is_default: true)
rescue Chef::Exceptions::CannotValidateStaticallyError
# If the validation is not static (i.e. has procs), we will have to
# coerce and validate the default each time we run
end
end
def to_s
"#{name || "<property type>"}#{declared_in ? " of resource #{declared_in.resource_name}" : ""}"
end
#
# The name of this property.
#
# @return [String]
#
def name
options[:name]
end
#
# The class this property was defined in.
#
# @return [Class]
#
def declared_in
options[:declared_in]
end
#
# The instance variable associated with this property.
#
# Defaults to `@<name>`
#
# @return [Symbol]
#
def instance_variable_name
if options.has_key?(:instance_variable_name)
options[:instance_variable_name]
elsif name
:"@#{name}"
end
end
#
# The raw default value for this resource.
#
# Does not coerce or validate the default. Does not evaluate lazy values.
#
# Defaults to `lazy { name }` if name_property is true; otherwise defaults to
# `nil`
#
def default
return options[:default] if options.has_key?(:default)
return Chef::DelayedEvaluator.new { name } if name_property?
nil
end
#
# Whether this is part of the resource's natural identity or not.
#
# @return [Boolean]
#
def identity?
options[:identity]
end
#
# Whether this is part of desired state or not.
#
# Defaults to true.
#
# @return [Boolean]
#
def desired_state?
return true if !options.has_key?(:desired_state)
options[:desired_state]
end
#
# Whether this is name_property or not.
#
# @return [Boolean]
#
def name_property?
options[:name_property]
end
#
# Whether this property has a default value.
#
# @return [Boolean]
#
def has_default?
options.has_key?(:default) || name_property?
end
#
# Whether this property is required or not.
#
# @return [Boolean]
#
def required?
options[:required]
end
#
# Whether this property is sensitive or not.
#
# Defaults to false.
#
# @return [Boolean]
#
def sensitive?
options.fetch(:sensitive, false)
end
#
# Validation options. (See Chef::Mixin::ParamsValidate#validate.)
#
# @return [Hash<Symbol,Object>]
#
def validation_options
@validation_options ||= options.reject do |k, v|
[:declared_in, :name, :instance_variable_name, :desired_state, :identity, :default, :name_property, :coerce, :required, :nillable, :sensitive].include?(k)
end
end
#
# Handle the property being called.
#
# The base implementation does the property get-or-set:
#
# ```ruby
# resource.myprop # get
# resource.myprop value # set
# ```
#
# Subclasses may implement this with any arguments they want, as long as
# the corresponding DSL calls it correctly.
#
# @param resource [Chef::Resource] The resource to get the property from.
# @param value The value to set (or NOT_PASSED if it is a get).
#
# @return The current value of the property. If it is a `set`, lazy values
# will be returned without running, validating or coercing. If it is a
# `get`, the non-lazy, coerced, validated value will always be returned.
#
def call(resource, value = NOT_PASSED)
if value == NOT_PASSED
return get(resource)
end
if value.nil? && !nillable?
# In Chef 12, value(nil) does a *get* instead of a set, so we
# warn if the value would have been changed. In Chef 13, it will be
# equivalent to value = nil.
result = get(resource, nil_set: true)
# Warn about this becoming a set in Chef 13.
begin
input_to_stored_value(resource, value)
# If nil is valid, and it would change the value, warn that this will change to a set.
if !result.nil?
Chef.log_deprecation("An attempt was made to change #{name} from #{result.inspect} to nil by calling #{name}(nil). In Chef 12, this does a get rather than a set. In Chef 13, this will change to set the value to nil.")
end
rescue Chef::Exceptions::DeprecatedFeatureError
raise
rescue
# If nil is invalid, warn that this will become an error.
Chef.log_deprecation("nil is an invalid value for #{self}. In Chef 13, this warning will change to an error. Error: #{$!}")
end
result
else
# Anything else, such as myprop(value) is a set
set(resource, value)
end
end
#
# Get the property value from the resource, handling lazy values,
# defaults, and validation.
#
# - If the property's value is lazy, it is evaluated, coerced and validated.
# - If the property has no value, and is required, raises ValidationFailed.
# - If the property has no value, but has a lazy default, it is evaluated,
# coerced and validated. If the evaluated value is frozen, the resulting
# - If the property has no value, but has a default, the default value
# will be returned and frozen. If the default value is lazy, it will be
# evaluated, coerced and validated, and the result stored in the property.
# - If the property has no value, but is name_property, `resource.name`
# is retrieved, coerced, validated and stored in the property.
# - Otherwise, `nil` is returned.
#
# @param resource [Chef::Resource] The resource to get the property from.
#
# @return The value of the property.
#
# @raise Chef::Exceptions::ValidationFailed If the value is invalid for
# this property, or if the value is required and not set.
#
def get(resource, nil_set: false)
# If it's set, return it (and evaluate any lazy values)
if is_set?(resource)
value = get_value(resource)
value = stored_value_to_output(resource, value)
else
# We are getting the default value.
# If the user does something like this:
#
# ```
# class MyResource < Chef::Resource
# property :content
# action :create do
# file '/x.txt' do
# content content
# end
# end
# end
# ```
#
# It won't do what they expect. This checks whether you try to *read*
# `content` while we are compiling the resource.
if !nil_set &&
resource.respond_to?(:resource_initializing) &&
resource.resource_initializing &&
resource.respond_to?(:enclosing_provider) &&
resource.enclosing_provider &&
resource.enclosing_provider.new_resource &&
resource.enclosing_provider.new_resource.respond_to?(name)
Chef::Log.warn("#{Chef::Log.caller_location}: property #{name} is declared in both #{resource} and #{resource.enclosing_provider}. Use new_resource.#{name} instead. At #{Chef::Log.caller_location}")
end
if has_default?
# If we were able to cache the stored_default, grab it.
if defined?(@stored_default)
value = @stored_default
else
# Otherwise, we have to validate it now.
value = input_to_stored_value(resource, default, is_default: true)
end
value = stored_value_to_output(resource, value, is_default: true)
# If the value is mutable (non-frozen), we set it on the instance
# so that people can mutate it. (All constant default values are
# frozen.)
if !value.frozen? && !value.nil?
set_value(resource, value)
end
value
elsif required?
raise Chef::Exceptions::ValidationFailed, "#{name} is required"
end
end
end
#
# Set the value of this property in the given resource.
#
# Non-lazy values are coerced and validated before being set. Coercion
# and validation of lazy values is delayed until they are first retrieved.
#
# @param resource [Chef::Resource] The resource to set this property in.
# @param value The value to set.
#
# @return The value that was set, after coercion (if lazy, still returns
# the lazy value)
#
# @raise Chef::Exceptions::ValidationFailed If the value is invalid for
# this property.
#
def set(resource, value)
set_value(resource, input_to_stored_value(resource, value))
end
#
# Find out whether this property has been set.
#
# This will be true if:
# - The user explicitly set the value
# - The property has a default, and the value was retrieved.
#
# From this point of view, it is worth looking at this as "what does the
# user think this value should be." In order words, if the user grabbed
# the value, even if it was a default, they probably based calculations on
# it. If they based calculations on it and the value changes, the rest of
# the world gets inconsistent.
#
# @param resource [Chef::Resource] The resource to get the property from.
#
# @return [Boolean]
#
def is_set?(resource)
value_is_set?(resource)
end
#
# Reset the value of this property so that is_set? will return false and the
# default will be returned in the future.
#
# @param resource [Chef::Resource] The resource to get the property from.
#
def reset(resource)
reset_value(resource)
end
#
# Coerce an input value into canonical form for the property.
#
# After coercion, the value is suitable for storage in the resource.
# You must validate values after coercion, however.
#
# Does no special handling for lazy values.
#
# @param resource [Chef::Resource] The resource we're coercing against
# (to provide context for the coerce).
# @param value The value to coerce.
#
# @return The coerced value.
#
# @raise Chef::Exceptions::ValidationFailed If the value is invalid for
# this property.
#
def coerce(resource, value)
if options.has_key?(:coerce)
# If we have no default value, `nil` is never coerced or validated
unless !has_default? && value.nil?
value = exec_in_resource(resource, options[:coerce], value)
end
end
value
end
#
# Validate a value.
#
# Calls Chef::Mixin::ParamsValidate#validate with #validation_options as
# options.
#
# @param resource [Chef::Resource] The resource we're validating against
# (to provide context for the validate).
# @param value The value to validate.
#
# @raise Chef::Exceptions::ValidationFailed If the value is invalid for
# this property.
#
def validate(resource, value)
# If we have no default value, `nil` is never coerced or validated
unless value.nil? && !has_default?
if resource
resource.validate({ name => value }, { name => validation_options })
else
name = self.name || :property_type
Chef::Mixin::ParamsValidate.validate({ name => value }, { name => validation_options })
end
end
end
#
# Derive a new Property that is just like this one, except with some added or
# changed options.
#
# @param options [Hash<Symbol,Object>] List of options that would be passed
# to #initialize.
#
# @return [Property] The new property type.
#
def derive(**modified_options)
# Since name_property, name_attribute and default override each other,
# if you specify one of them in modified_options it overrides anything in
# the original options.
options = self.options
if modified_options.has_key?(:name_property) ||
modified_options.has_key?(:name_attribute) ||
modified_options.has_key?(:default)
options = options.reject { |k, v| k == :name_attribute || k == :name_property || k == :default }
end
self.class.new(options.merge(modified_options))
end
#
# Emit the DSL for this property into the resource class (`declared_in`).
#
# Creates a getter and setter for the property.
#
def emit_dsl
# We don't create the getter/setter if it's a custom property; we will
# be using the existing getter/setter to manipulate it instead.
return if !instance_variable_name
# We prefer this form because the property name won't show up in the
# stack trace if you use `define_method`.
declared_in.class_eval <<-EOM, __FILE__, __LINE__ + 1
def #{name}(value=NOT_PASSED)
raise "Property `#{name}` of `\#{self}` was incorrectly passed a block. Possible property-resource collision. To call a resource named `#{name}` either rename the property or else use `declare_resource(:#{name}, ...)`" if block_given?
self.class.properties[#{name.inspect}].call(self, value)
end
def #{name}=(value)
raise "Property `#{name}` of `\#{self}` was incorrectly passed a block. Possible property-resource collision. To call a resource named `#{name}` either rename the property or else use `declare_resource(:#{name}, ...)`" if block_given?
self.class.properties[#{name.inspect}].set(self, value)
end
EOM
rescue SyntaxError
# If the name is not a valid ruby name, we use define_method.
declared_in.define_method(name) do |value = NOT_PASSED, &block|
raise "Property `#{name}` of `#{self}` was incorrectly passed a block! Possible property-resource collision. To call a resource named `#{name}` either rename the property or else use `declare_resource(:#{name}, ...)`" if block
self.class.properties[name].call(self, value)
end
declared_in.define_method("#{name}=") do |value, &block|
raise "Property `#{name}` of `#{self}` was incorrectly passed a block! Possible property-resource collision. To call a resource named `#{name}` either rename the property or else use `declare_resource(:#{name}, ...)`" if block
self.class.properties[name].set(self, value)
end
end
#
# The options this Property will use for get/set behavior and validation.
#
# @see #initialize for a list of valid options.
#
attr_reader :options
#
# Find out whether this type accepts nil explicitly.
#
# A type accepts nil explicitly if "is" allows nil, it validates as nil, *and* is not simply
# an empty type.
#
# A type is presumed to accept nil if it does coercion (which must handle nil).
#
# These examples accept nil explicitly:
# ```ruby
# property :a, [ String, nil ]
# property :a, [ String, NilClass ]
# property :a, [ String, proc { |v| v.nil? } ]
# ```
#
# This does not (because the "is" doesn't exist or doesn't have nil):
#
# ```ruby
# property :x, String
# ```
#
# These do not, even though nil would validate fine (because they do not
# have "is"):
#
# ```ruby
# property :a
# property :a, equal_to: [ 1, 2, 3, nil ]
# property :a, kind_of: [ String, NilClass ]
# property :a, respond_to: [ ]
# property :a, callbacks: { "a" => proc { |v| v.nil? } }
# ```
#
# @param resource [Chef::Resource] The resource we're coercing against
# (to provide context for the coerce).
#
# @return [Boolean] Whether this value explicitly accepts nil.
#
# @api private
def explicitly_accepts_nil?(resource)
options.has_key?(:coerce) ||
(options.has_key?(:is) && resource.send(:_pv_is, { name => nil }, name, options[:is], raise_error: false))
end
# @api private
def get_value(resource)
if instance_variable_name
resource.instance_variable_get(instance_variable_name)
else
resource.send(name)
end
end
# @api private
def set_value(resource, value)
if instance_variable_name
resource.instance_variable_set(instance_variable_name, value)
else
resource.send(name, value)
end
end
# @api private
def value_is_set?(resource)
if instance_variable_name
resource.instance_variable_defined?(instance_variable_name)
else
true
end
end
# @api private
def reset_value(resource)
if instance_variable_name
if value_is_set?(resource)
resource.remove_instance_variable(instance_variable_name)
end
else
raise ArgumentError, "Property #{name} has no instance variable defined and cannot be reset"
end
end
private
def exec_in_resource(resource, proc, *args)
if resource
if proc.arity > args.size
value = proc.call(resource, *args)
else
value = resource.instance_exec(*args, &proc)
end
else
# If we don't have a resource yet, we can't exec in resource!
raise Chef::Exceptions::CannotValidateStaticallyError, "Cannot validate or coerce without a resource"
end
end
def input_to_stored_value(resource, value, is_default: false)
unless value.is_a?(DelayedEvaluator)
value = coerce_and_validate(resource, value, is_default: is_default)
end
value
end
def stored_value_to_output(resource, value, is_default: false)
# Crack open lazy values before giving the result to the user
if value.is_a?(DelayedEvaluator)
value = exec_in_resource(resource, value)
value = coerce_and_validate(resource, value, is_default: is_default)
end
value
end
# Coerces and validates the value. If the value is a default, it will warn
# the user that invalid defaults are bad mmkay, and return it as if it were
# valid.
def coerce_and_validate(resource, value, is_default: false)
result = coerce(resource, value)
begin
# If the input is from a default, we need to emit an invalid default warning on validate.
validate(resource, result)
rescue Chef::Exceptions::CannotValidateStaticallyError
# This one gets re-raised
raise
rescue
# Anything else is just an invalid default: in those cases, we just
# warn and return the (possibly coerced) value to the user.
if is_default
if value.nil?
Chef.log_deprecation("Default value nil is invalid for property #{self}. Possible fixes: 1. Remove 'default: nil' if nil means 'undefined'. 2. Set a valid default value if there is a reasonable one. 3. Allow nil as a valid value of your property (for example, 'property #{name.inspect}, [ String, nil ], default: nil'). Error: #{$!}")
else
Chef.log_deprecation("Default value #{value.inspect} is invalid for property #{self}. In Chef 13 this will become an error: #{$!}.")
end
else
raise
end
end
result
end
def nillable?
!!options[:nillable]
end
end
end
end
end
end

View File

@ -0,0 +1,164 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/provider'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
require "chef_compat/copied_from_chef/chef/dsl/core"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object)
include Chef::DSL::Core
attr_accessor :action
def initialize(new_resource, run_context)
super if defined?(::Chef::Provider)
@new_resource = new_resource
@action = action
@current_resource = nil
@run_context = run_context
@converge_actions = nil
@recipe_name = nil
@cookbook_name = nil
self.class.include_resource_dsl_module(new_resource)
end
def converge_if_changed(*properties, &converge_block)
if !converge_block
raise ArgumentError, "converge_if_changed must be passed a block!"
end
properties = new_resource.class.state_properties.map { |p| p.name } if properties.empty?
properties = properties.map { |p| p.to_sym }
if current_resource
# Collect the list of modified properties
specified_properties = properties.select { |property| new_resource.property_is_set?(property) }
modified = specified_properties.select { |p| new_resource.send(p) != current_resource.send(p) }
if modified.empty?
properties_str = if sensitive
specified_properties.join(", ")
else
specified_properties.map { |p| "#{p}=#{new_resource.send(p).inspect}" }.join(", ")
end
Chef::Log.debug("Skipping update of #{new_resource}: has not changed any of the specified properties #{properties_str}.")
return false
end
# Print the pretty green text and run the block
property_size = modified.map { |p| p.size }.max
modified.map! do |p|
properties_str = if sensitive
"(suppressed sensitive property)"
else
"#{new_resource.send(p).inspect} (was #{current_resource.send(p).inspect})"
end
" set #{p.to_s.ljust(property_size)} to #{properties_str}"
end
converge_by([ "update #{current_resource.identity}" ] + modified, &converge_block)
else
# The resource doesn't exist. Mark that we are *creating* this, and
# write down any properties we are setting.
property_size = properties.map { |p| p.size }.max
created = properties.map do |property|
default = " (default value)" unless new_resource.property_is_set?(property)
properties_str = if sensitive
"(suppressed sensitive property)"
else
new_resource.send(property).inspect
end
" set #{property.to_s.ljust(property_size)} to #{properties_str}#{default}"
end
converge_by([ "create #{new_resource.identity}" ] + created, &converge_block)
end
true
end
def self.include_resource_dsl(include_resource_dsl)
@include_resource_dsl = include_resource_dsl
end
def self.include_resource_dsl_module(resource)
if @include_resource_dsl && !defined?(@included_resource_dsl_module)
provider_class = self
@included_resource_dsl_module = Module.new do
extend Forwardable
define_singleton_method(:to_s) { "forwarder module for #{provider_class}" }
define_singleton_method(:inspect) { to_s }
# Add a delegator for each explicit property that will get the *current* value
# of the property by default instead of the *actual* value.
resource.class.properties.each do |name, property|
class_eval(<<-EOM, __FILE__, __LINE__)
def #{name}(*args, &block)
# If no arguments were passed, we process "get" by defaulting
# the value to current_resource, not new_resource. This helps
# avoid issues where resources accidentally overwrite perfectly
# valid stuff with default values.
if args.empty? && !block
if !new_resource.property_is_set?(__method__) && current_resource
return current_resource.public_send(__method__)
end
end
new_resource.public_send(__method__, *args, &block)
end
EOM
end
dsl_methods =
resource.class.public_instance_methods +
resource.class.protected_instance_methods -
provider_class.instance_methods -
resource.class.properties.keys
def_delegators(:new_resource, *dsl_methods)
end
include @included_resource_dsl_module
end
end
def self.use_inline_resources
extend InlineResources::ClassMethods
include InlineResources
end
module InlineResources
CopiedFromChef.extend_chef_module(::Chef::Provider::InlineResources, self) if defined?(::Chef::Provider::InlineResources)
def compile_and_converge_action(&block)
old_run_context = run_context
@run_context = run_context.create_child
return_value = instance_eval(&block)
Chef::Runner.new(run_context).converge
return_value
ensure
if run_context.resource_collection.any? { |r| r.updated? }
new_resource.updated_by_last_action(true)
end
@run_context = old_run_context
end
module ClassMethods
CopiedFromChef.extend_chef_module(::Chef::Provider::InlineResources::ClassMethods, self) if defined?(::Chef::Provider::InlineResources::ClassMethods)
def action(name, &block)
# We need the block directly in a method so that `super` works
define_method("compile_action_#{name}", &block)
# We try hard to use `def` because define_method doesn't show the method name in the stack.
begin
class_eval <<-EOM
def action_#{name}
compile_and_converge_action { compile_action_#{name} }
end
EOM
rescue SyntaxError
define_method("action_#{name}") { send("compile_action_#{name}") }
end
end
end
end
protected
end
end
end
end
end

View File

@ -0,0 +1,269 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/provider/apt_repository'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Thom May (<thom@chef.io>)
# Copyright:: Copyright (c) 2016 Chef Software, 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_compat/copied_from_chef/chef/resource"
require "chef_compat/copied_from_chef/chef/dsl/declare_resource"
require "chef_compat/copied_from_chef/chef/provider/noop"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object)
class AptRepository < (defined?(::Chef::Provider::AptRepository) ? ::Chef::Provider::AptRepository : Chef::Provider)
use_inline_resources
include Chef::Mixin::ShellOut
extend Chef::Mixin::Which
provides :apt_repository do
which("apt-get")
end
def whyrun_supported?
true
end
def load_current_resource
end
action :add do
unless new_resource.key.nil?
if is_key_id?(new_resource.key) && !has_cookbook_file?(new_resource.key)
install_key_from_keyserver
else
install_key_from_uri
end
end
declare_resource(:execute, "apt-cache gencaches") do
ignore_failure true
action :nothing
end
declare_resource(:apt_update, new_resource.name) do
ignore_failure true
action :nothing
end
components = if is_ppa_url?(new_resource.uri) && new_resource.components.empty?
"main"
else
new_resource.components
end
repo = build_repo(
new_resource.uri,
new_resource.distribution,
components,
new_resource.trusted,
new_resource.arch,
new_resource.deb_src
)
declare_resource(:file, "/etc/apt/sources.list.d/#{new_resource.name}.list") do
owner "root"
group "root"
mode "0644"
content repo
sensitive new_resource.sensitive
action :create
notifies :run, "execute[apt-cache gencaches]", :immediately
notifies :update, "apt_update[#{new_resource.name}]", :immediately if new_resource.cache_rebuild
end
end
action :remove do
if ::File.exist?("/etc/apt/sources.list.d/#{new_resource.name}.list")
converge_by "Removing #{new_resource.name} repository from /etc/apt/sources.list.d/" do
declare_resource(:file, "/etc/apt/sources.list.d/#{new_resource.name}.list") do
sensitive new_resource.sensitive
action :delete
notifies :update, "apt_update[#{new_resource.name}]", :immediately if new_resource.cache_rebuild
end
declare_resource(:apt_update, new_resource.name) do
ignore_failure true
action :nothing
end
end
end
end
def is_key_id?(id)
id = id[2..-1] if id.start_with?("0x")
id =~ /^\h+$/ && [8, 16, 40].include?(id.length)
end
def extract_fingerprints_from_cmd(cmd)
so = shell_out(cmd)
so.run_command
so.stdout.split(/\n/).map do |t|
if z = t.match(/^ +Key fingerprint = ([0-9A-F ]+)/)
z[1].split.join
end
end.compact
end
def key_is_valid?(cmd, key)
valid = true
so = shell_out(cmd)
so.run_command
so.stdout.split(/\n/).map do |t|
if t =~ %r{^\/#{key}.*\[expired: .*\]$}
Chef::Log.debug "Found expired key: #{t}"
valid = false
break
end
end
Chef::Log.debug "key #{key} #{valid ? "is valid" : "is not valid"}"
valid
end
def cookbook_name
new_resource.cookbook || new_resource.cookbook_name
end
def has_cookbook_file?(fn)
run_context.has_cookbook_file_in_cookbook?(cookbook_name, fn)
end
def no_new_keys?(file)
installed_keys = extract_fingerprints_from_cmd("apt-key finger")
proposed_keys = extract_fingerprints_from_cmd("gpg --with-fingerprint #{file}")
(installed_keys & proposed_keys).sort == proposed_keys.sort
end
def install_key_from_uri
key_name = new_resource.key.gsub(/[^0-9A-Za-z\-]/, "_")
cached_keyfile = ::File.join(Chef::Config[:file_cache_path], key_name)
type = if new_resource.key.start_with?("http")
:remote_file
elsif has_cookbook_file?(new_resource.key)
:cookbook_file
else
raise Chef::Exceptions::FileNotFound, "Cannot locate key file"
end
declare_resource(type, cached_keyfile) do
source new_resource.key
mode "0644"
sensitive new_resource.sensitive
action :create
end
raise "The key #{cached_keyfile} is invalid and cannot be used to verify an apt repository." unless key_is_valid?("gpg #{cached_keyfile}", "")
declare_resource(:execute, "apt-key add #{cached_keyfile}") do
sensitive new_resource.sensitive
action :run
not_if do
no_new_keys?(cached_keyfile)
end
notifies :run, "execute[apt-cache gencaches]", :immediately
end
end
def install_key_from_keyserver(key = new_resource.key, keyserver = new_resource.keyserver)
cmd = "apt-key adv --recv"
cmd << " --keyserver-options http-proxy=#{new_resource.key_proxy}" if new_resource.key_proxy
cmd << " --keyserver "
cmd << if keyserver.start_with?("hkp://")
keyserver
else
"hkp://#{keyserver}:80"
end
cmd << " #{key}"
declare_resource(:execute, "install-key #{key}") do
command cmd
sensitive new_resource.sensitive
not_if do
present = extract_fingerprints_from_cmd("apt-key finger").any? do |fp|
fp.end_with? key.upcase
end
present && key_is_valid?("apt-key list", key.upcase)
end
notifies :run, "execute[apt-cache gencaches]", :immediately
end
raise "The key #{key} is invalid and cannot be used to verify an apt repository." unless key_is_valid?("apt-key list", key.upcase)
end
def install_ppa_key(owner, repo)
url = "https://launchpad.net/api/1.0/~#{owner}/+archive/#{repo}"
key_id = Chef::HTTP::Simple.new(url).get("signing_key_fingerprint").delete('"')
install_key_from_keyserver(key_id, "keyserver.ubuntu.com")
rescue Net::HTTPServerException => e
raise "Could not access Launchpad ppa API: #{e.message}"
end
def is_ppa_url?(url)
url.start_with?("ppa:")
end
def make_ppa_url(ppa)
return unless is_ppa_url?(ppa)
owner, repo = ppa[4..-1].split("/")
repo ||= "ppa"
install_ppa_key(owner, repo)
"http://ppa.launchpad.net/#{owner}/#{repo}/ubuntu"
end
def build_repo(uri, distribution, components, trusted, arch, add_src = false)
uri = make_ppa_url(uri) if is_ppa_url?(uri)
uri = '"' + uri + '"' unless uri.start_with?("'", '"')
components = Array(components).join(" ")
options = []
options << "arch=#{arch}" if arch
options << "trusted=yes" if trusted
optstr = unless options.empty?
"[" + options.join(" ") + "]"
end
info = [ optstr, uri, distribution, components ].compact.join(" ")
repo = "deb #{info}\n"
repo << "deb-src #{info}\n" if add_src
repo
end
end
end
end
Chef::Provider::Noop.provides :apt_repository
end
end
end

View File

@ -0,0 +1,105 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/provider/apt_update'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Thom May (<thom@chef.io>)
# Copyright:: Copyright (c) 2016 Chef Software, 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_compat/copied_from_chef/chef/provider"
require "chef_compat/copied_from_chef/chef/provider/noop"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object)
class AptUpdate < (defined?(::Chef::Provider::AptUpdate) ? ::Chef::Provider::AptUpdate : Chef::Provider)
use_inline_resources
extend Chef::Mixin::Which
provides :apt_update do
which("apt-get")
end
APT_CONF_DIR = "/etc/apt/apt.conf.d"
STAMP_DIR = "/var/lib/apt/periodic"
def whyrun_supported?
true
end
def load_current_resource
end
action :periodic do
if !apt_up_to_date?
converge_by "update new lists of packages" do
do_update
end
end
end
action :update do
converge_by "force update new lists of packages" do
do_update
end
end
private
# Determines whether we need to run `apt-get update`
#
# @return [Boolean]
def apt_up_to_date?
::File.exist?("#{STAMP_DIR}/update-success-stamp") &&
::File.mtime("#{STAMP_DIR}/update-success-stamp") > Time.now - new_resource.frequency
end
def do_update
[STAMP_DIR, APT_CONF_DIR].each do |d|
declare_resource(:directory, d) do
recursive true
end
end
declare_resource(:file, "#{APT_CONF_DIR}/15update-stamp") do
content "APT::Update::Post-Invoke-Success {\"touch #{STAMP_DIR}/update-success-stamp 2>/dev/null || true\";};\n"
action :create_if_missing
end
declare_resource(:execute, "apt-get -q update")
end
end
end
end
Chef::Provider::Noop.provides :apt_update
end
end
end

View File

@ -0,0 +1,56 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/provider/noop'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Thom May (<thom@chef.io>)
# Copyright:: Copyright (c) 2016 Chef Software, 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.
#
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object)
class Noop < (defined?(::Chef::Provider::Noop) ? ::Chef::Provider::Noop : Chef::Provider)
def load_current_resource; end
def respond_to_missing?(method_sym, include_private = false)
method_sym.to_s.start_with?("action_") || super
end
def method_missing(method_sym, *arguments, &block)
if method_sym.to_s =~ /^action_/
Chef::Log.debug("NoOp-ing for #{method_sym}")
else
super
end
end
end
end
end
end
end
end

View File

@ -0,0 +1,125 @@
# This file was generated by Chef
# Do NOT modify this file by hand.
[<%= @config.repositoryid %>]
name=<%= @config.description %>
<% if @config.baseurl %>
baseurl=<%= @config.baseurl %>
<% end %>
<% if @config.cost %>
cost=<%= @config.cost %>
<% end %>
<% if @config.enabled %>
enabled=1
<% else %>
enabled=0
<% end %>
<% if @config.enablegroups %>
enablegroups=1
<% end %>
<% if @config.exclude %>
exclude=<%= @config.exclude %>
<% end %>
<% if @config.failovermethod %>
failovermethod=<%= @config.failovermethod %>
<% end %>
<% if @config.fastestmirror_enabled %>
fastestmirror_enabled=<%= @config.fastestmirror_enabled %>
<% end %>
<% if @config.gpgcheck %>
gpgcheck=1
<% else %>
gpgcheck=0
<% end %>
<% if @config.gpgkey %>
gpgkey=<%= case @config.gpgkey
when Array
@config.gpgkey.join("\n ")
else
@config.gpgkey
end %>
<% end -%>
<% if @config.http_caching %>
http_caching=<%= @config.http_caching %>
<% end %>
<% if @config.include_config %>
include=<%= @config.include_config %>
<% end %>
<% if @config.includepkgs %>
includepkgs=<%= @config.includepkgs %>
<% end %>
<% if @config.keepalive %>
keepalive=1
<% end %>
<% if @config.metadata_expire %>
metadata_expire=<%= @config.metadata_expire %>
<% end %>
<% if @config.mirrorlist %>
mirrorlist=<%= @config.mirrorlist %>
<% end %>
<% if @config.mirror_expire %>
mirror_expire=<%= @config.mirror_expire %>
<% end %>
<% if @config.mirrorlist_expire %>
mirrorlist_expire=<%= @config.mirrorlist_expire %>
<% end %>
<% if @config.priority %>
priority=<%= @config.priority %>
<% end %>
<% if @config.proxy %>
proxy=<%= @config.proxy %>
<% end %>
<% if @config.proxy_username %>
proxy_username=<%= @config.proxy_username %>
<% end %>
<% if @config.proxy_password %>
proxy_password=<%= @config.proxy_password %>
<% end %>
<% if @config.username %>
username=<%= @config.username %>
<% end %>
<% if @config.password %>
password=<%= @config.password %>
<% end %>
<% if @config.repo_gpgcheck %>
repo_gpgcheck=1
<% end %>
<% if @config.max_retries %>
retries=<%= @config.max_retries %>
<% end %>
<% if @config.report_instanceid %>
report_instanceid=<%= @config.report_instanceid %>
<% end %>
<% if @config.skip_if_unavailable %>
skip_if_unavailable=1
<% end %>
<% if @config.sslcacert %>
sslcacert=<%= @config.sslcacert %>
<% end %>
<% if @config.sslclientcert %>
sslclientcert=<%= @config.sslclientcert %>
<% end %>
<% if @config.sslclientkey %>
sslclientkey=<%= @config.sslclientkey %>
<% end %>
<% unless @config.sslverify.nil? %>
sslverify=<%= ( @config.sslverify ) ? 'true' : 'false' %>
<% end %>
<% if @config.timeout %>
timeout=<%= @config.timeout %>
<% end %>
<% if @config.options -%>
<% @config.options.each do |key, value| -%>
<%= key %>=<%=
case value
when Array
value.join("\n ")
when TrueClass
'1'
when FalseClass
'0'
else
value
end %>
<% end -%>
<% end -%>

View File

@ -0,0 +1,253 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/provider/systemd_unit'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Nathan Williams (<nath.e.will@gmail.com>)
# Copyright:: Copyright 2016, Nathan Williams
# 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_compat/copied_from_chef/chef/provider"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object)
class SystemdUnit < (defined?(::Chef::Provider::SystemdUnit) ? ::Chef::Provider::SystemdUnit : Chef::Provider)
include Chef::Mixin::Which
include Chef::Mixin::ShellOut
provides :systemd_unit, os: "linux"
def load_current_resource
@current_resource = Chef::Resource::SystemdUnit.new(new_resource.name)
current_resource.content(::File.read(unit_path)) if ::File.exist?(unit_path)
current_resource.user(new_resource.user)
current_resource.enabled(enabled?)
current_resource.active(active?)
current_resource.masked(masked?)
current_resource.static(static?)
current_resource.triggers_reload(new_resource.triggers_reload)
current_resource
end
def define_resource_requirements
super
requirements.assert(:create) do |a|
a.assertion { IniParse.parse(new_resource.to_ini) }
a.failure_message "Unit content is not valid INI text"
end
end
def action_create
if current_resource.content != new_resource.to_ini
converge_by("creating unit: #{new_resource.name}") do
manage_unit_file(:create)
daemon_reload if new_resource.triggers_reload
end
end
end
def action_delete
if ::File.exist?(unit_path)
converge_by("deleting unit: #{new_resource.name}") do
manage_unit_file(:delete)
daemon_reload if new_resource.triggers_reload
end
end
end
def action_enable
if current_resource.static
Chef::Log.debug("#{new_resource.name} is a static unit, enabling is a NOP.")
end
unless current_resource.enabled || current_resource.static
converge_by("enabling unit: #{new_resource.name}") do
systemctl_execute!(:enable, new_resource.name)
end
end
end
def action_disable
if current_resource.static
Chef::Log.debug("#{new_resource.name} is a static unit, disabling is a NOP.")
end
if current_resource.enabled && !current_resource.static
converge_by("disabling unit: #{new_resource.name}") do
systemctl_execute!(:disable, new_resource.name)
end
end
end
def action_mask
unless current_resource.masked
converge_by("masking unit: #{new_resource.name}") do
systemctl_execute!(:mask, new_resource.name)
end
end
end
def action_unmask
if current_resource.masked
converge_by("unmasking unit: #{new_resource.name}") do
systemctl_execute!(:unmask, new_resource.name)
end
end
end
def action_start
unless current_resource.active
converge_by("starting unit: #{new_resource.name}") do
systemctl_execute!(:start, new_resource.name)
end
end
end
def action_stop
if current_resource.active
converge_by("stopping unit: #{new_resource.name}") do
systemctl_execute!(:stop, new_resource.name)
end
end
end
def action_restart
converge_by("restarting unit: #{new_resource.name}") do
systemctl_execute!(:restart, new_resource.name)
end
end
def action_reload
if current_resource.active
converge_by("reloading unit: #{new_resource.name}") do
systemctl_execute!(:reload, new_resource.name)
end
else
Chef::Log.debug("#{new_resource.name} is not active, skipping reload.")
end
end
def action_try_restart
converge_by("try-restarting unit: #{new_resource.name}") do
systemctl_execute!("try-restart", new_resource.name)
end
end
def action_reload_or_restart
converge_by("reload-or-restarting unit: #{new_resource.name}") do
systemctl_execute!("reload-or-restart", new_resource.name)
end
end
def action_reload_or_try_restart
converge_by("reload-or-try-restarting unit: #{new_resource.name}") do
systemctl_execute!("reload-or-try-restart", new_resource.name)
end
end
def active?
systemctl_execute("is-active", new_resource.name).exitstatus == 0
end
def enabled?
systemctl_execute("is-enabled", new_resource.name).exitstatus == 0
end
def masked?
systemctl_execute(:status, new_resource.name).stdout.include?("masked")
end
def static?
systemctl_execute("is-enabled", new_resource.name).stdout.include?("static")
end
private
def unit_path
if new_resource.user
"/etc/systemd/user/#{new_resource.name}"
else
"/etc/systemd/system/#{new_resource.name}"
end
end
def manage_unit_file(action = :nothing)
Chef::Resource::File.new(unit_path, run_context).tap do |f|
f.owner "root"
f.group "root"
f.mode "0644"
f.content new_resource.to_ini
end.run_action(action)
end
def daemon_reload
shell_out_with_systems_locale!("#{systemctl_path} daemon-reload")
end
def systemctl_execute!(action, unit)
shell_out_with_systems_locale!("#{systemctl_cmd} #{action} #{unit}", systemctl_opts)
end
def systemctl_execute(action, unit)
shell_out("#{systemctl_cmd} #{action} #{unit}", systemctl_opts)
end
def systemctl_cmd
@systemctl_cmd ||= "#{systemctl_path} #{systemctl_args}"
end
def systemctl_path
@systemctl_path ||= which("systemctl")
end
def systemctl_args
@systemctl_args ||= new_resource.user ? "--user" : "--system"
end
def systemctl_opts
@systemctl_opts ||=
if new_resource.user
{
:user => new_resource.user,
:environment => {
"DBUS_SESSION_BUS_ADDRESS" => "unix:path=/run/user/#{node['etc']['passwd'][new_resource.user]['uid']}/bus",
},
}
else
{}
end
end
end
end
end
end
end
end

View File

@ -0,0 +1,137 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/provider/yum_repository'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Thom May (<thom@chef.io>)
# Copyright:: Copyright (c) 2016 Chef Software, 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_compat/copied_from_chef/chef/resource"
require "chef_compat/copied_from_chef/chef/dsl/declare_resource"
require "chef_compat/copied_from_chef/chef/provider/noop"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object)
class YumRepository < (defined?(::Chef::Provider::YumRepository) ? ::Chef::Provider::YumRepository : Chef::Provider)
use_inline_resources
extend Chef::Mixin::Which
provides :yum_repository do
which "yum"
end
def whyrun_supported?; true; end
def load_current_resource; end
action :create do
declare_resource(:template, "/etc/yum.repos.d/#{new_resource.repositoryid}.repo") do
if template_available?(new_resource.source)
source new_resource.source
else
source ::File.expand_path("../support/yum_repo.erb", __FILE__)
local true
end
sensitive new_resource.sensitive
variables(config: new_resource)
mode new_resource.mode
if new_resource.make_cache
notifies :run, "execute[yum clean metadata #{new_resource.repositoryid}]", :immediately if new_resource.clean_metadata || new_resource.clean_headers
notifies :run, "execute[yum-makecache-#{new_resource.repositoryid}]", :immediately
notifies :create, "ruby_block[yum-cache-reload-#{new_resource.repositoryid}]", :immediately
end
end
declare_resource(:execute, "yum clean metadata #{new_resource.repositoryid}") do
command "yum clean metadata --disablerepo=* --enablerepo=#{new_resource.repositoryid}"
action :nothing
end
# get the metadata for this repo only
declare_resource(:execute, "yum-makecache-#{new_resource.repositoryid}") do
command "yum -q -y makecache --disablerepo=* --enablerepo=#{new_resource.repositoryid}"
action :nothing
only_if { new_resource.enabled }
end
# reload internal Chef yum cache
declare_resource(:ruby_block, "yum-cache-reload-#{new_resource.repositoryid}") do
block { Chef::Provider::Package::Yum::YumCache.instance.reload }
action :nothing
end
end
action :delete do
declare_resource(:file, "/etc/yum.repos.d/#{new_resource.repositoryid}.repo") do
action :delete
notifies :run, "execute[yum clean all #{new_resource.repositoryid}]", :immediately
notifies :create, "ruby_block[yum-cache-reload-#{new_resource.repositoryid}]", :immediately
end
declare_resource(:execute, "yum clean all #{new_resource.repositoryid}") do
command "yum clean all --disablerepo=* --enablerepo=#{new_resource.repositoryid}"
only_if "yum repolist | grep -P '^#{new_resource.repositoryid}([ \t]|$)'"
action :nothing
end
declare_resource(:ruby_block, "yum-cache-reload-#{new_resource.repositoryid}") do
block { Chef::Provider::Package::Yum::YumCache.instance.reload }
action :nothing
end
end
action :makecache do
declare_resource(:execute, "yum-makecache-#{new_resource.repositoryid}") do
command "yum -q -y makecache --disablerepo=* --enablerepo=#{new_resource.repositoryid}"
action :run
only_if { new_resource.enabled }
end
declare_resource(:ruby_block, "yum-cache-reload-#{new_resource.repositoryid}") do
block { Chef::Provider::Package::Yum::YumCache.instance.reload }
action :run
end
end
alias_method :action_add, :action_create
alias_method :action_remove, :action_delete
def template_available?(path)
!path.nil? && run_context.has_template_in_cookbook?(new_resource.cookbook_name, path)
end
end
end
end
Chef::Provider::Noop.provides :yum_repository
end
end
end

View File

@ -0,0 +1,214 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/resource'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
require "chef_compat/copied_from_chef/chef/resource/action_class"
require "chef_compat/copied_from_chef/chef/provider"
require "chef_compat/copied_from_chef/chef/mixin/properties"
require "chef_compat/copied_from_chef/chef/dsl/universal"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object)
include Chef::Mixin::Properties
property :name, String, coerce: proc { |v| v.is_a?(Array) ? v.join(", ") : v.to_s }, desired_state: false
def initialize(name, run_context = nil)
super if defined?(::Chef::Resource)
name(name) unless name.nil?
@run_context = run_context
@noop = nil
@before = nil
@params = Hash.new
@provider = nil
@allowed_actions = self.class.allowed_actions.to_a
@action = self.class.default_action
@updated = false
@updated_by_last_action = false
@supports = {}
@ignore_failure = false
@retries = 0
@retry_delay = 2
@not_if = []
@only_if = []
@source_line = nil
# We would like to raise an error when the user gives us a guard
# interpreter and a ruby_block to the guard. In order to achieve this
# we need to understand when the user overrides the default guard
# interpreter. Therefore we store the default separately in a different
# attribute.
@guard_interpreter = nil
@default_guard_interpreter = :default
@elapsed_time = 0
@sensitive = false
end
def action(arg = nil)
if arg
arg = Array(arg).map(&:to_sym)
arg.each do |action|
validate(
{ action: action },
{ action: { kind_of: Symbol, equal_to: allowed_actions } }
)
end
@action = arg
else
@action
end
end
alias_method :action=, :action
class UnresolvedSubscribes < (defined?(::Chef::Resource::UnresolvedSubscribes) ? ::Chef::Resource::UnresolvedSubscribes : self)
alias_method :to_s, :name
alias_method :declared_key, :name
end
def state_for_resource_reporter
state = {}
state_properties = self.class.state_properties
state_properties.each do |property|
if property.identity? || property.is_set?(self)
state[property.name] = property.sensitive? ? "*sensitive value suppressed*" : send(property.name)
end
end
state
end
alias_method :state, :state_for_resource_reporter
def identity
result = {}
identity_properties = self.class.identity_properties
identity_properties.each do |property|
result[property.name] = send(property.name)
end
return result.values.first if identity_properties.size == 1
result
end
attr_reader :resource_initializing
def resource_initializing=(value)
if value
@resource_initializing = true
else
remove_instance_variable(:@resource_initializing)
end
end
def to_hash
# Grab all current state, then any other ivars (backcompat)
result = {}
self.class.state_properties.each do |p|
result[p.name] = p.get(self)
end
safe_ivars = instance_variables.map { |ivar| ivar.to_sym } - FORBIDDEN_IVARS
safe_ivars.each do |iv|
key = iv.to_s.sub(/^@/, "").to_sym
next if result.has_key?(key)
result[key] = instance_variable_get(iv)
end
result
end
def self.identity_property(name = nil)
result = identity_properties(*Array(name))
if result.size > 1
raise Chef::Exceptions::MultipleIdentityError, "identity_property cannot be called on an object with more than one identity property (#{result.map { |r| r.name }.join(", ")})."
end
result.first
end
attr_accessor :allowed_actions
def allowed_actions(value = NOT_PASSED)
if value != NOT_PASSED
self.allowed_actions = value
end
@allowed_actions
end
def resource_name
@resource_name || self.class.resource_name
end
def self.use_automatic_resource_name
automatic_name = convert_to_snake_case(self.name.split("::")[-1])
resource_name automatic_name
end
def self.allowed_actions(*actions)
@allowed_actions ||=
if superclass.respond_to?(:allowed_actions)
superclass.allowed_actions.dup
else
[ :nothing ]
end
@allowed_actions |= actions.flatten
end
def self.allowed_actions=(value)
@allowed_actions = value.uniq
end
def self.default_action(action_name = NOT_PASSED)
unless action_name.equal?(NOT_PASSED)
@default_action = Array(action_name).map(&:to_sym)
self.allowed_actions |= @default_action
end
if @default_action
@default_action
elsif superclass.respond_to?(:default_action)
superclass.default_action
else
[:nothing]
end
end
def self.default_action=(action_name)
default_action action_name
end
def self.action(action, &recipe_block)
action = action.to_sym
declare_action_class
action_class.action(action, &recipe_block)
self.allowed_actions += [ action ]
default_action action if Array(default_action) == [:nothing]
end
def self.load_current_value(&load_block)
define_method(:load_current_value!, &load_block)
end
def current_value_does_not_exist!
raise Chef::Exceptions::CurrentValueDoesNotExist
end
def self.action_class(&block)
return @action_class if @action_class && !block
# If the superclass needed one, then we need one as well.
if block || (superclass.respond_to?(:action_class) && superclass.action_class)
@action_class = declare_action_class(&block)
end
@action_class
end
def self.declare_action_class(&block)
@action_class ||= begin
if superclass.respond_to?(:action_class)
base_provider = superclass.action_class
end
base_provider ||= Chef::Provider
resource_class = self
Class.new(base_provider) do
include ActionClass
self.resource_class = resource_class
end
end
@action_class.class_eval(&block) if block
@action_class
end
FORBIDDEN_IVARS = [:@run_context, :@not_if, :@only_if, :@enclosing_provider]
HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@not_if, :@only_if, :@elapsed_time, :@enclosing_provider]
class << self
end
@@sorted_descendants = nil
module DeprecatedLWRPClass
CopiedFromChef.extend_chef_module(::Chef::Resource::DeprecatedLWRPClass, self) if defined?(::Chef::Resource::DeprecatedLWRPClass)
end
end
end
end
end
end

View File

@ -0,0 +1,114 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/resource/action_class'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: John Keiser (<jkeiser@chef.io)
# Copyright:: Copyright 2015-2016, Chef Software 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_compat/copied_from_chef/chef/dsl/recipe"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object)
module ActionClass
CopiedFromChef.extend_chef_module(::Chef::Resource::ActionClass, self) if defined?(::Chef::Resource::ActionClass)
include Chef::DSL::Recipe
def to_s
"#{new_resource || "<no resource>"} action #{action ? action.inspect : "<no action>"}"
end
def whyrun_supported?
true
end
#
# If load_current_value! is defined on the resource, use that.
#
def load_current_resource
if new_resource.respond_to?(:load_current_value!)
# dup the resource and then reset desired-state properties.
current_resource = new_resource.dup
# We clear desired state in the copy, because it is supposed to be actual state.
# We keep identity properties and non-desired-state, which are assumed to be
# "control" values like `recurse: true`
current_resource.class.properties.each do |name, property|
if property.desired_state? && !property.identity? && !property.name_property?
property.reset(current_resource)
end
end
# Call the actual load_current_value! method. If it raises
# CurrentValueDoesNotExist, set current_resource to `nil`.
begin
# If the user specifies load_current_value do |desired_resource|, we
# pass in the desired resource as well as the current one.
if current_resource.method(:load_current_value!).arity > 0
current_resource.load_current_value!(new_resource)
else
current_resource.load_current_value!
end
rescue Chef::Exceptions::CurrentValueDoesNotExist
current_resource = nil
end
end
@current_resource = current_resource
end
def self.included(other)
other.extend(ClassMethods)
other.use_inline_resources
other.include_resource_dsl true
end
module ClassMethods
CopiedFromChef.extend_chef_module(::Chef::Resource::ActionClass::ClassMethods, self) if defined?(::Chef::Resource::ActionClass::ClassMethods)
#
# The Chef::Resource class this ActionClass was declared against.
#
# @return [Class] The Chef::Resource class this ActionClass was declared against.
#
attr_accessor :resource_class
def to_s
"#{resource_class} action provider"
end
def inspect
to_s
end
end
end
end
end
end
end
end

View File

@ -0,0 +1,66 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/resource/apt_repository'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Thom May (<thom@chef.io>)
# Copyright:: Copyright (c) 2016 Chef Software, 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_compat/copied_from_chef/chef/resource"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object)
class AptRepository < (defined?(::Chef::Resource::AptRepository) ? ::Chef::Resource::AptRepository : Chef::Resource)
resource_name :apt_repository
provides :apt_repository
property :repo_name, String, name_property: true
property :uri, String
property :distribution, [ String, nil, false ], default: lazy { node["lsb"]["codename"] }, nillable: true, coerce: proc { |x| x ? x : nil }
property :components, Array, default: []
property :arch, [String, nil, false], default: nil, nillable: true, coerce: proc { |x| x ? x : nil }
property :trusted, [TrueClass, FalseClass], default: false
# whether or not to add the repository as a source repo, too
property :deb_src, [TrueClass, FalseClass], default: false
property :keyserver, [String, nil, false], default: "keyserver.ubuntu.com", nillable: true, coerce: proc { |x| x ? x : nil }
property :key, [String, nil, false], default: nil, nillable: true, coerce: proc { |x| x ? x : nil }
property :key_proxy, [String, nil, false], default: nil, nillable: true, coerce: proc { |x| x ? x : nil }
property :cookbook, [String, nil, false], default: nil, desired_state: false, nillable: true, coerce: proc { |x| x ? x : nil }
property :cache_rebuild, [TrueClass, FalseClass], default: true, desired_state: false
property :sensitive, [TrueClass, FalseClass], default: false, desired_state: false
default_action :add
allowed_actions :add, :remove
end
end
end
end
end
end

View File

@ -0,0 +1,52 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/resource/apt_update'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Thom May (<thom@chef.io>)
# Copyright:: Copyright (c) 2016 Chef Software, 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_compat/copied_from_chef/chef/resource"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object)
class AptUpdate < (defined?(::Chef::Resource::AptUpdate) ? ::Chef::Resource::AptUpdate : Chef::Resource)
resource_name :apt_update
provides :apt_update, os: "linux"
property :frequency, Integer, default: 86_400
default_action :periodic
allowed_actions :update, :periodic
end
end
end
end
end
end

View File

@ -0,0 +1,81 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/resource/systemd_unit'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Nathan Williams (<nath.e.will@gmail.com>)
# Copyright:: Copyright 2016, Nathan Williams
# 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_compat/copied_from_chef/chef/resource"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object)
class SystemdUnit < (defined?(::Chef::Resource::SystemdUnit) ? ::Chef::Resource::SystemdUnit : Chef::Resource)
resource_name :systemd_unit
default_action :nothing
allowed_actions :create, :delete,
:enable, :disable,
:mask, :unmask,
:start, :stop,
:restart, :reload,
:try_restart, :reload_or_restart,
:reload_or_try_restart
property :enabled, [TrueClass, FalseClass]
property :active, [TrueClass, FalseClass]
property :masked, [TrueClass, FalseClass]
property :static, [TrueClass, FalseClass]
property :user, String, desired_state: false
property :content, [String, Hash]
property :triggers_reload, [TrueClass, FalseClass],
default: true, desired_state: false
def to_ini
case content
when Hash
IniParse.gen do |doc|
content.each_pair do |sect, opts|
doc.section(sect) do |section|
opts.each_pair do |opt, val|
section.option(opt, val)
end
end
end
end.to_s
else
content.to_s
end
end
end
end
end
end
end
end

View File

@ -0,0 +1,98 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/resource/yum_repository'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Thom May (<thom@chef.io>)
# Copyright:: Copyright (c) 2016 Chef Software, 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_compat/copied_from_chef/chef/resource"
class Chef < (defined?(::Chef) ? ::Chef : Object)
class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object)
class YumRepository < (defined?(::Chef::Resource::YumRepository) ? ::Chef::Resource::YumRepository : Chef::Resource)
resource_name :yum_repository
provides :yum_repository
# http://linux.die.net/man/5/yum.conf
property :baseurl, String, regex: /.*/
property :cost, String, regex: /^\d+$/
property :clean_headers, [TrueClass, FalseClass], default: false # deprecated
property :clean_metadata, [TrueClass, FalseClass], default: true
property :description, String, regex: /.*/, default: "Yum Repository"
property :enabled, [TrueClass, FalseClass], default: true
property :enablegroups, [TrueClass, FalseClass]
property :exclude, String, regex: /.*/
property :failovermethod, String, equal_to: %w{priority roundrobin}
property :fastestmirror_enabled, [TrueClass, FalseClass]
property :gpgcheck, [TrueClass, FalseClass], default: true
property :gpgkey, [String, Array], regex: /.*/
property :http_caching, String, equal_to: %w{packages all none}
property :include_config, String, regex: /.*/
property :includepkgs, String, regex: /.*/
property :keepalive, [TrueClass, FalseClass]
property :make_cache, [TrueClass, FalseClass], default: true
property :max_retries, [String, Integer]
property :metadata_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/, /never/]
property :mirrorexpire, String, regex: /.*/
property :mirrorlist, String, regex: /.*/
property :mirror_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/]
property :mirrorlist_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/]
property :mode, default: "0644"
property :priority, String, regex: /^(\d?[0-9]|[0-9][0-9])$/
property :proxy, String, regex: /.*/
property :proxy_username, String, regex: /.*/
property :proxy_password, String, regex: /.*/
property :username, String, regex: /.*/
property :password, String, regex: /.*/
property :repo_gpgcheck, [TrueClass, FalseClass]
property :report_instanceid, [TrueClass, FalseClass]
property :repositoryid, String, regex: /.*/, name_property: true
property :sensitive, [TrueClass, FalseClass], default: false
property :skip_if_unavailable, [TrueClass, FalseClass]
property :source, String, regex: /.*/
property :sslcacert, String, regex: /.*/
property :sslclientcert, String, regex: /.*/
property :sslclientkey, String, regex: /.*/
property :sslverify, [TrueClass, FalseClass]
property :timeout, String, regex: /^\d+$/
property :options, Hash
default_action :create
allowed_actions :create, :remove, :makecache, :add, :delete
# provide compatibility with the yum cookbook < 3.0 properties
alias_method :url, :baseurl
alias_method :keyurl, :gpgkey
end
end
end
end
end
end

View File

@ -0,0 +1,174 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
begin
require 'chef/resource_builder'
rescue LoadError; end
require 'chef_compat/copied_from_chef'
class Chef
module ::ChefCompat
module CopiedFromChef
#
# Author:: Lamont Granquist (<lamont@chef.io>)
# Copyright:: Copyright 2015-2016, Chef Software, 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.
#
# NOTE: this was extracted from the Recipe DSL mixin, relevant specs are in spec/unit/recipe_spec.rb
class Chef < (defined?(::Chef) ? ::Chef : Object)
class ResourceBuilder < (defined?(::Chef::ResourceBuilder) ? ::Chef::ResourceBuilder : Object)
attr_reader :type
attr_reader :name
attr_reader :created_at
attr_reader :params
attr_reader :run_context
attr_reader :cookbook_name
attr_reader :recipe_name
attr_reader :enclosing_provider
attr_reader :resource
# FIXME (ruby-2.1 syntax): most of these are mandatory
def initialize(type: nil, name: nil, created_at: nil, params: nil, run_context: nil, cookbook_name: nil, recipe_name: nil, enclosing_provider: nil)
super if defined?(::Chef::ResourceBuilder)
@type = type
@name = name
@created_at = created_at
@params = params
@run_context = run_context
@cookbook_name = cookbook_name
@recipe_name = recipe_name
@enclosing_provider = enclosing_provider
end
def build(&block)
raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil?
@resource = resource_class.new(name, run_context)
if resource.resource_name.nil?
raise Chef::Exceptions::InvalidResourceSpecification, "#{resource}.resource_name is `nil`! Did you forget to put `provides :blah` or `resource_name :blah` in your resource class?"
end
resource.source_line = created_at
resource.declared_type = type
# If we have a resource like this one, we want to steal its state
# This behavior is very counter-intuitive and should be removed.
# See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694
# Moved to this location to resolve CHEF-5052, https://tickets.opscode.com/browse/CHEF-5052
if prior_resource
resource.load_from(prior_resource)
end
resource.cookbook_name = cookbook_name
resource.recipe_name = recipe_name
# Determine whether this resource is being created in the context of an enclosing Provider
resource.enclosing_provider = enclosing_provider
# XXX: this is required for definition params inside of the scope of a
# subresource to work correctly.
resource.params = params
# Evaluate resource attribute DSL
if block_given?
resource.resource_initializing = true
begin
resource.instance_eval(&block)
ensure
resource.resource_initializing = false
end
end
# emit a cloned resource warning if it is warranted
if prior_resource
if is_trivial_resource?(prior_resource) && identicalish_resources?(prior_resource, resource)
emit_harmless_cloning_debug
else
emit_cloned_resource_warning
end
end
# Run optional resource hook
resource.after_created
resource
end
private
def resource_class
# Checks the new platform => short_name => resource mapping initially
# then fall back to the older approach (Chef::Resource.const_get) for
# backward compatibility
@resource_class ||= Chef::Resource.resource_for_node(type, run_context.node)
end
def is_trivial_resource?(resource)
trivial_resource = resource_class.new(name, run_context)
# force un-lazy the name property on the created trivial resource
name_property = resource_class.properties.find { |sym, p| p.name_property? }
trivial_resource.send(name_property[0]) unless name_property.nil?
identicalish_resources?(trivial_resource, resource)
end
# this is an equality test specific to checking for 3694 cloning warnings
def identicalish_resources?(first, second)
skipped_ivars = [ :@source_line, :@cookbook_name, :@recipe_name, :@params, :@elapsed_time, :@declared_type ]
checked_ivars = ( first.instance_variables | second.instance_variables ) - skipped_ivars
non_matching_ivars = checked_ivars.reject do |iv|
if iv == :@action && ( [first.instance_variable_get(iv)].flatten == [:nothing] || [second.instance_variable_get(iv)].flatten == [:nothing] )
# :nothing action on either side of the comparison always matches
true
else
first.instance_variable_get(iv) == second.instance_variable_get(iv)
end
end
Chef::Log.debug("ivars which did not match with the prior resource: #{non_matching_ivars}")
non_matching_ivars.empty?
end
def emit_cloned_resource_warning
message = "Cloning resource attributes for #{resource} from prior resource (CHEF-3694)"
message << "\nPrevious #{prior_resource}: #{prior_resource.source_line}" if prior_resource.source_line
message << "\nCurrent #{resource}: #{resource.source_line}" if resource.source_line
Chef.log_deprecation(message)
end
def emit_harmless_cloning_debug
Chef::Log.debug("Harmless resource cloning from #{prior_resource}:#{prior_resource.source_line} to #{resource}:#{resource.source_line}")
end
def prior_resource
@prior_resource ||=
begin
key = "#{type}[#{name}]"
run_context.resource_collection.lookup_local(key)
rescue Chef::Exceptions::ResourceNotFound
nil
end
end
end
end
require "chef_compat/copied_from_chef/chef/resource"
end
end
end

View File

@ -0,0 +1,8 @@
require 'chef_compat/monkeypatches'
require 'chef_compat/copied_from_chef/chef/mixin/properties'
module ChefCompat
module Mixin
Properties = ChefCompat::CopiedFromChef::Chef::Mixin::Properties
end
end

View File

@ -0,0 +1,41 @@
class Chef
class RunContext
class ChildRunContext < RunContext
# magic that lets us re-parse the ChildRunContext without erroring due to
# cheffish and chef-provisioning hooks having been loaded (on old versions of
# chef-client without the lazy hooks for those gems)
@__skip_method_checking = true
end
end
end
# fix to quiet constant redefined warnings
if defined?(Chef::RunContext::ChildRunContext::CHILD_STATE)
Chef::RunContext::ChildRunContext.send(:remove_const, :CHILD_STATE)
end
require 'chef_compat/monkeypatches/chef'
require 'chef_compat/monkeypatches/chef/exceptions'
require 'chef_compat/monkeypatches/chef/log'
require 'chef_compat/monkeypatches/chef/node'
require 'chef_compat/monkeypatches/chef/mixin/params_validate'
require 'chef_compat/monkeypatches/chef/property'
require 'chef_compat/monkeypatches/chef/provider'
require 'chef_compat/monkeypatches/chef/recipe' # copied from chef
require 'chef_compat/monkeypatches/chef/recipe_hook'
require 'chef_compat/monkeypatches/chef/resource'
require 'chef_compat/monkeypatches/chef/resource_builder'
require 'chef_compat/monkeypatches/chef/resource/lwrp_base'
require 'chef_compat/monkeypatches/chef/resource_collection'
require 'chef_compat/monkeypatches/chef/resource_collection/resource_list'
require 'chef_compat/monkeypatches/chef/resource_collection/resource_set'
require 'chef_compat/monkeypatches/chef/run_context' # copied from chef
require 'chef_compat/monkeypatches/chef/runner' # copied from chef
# fix for Chef::RunContext instance that has already been created
ObjectSpace.each_object(Chef::RunContext) do |run_context|
run_context.node.run_context = run_context
run_context.instance_variable_set(:@loaded_recipes_hash, {})
run_context.instance_variable_set(:@loaded_attributes_hash, {})
run_context.initialize_child_state
end

View File

@ -0,0 +1,33 @@
class Chef
NOT_PASSED = Object.new if !defined?(NOT_PASSED)
# Earlier versions of Chef didn't have this message
module ChefCompatDeprecation
def log_deprecation(message, location=nil)
if !location
# Pick the first caller that is *not* part of the Chef or ChefCompat gem,
# that's the thing the user wrote.
chef_compat_gem_path = File.expand_path("../../..", __FILE__)
chef_gem_path = File.expand_path("../..",::Chef::Resource.instance_method(:initialize).source_location[0])
caller(0..10).each do |c|
if !c.start_with?(chef_gem_path) && !c.start_with?(chef_compat_gem_path)
location = c
break
end
end
end
begin
super
# Bleagh. `super_method` doesn't exist on older rubies and I haven't
# figured out a way to check for its existence otherwise.
rescue NoMethodError
Chef::Log.warn(message)
end
end
end
class<<self
prepend ChefCompatDeprecation
end
end

View File

@ -0,0 +1,10 @@
require 'chef/exceptions'
class Chef
class Exceptions
# Used in Resource::ActionClass#load_current_resource to denote that
# the resource doesn't actually exist (for example, the file does not exist)
class CurrentValueDoesNotExist < RuntimeError; end unless defined?(CurrentValueDoesNotExist)
class CannotValidateStaticallyError < RuntimeError; end unless defined?(CannotValidateStaticallyError)
end
end

View File

@ -0,0 +1,30 @@
require 'chef/log'
# for now we have to patch this in everything
class Chef
class Log
def self.caller_location
# Pick the first caller that is *not* part of the Chef gem, that's the
# thing the user wrote.
compat_resource_path = File.expand_path("../../../../..", __FILE__)
chef_gem_path = Gem.loaded_specs['chef'].full_gem_path
caller(0..20).find { |c| !c.start_with?(compat_resource_path) && !c.start_with?(chef_gem_path) }
end
end
end
if Gem::Requirement.new('< 12.13.37').satisfied_by?(Gem::Version.new(Chef::VERSION))
# FIXME: why does this not match the implementation in Chef itself?
class Chef
class Log
module ChefCompatDeprecation
def deprecation(message, location=nil)
Chef.log_deprecation(message, location)
end
end
extend ChefCompatDeprecation
end
end
end

View File

@ -0,0 +1,17 @@
if Chef::VERSION.to_f >= 12.5 && Chef::VERSION.to_f <= 12.8
require 'chef/mixin/params_validate'
class Chef
module Mixin
module ParamsValidate
class SetOrReturnProperty < Chef::Property
# 12.9 introduced a new optional parameter to `get()` to avoid a nil-set warning.
# When their method gets called with 2 args, we need to ignore and call with 1.
alias_method :_original_get2, :get
def get(resource, *args)
_original_get2(resource)
end
end
end
end
end
end

View File

@ -0,0 +1,9 @@
class Chef
class Node
unless method_defined?(:set_cookbook_attribute)
def set_cookbook_attribute
# this implementation deliberately left blank - we don't need to do anything we just need to not fail
end
end
end
end

View File

@ -0,0 +1,15 @@
# 12.9 introduced a new optional parameter to `get()` to avoid a nil-set warning.
# We need to mimick it here.
if Chef::VERSION.to_f >= 12.5 && Chef::VERSION.to_f <= 12.8
require 'chef/property'
class Chef
class Property
# 12.9 introduced a new optional parameter to `get()` to avoid a nil-set warning.
# When their method gets called with 2 args, we need to ignore and call with 1.
alias_method :_original_get, :get
def get(resource, *args)
_original_get(resource)
end
end
end
end

View File

@ -0,0 +1,65 @@
require 'chef/provider'
require 'chef/provider/lwrp_base'
class Chef::Provider
if !defined?(InlineResources)
InlineResources = Chef::Provider::LWRPBase::InlineResources
end
module InlineResources
require 'chef/dsl/recipe'
require 'chef/dsl/platform_introspection'
require 'chef/dsl/data_query'
require 'chef/dsl/include_recipe'
include Chef::DSL::Recipe
include Chef::DSL::PlatformIntrospection
include Chef::DSL::DataQuery
include Chef::DSL::IncludeRecipe
unless Chef::Provider::InlineResources::ClassMethods.instance_method(:action).source_location[0] =~ /chefspec/
# Don't override action if chefspec is doing its thing
module ::ChefCompat
module Monkeypatches
module InlineResources
module ClassMethods
def action(name, &block)
super(name) { send("compile_action_#{name}") }
# We put the action in its own method so that super() works.
define_method("compile_action_#{name}", &block)
end
end
end
end
end
module ClassMethods
prepend ChefCompat::Monkeypatches::InlineResources::ClassMethods
end
end
end
end
class Chef
class Provider
class LWRPBase < Provider
if defined?(InlineResources)
module InlineResources
# since we upgrade the Chef::Runner and Chef::RunContext globally to >= 12.14 style classes, we need to also
# fix the use_inline_resources LWRPBase wrapper that creates a sub-resource collection with the ugpraded code
# from the Chef::Provider subclasses that do similar things in post-12.5 chef.
def recipe_eval_with_update_check(&block)
old_run_context = run_context
@run_context = run_context.create_child
return_value = instance_eval(&block)
Chef::Runner.new(run_context).converge
return_value
ensure
if run_context.resource_collection.any? { |r| r.updated? }
new_resource.updated_by_last_action(true)
end
@run_context = old_run_context
end
end
end
end
end
end

View File

@ -0,0 +1,118 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
if Gem::Requirement.new('< 12.16.42').satisfied_by?(Gem::Version.new(Chef::VERSION))
#--
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
# Copyright:: Copyright 2008-2016, Chef Software 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/dsl/recipe"
require "chef/mixin/from_file"
require "chef/mixin/deprecation"
class Chef
# == Chef::Recipe
# A Recipe object is the context in which Chef recipes are evaluated.
class Recipe
attr_accessor :cookbook_name, :recipe_name, :recipe, :params, :run_context
include Chef::DSL::Recipe
include Chef::Mixin::FromFile
include Chef::Mixin::Deprecation
# Parses a potentially fully-qualified recipe name into its
# cookbook name and recipe short name.
#
# For example:
# "aws::elastic_ip" returns [:aws, "elastic_ip"]
# "aws" returns [:aws, "default"]
# "::elastic_ip" returns [ current_cookbook, "elastic_ip" ]
#--
# TODO: Duplicates functionality of RunListItem
def self.parse_recipe_name(recipe_name, current_cookbook: nil)
case recipe_name
when /(.+?)::(.+)/
[ $1.to_sym, $2 ]
when /^::(.+)/
raise "current_cookbook is nil, cannot resolve #{recipe_name}" if current_cookbook.nil?
[ current_cookbook.to_sym, $1 ]
else
[ recipe_name.to_sym, "default" ]
end
end
def initialize(cookbook_name, recipe_name, run_context)
@cookbook_name = cookbook_name
@recipe_name = recipe_name
@run_context = run_context
# TODO: 5/19/2010 cw/tim: determine whether this can be removed
@params = Hash.new
end
# Used in DSL mixins
def node
run_context.node
end
# Used by the DSL to look up resources when executing in the context of a
# recipe.
def resources(*args)
run_context.resource_collection.find(*args)
end
# This was moved to Chef::Node#tag, redirecting here for compatibility
def tag(*tags)
run_context.node.tag(*tags)
end
# Returns true if the node is tagged with *all* of the supplied +tags+.
#
# === Parameters
# tags<Array>:: A list of tags
#
# === Returns
# true<TrueClass>:: If all the parameters are present
# false<FalseClass>:: If any of the parameters are missing
def tagged?(*tags)
tags.each do |tag|
return false unless run_context.node.tags.include?(tag)
end
true
end
# Removes the list of tags from the node.
#
# === Parameters
# tags<Array>:: A list of tags
#
# === Returns
# tags<Array>:: The current list of run_context.node.tags
def untag(*tags)
tags.each do |tag|
run_context.node.tags.delete(tag)
end
end
end
end
end

View File

@ -0,0 +1,20 @@
require 'chef/recipe'
require 'chef_compat/recipe'
class Chef::Recipe
# If the cookbook depends on compat_resource, create a ChefCompat::Recipe object
# instead of Chef::Recipe, for the extra goodies.
def self.new(cookbook_name, recipe_name, run_context)
if run_context &&
cookbook_name &&
recipe_name &&
run_context.cookbook_collection &&
run_context.cookbook_collection[cookbook_name] &&
run_context.cookbook_collection[cookbook_name].metadata.dependencies.has_key?('compat_resource') &&
self != ::ChefCompat::Recipe
::ChefCompat::Recipe.new(cookbook_name, recipe_name, run_context)
else
super
end
end
end

View File

@ -0,0 +1,156 @@
# this is NOT an AUTOGENERATED file
require 'chef/resource'
class Chef
class Resource
class UnresolvedSubscribes < self
# The full key ise given as the name in {Resource#subscribes}
alias_method :to_s, :name
alias_method :declared_key, :name
end
#
# Force a delayed notification into this resource's run_context.
#
# This should most likely be paired with action :nothing
#
# @param arg [Array[Symbol], Symbol] A list of actions (e.g. `:create`)
#
def delayed_action(arg)
arg = Array(arg).map(&:to_sym)
arg.map do |action|
validate(
{ action: action },
{ action: { kind_of: Symbol, equal_to: allowed_actions } }
)
# the resource effectively sends a delayed notification to itself
run_context.add_delayed_action(Notification.new(self, action, self))
end
end
def subscribes(action, resources, timing = :delayed)
resources = [resources].flatten
resources.each do |resource|
if resource.is_a?(String)
resource = UnresolvedSubscribes.new(resource, run_context)
end
if resource.run_context.nil?
resource.run_context = run_context
end
resource.notifies(action, self, timing)
end
true
end
def notifies(action, resource_spec, timing = :delayed)
# when using old-style resources(:template => "/foo.txt") style, you
# could end up with multiple resources.
validate_resource_spec!(resource_spec)
resources = [ resource_spec ].flatten
resources.each do |resource|
case timing.to_s
when "delayed"
notifies_delayed(action, resource)
when "immediate", "immediately"
notifies_immediately(action, resource)
when "before"
notifies_before(action, resource)
else
raise ArgumentError, "invalid timing: #{timing} for notifies(#{action}, #{resources.inspect}, #{timing}) resource #{self} "\
"Valid timings are: :delayed, :immediate, :immediately, :before"
end
end
true
end
#
# Iterates over all immediate and delayed notifications, calling
# resolve_resource_reference on each in turn, causing them to
# resolve lazy/forward references.
def resolve_notification_references
run_context.before_notifications(self).each { |n|
n.resolve_resource_reference(run_context.resource_collection)
}
run_context.immediate_notifications(self).each { |n|
n.resolve_resource_reference(run_context.resource_collection)
}
run_context.delayed_notifications(self).each {|n|
n.resolve_resource_reference(run_context.resource_collection)
}
end
# Helper for #notifies
def notifies_before(action, resource_spec)
run_context.notifies_before(Notification.new(resource_spec, action, self))
end
# Helper for #notifies
def notifies_immediately(action, resource_spec)
run_context.notifies_immediately(Notification.new(resource_spec, action, self))
end
# Helper for #notifies
def notifies_delayed(action, resource_spec)
run_context.notifies_delayed(Notification.new(resource_spec, action, self))
end
#
# Get the current actual value of this resource.
#
# This does not cache--a new value will be returned each time.
#
# @return A new copy of the resource, with values filled in from the actual
# current value.
#
def current_value
provider = provider_for_action(Array(action).first)
if provider.whyrun_mode? && !provider.whyrun_supported?
raise "Cannot retrieve #{self.class.current_resource} in why-run mode: #{provider} does not support why-run"
end
provider.load_current_resource
provider.current_resource
end
# These methods are necessary for new resources to initialize old ones properly
attr_reader :resource_initializing
def resource_initializing=(value)
if value
@resource_initializing = value
else
remove_instance_variable(:@resource_initializing)
end
end
if !respond_to?(:resource_name)
def self.resource_name(name=Chef::NOT_PASSED)
# Setter
if name != Chef::NOT_PASSED
# remove_canonical_dsl
# Set the resource_name and call provides
if name
name = name.to_sym
# If our class is not already providing this name, provide it.
# Commented out: use of resource_name and provides will need to be
# mutually exclusive in this world, generally.
# if !Chef::ResourceResolver.includes_handler?(name, self)
provides name#, canonical: true
# end
@resource_name = name
else
@resource_name = nil
end
end
@resource_name
end
def self.resource_name=(name)
resource_name(name)
end
end
end
end

View File

@ -0,0 +1,60 @@
require 'chef_compat/resource/lwrp_base'
require 'chef/resource/lwrp_base'
module ChefCompat
module Monkeypatches
#
# NOTE: LOTS OF METAPROGRAMMING HERE. NOT FOR FAINT OF HEART.
#
# Add an empty module to Class so we can temporarily override it in build_from_file
module Class
end
class<<::Class
prepend(ChefCompat::Monkeypatches::Class)
end
module Chef
module Resource
module LWRPBase
def build_from_file(cookbook_name, filename, run_context)
# If the cookbook this LWRP is from depends on compat_resource, fix its LWRPs up real good
if run_context.cookbook_collection[cookbook_name].metadata.dependencies.has_key?('compat_resource')
# All cookbooks do Class.new(Chef::Resource::LWRPBase). Change Class.new
# temporarily to translate Chef::Resource::LWRPBase to ChefCompat::Resource
ChefCompat::Monkeypatches::Class.module_eval do
def new(*args, &block)
# Trick it! Use ChefCompat::Resource instead of Chef::Resource::LWRPBase
if args == [ ::Chef::Resource::LWRPBase ]
ChefCompat::Monkeypatches::Class.module_eval do
remove_method(:new) if method_defined?(:new)
end
args = [ ChefCompat::Resource::LWRPBase ]
end
super(*args, &block)
end
end
begin
# Call the actual build_from_file
super
ensure
class<<ChefCompat::Monkeypatches::Class
remove_method(:new) if method_defined?(:new)
end
end
else
# Call the actual build_from_file
super
end
end
end
class <<::Chef::Resource::LWRPBase
prepend(LWRPBase)
end
end
end
end
end

View File

@ -0,0 +1,167 @@
#
# Author:: Lamont Granquist (<lamont@chef.io>)
# Copyright:: Copyright 2015-2016, Chef Software, 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.
#
# XXX: we now have two copies of this file in the compat_resource cookbook. I'm uncertain if this is a
# bug or a feature, and I suspect it is actually a feature. The point of this file is that for all
# resources and cookbooks the global Chef::ResourceBuilder class must be upgraded to at least the
# 12.10.24 version. The point of the other copy is that for compat_resource cookbooks all their
# resources should be using the lastest version that has been sync'd. So these two files should
# diverge as times goes on. I believe that is the correct behavior and that we want to have both
# files in this cookbook.
# NOTE: this was extracted from the Recipe DSL mixin, relevant specs are in spec/unit/recipe_spec.rb
if Gem::Requirement.new("< 12.10.24").satisfied_by?(Gem::Version.new(Chef::VERSION))
begin
require 'chef/resource_builder'
# we use the LoadError this creates on early 12.x to not monkeypatch chef client versions that don't have Chef::ResourceBuilder
# (it is lazily included and doesn't appear until compile time so we can't resolve the symbol during library loading)
class Chef
class ResourceBuilder
attr_reader :type
attr_reader :name
attr_reader :created_at
attr_reader :params
attr_reader :run_context
attr_reader :cookbook_name
attr_reader :recipe_name
attr_reader :enclosing_provider
attr_reader :resource
# FIXME (ruby-2.1 syntax): most of these are mandatory
def initialize(type:nil, name:nil, created_at: nil, params: nil, run_context: nil, cookbook_name: nil, recipe_name: nil, enclosing_provider: nil)
@type = type
@name = name
@created_at = created_at
@params = params
@run_context = run_context
@cookbook_name = cookbook_name
@recipe_name = recipe_name
@enclosing_provider = enclosing_provider
end
def build(&block)
raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil?
@resource = resource_class.new(name, run_context)
if resource.resource_name.nil?
raise Chef::Exceptions::InvalidResourceSpecification, "#{resource}.resource_name is `nil`! Did you forget to put `provides :blah` or `resource_name :blah` in your resource class?"
end
resource.source_line = created_at
resource.declared_type = type
# If we have a resource like this one, we want to steal its state
# This behavior is very counter-intuitive and should be removed.
# See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694
# Moved to this location to resolve CHEF-5052, https://tickets.opscode.com/browse/CHEF-5052
if prior_resource
resource.load_from(prior_resource)
end
resource.cookbook_name = cookbook_name
resource.recipe_name = recipe_name
# Determine whether this resource is being created in the context of an enclosing Provider
resource.enclosing_provider = enclosing_provider
# XXX: this is required for definition params inside of the scope of a
# subresource to work correctly.
resource.params = params
# Evaluate resource attribute DSL
if block_given?
resource.resource_initializing = true
begin
resource.instance_eval(&block)
ensure
resource.resource_initializing = false
end
end
# emit a cloned resource warning if it is warranted
if prior_resource
if is_trivial_resource?(prior_resource) && identicalish_resources?(prior_resource, resource)
emit_harmless_cloning_debug
else
emit_cloned_resource_warning
end
end
# Run optional resource hook
resource.after_created
resource
end
private
def resource_class
# Checks the new platform => short_name => resource mapping initially
# then fall back to the older approach (Chef::Resource.const_get) for
# backward compatibility
@resource_class ||= Chef::Resource.resource_for_node(type, run_context.node)
end
def is_trivial_resource?(resource)
identicalish_resources?(resource_class.new(name, run_context), resource)
end
# this is an equality test specific to checking for 3694 cloning warnings
def identicalish_resources?(first, second)
skipped_ivars = [ :@source_line, :@cookbook_name, :@recipe_name, :@params, :@elapsed_time, :@declared_type ]
checked_ivars = ( first.instance_variables | second.instance_variables ) - skipped_ivars
non_matching_ivars = checked_ivars.reject do |iv|
if iv == :@action && ( [first.instance_variable_get(iv)].flatten == [:nothing] || [second.instance_variable_get(iv)].flatten == [:nothing] )
# :nothing action on either side of the comparison always matches
true
else
first.instance_variable_get(iv) == second.instance_variable_get(iv)
end
end
Chef::Log.debug("ivars which did not match with the prior resource: #{non_matching_ivars}")
non_matching_ivars.empty?
end
def emit_cloned_resource_warning
Chef::Log.warn("Cloning resource attributes for #{resource} from prior resource (CHEF-3694)")
Chef::Log.warn("Previous #{prior_resource}: #{prior_resource.source_line}") if prior_resource.source_line
Chef::Log.warn("Current #{resource}: #{resource.source_line}") if resource.source_line
end
def emit_harmless_cloning_debug
Chef::Log.debug("Harmless resource cloning from #{prior_resource}:#{prior_resource.source_line} to #{resource}:#{resource.source_line}")
end
def prior_resource
@prior_resource ||=
begin
key = "#{type}[#{name}]"
run_context.resource_collection.lookup_local(key)
rescue Chef::Exceptions::ResourceNotFound
nil
end
end
end
end
rescue LoadError
# cool we're just on early chef 12.x, nothing to do -- we don't have to worry because there's also not parent_run_context pointer, so we don't have to
# use lookup_local to avoid resource cloning shit out of the parent run_context. the resource collection's lookup() method will always use lookup_local
# over lookup_recursive.
end
end

View File

@ -0,0 +1,103 @@
#
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
# Copyright:: Copyright 2008-2016, Chef Software 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/resource_collection/resource_set"
require "chef/resource_collection/resource_list"
require "chef/resource_collection"
require "chef/exceptions"
module ChefCompat
module Monkeypatches
module Chef
module ResourceCollection
module RecursiveNotificationLookup
#
# Copied verbatim from Chef 12.10.24
#
attr_accessor :run_context
def initialize(run_context = nil)
super()
@run_context = run_context
end
def lookup_local(key)
resource_set.lookup(key)
end
def find_local(*args)
resource_set.find(*args)
end
def lookup(key)
if run_context.nil?
lookup_local(key)
else
lookup_recursive(run_context, key)
end
end
def find(*args)
if run_context.nil?
find_local(*args)
else
find_recursive(run_context, *args)
end
end
private
def lookup_recursive(rc, key)
rc.resource_collection.send(:resource_set).lookup(key)
rescue ::Chef::Exceptions::ResourceNotFound
raise if !rc.respond_to?(:parent_run_context) || rc.parent_run_context.nil?
lookup_recursive(rc.parent_run_context, key)
end
def find_recursive(rc, *args)
rc.resource_collection.send(:resource_set).find(*args)
rescue ::Chef::Exceptions::ResourceNotFound
raise if !rc.respond_to?(:parent_run_context) || rc.parent_run_context.nil?
find_recursive(rc.parent_run_context, *args)
end
end
module DeleteResources
#
# Copied verbatim from Chef 12.10.24
#
def delete(key)
resource_list.delete(key)
resource_set.delete(key)
end
end
end
end
end
end
class Chef::ResourceCollection
unless method_defined?(:lookup_local)
prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::RecursiveNotificationLookup
end
unless method_defined?(:delete)
prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::DeleteResources
end
end

View File

@ -0,0 +1,49 @@
#
# Author:: Tyler Ball (<tball@chef.io>)
# Copyright:: Copyright 2014-2016, Chef Software, 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/resource_collection/resource_list"
require "chef/exceptions"
module ChefCompat
module Monkeypatches
module Chef
module ResourceCollection
module ResourceList
module DeleteResource
# Copied verbatim from Chef 12.10.4
def delete(key)
raise ArgumentError, "Must pass a Chef::Resource or String to delete" unless key.is_a?(String) || key.is_a?(Chef::Resource)
key = key.to_s
ret = @resources.reject! { |r| r.to_s == key }
if ret.nil?
raise ::Chef::Exceptions::ResourceNotFound, "Cannot find a resource matching #{key} (did you define it first?)"
end
ret
end
end
end
end
end
end
end
class Chef::ResourceCollection::ResourceList
unless method_defined?(:delete)
prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::ResourceList::DeleteResource
end
end

View File

@ -0,0 +1,49 @@
#
# Author:: Tyler Ball (<tball@chef.io>)
# Copyright:: Copyright 2014-2016, Chef Software, 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/resource_collection/resource_list"
require "chef/exceptions"
module ChefCompat
module Monkeypatches
module Chef
module ResourceCollection
module ResourceSet
module DeleteResource
def delete(key)
raise ArgumentError, "Must pass a Chef::Resource or String to delete" unless key.is_a?(String) || key.is_a?(Chef::Resource)
key = key.to_s
res = @resources_by_key.delete(key)
if res == @resources_by_key.default
raise Chef::Exceptions::ResourceNotFound, "Cannot find a resource matching #{key} (did you define it first?)"
end
res
end
end
end
end
end
end
end
class Chef::ResourceCollection::ResourceSet
unless method_defined?(:delete)
prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::ResourceSet::DeleteResource
end
end

View File

@ -0,0 +1,691 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
if Gem::Requirement.new('< 12.16.42').satisfied_by?(Gem::Version.new(Chef::VERSION))
#
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
# Author:: Tim Hinderliter (<tim@chef.io>)
# Copyright:: Copyright 2008-2016, Chef Software 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/resource_collection"
require "chef/cookbook_version"
require "chef/node"
require "chef/role"
require "chef/log"
require "chef/recipe"
require "chef/run_context/cookbook_compiler"
require "chef/event_dispatch/events_output_stream"
require "forwardable"
class Chef
# == Chef::RunContext
# Value object that loads and tracks the context of a Chef run
class RunContext
#
# Global state
#
#
# The node for this run
#
# @return [Chef::Node]
#
attr_reader :node
#
# The set of cookbooks involved in this run
#
# @return [Chef::CookbookCollection]
#
attr_reader :cookbook_collection
#
# Resource Definitions for this run. Populated when the files in
# +definitions/+ are evaluated (this is triggered by #load).
#
# @return [Array[Chef::ResourceDefinition]]
#
attr_reader :definitions
#
# Event dispatcher for this run.
#
# @return [Chef::EventDispatch::Dispatcher]
#
attr_reader :events
#
# Hash of factoids for a reboot request.
#
# @return [Hash]
#
attr_accessor :reboot_info
#
# Scoped state
#
#
# The parent run context.
#
# @return [Chef::RunContext] The parent run context, or `nil` if this is the
# root context.
#
attr_reader :parent_run_context
#
# The root run context.
#
# @return [Chef::RunContext] The root run context.
#
def root_run_context
rc = self
rc = rc.parent_run_context until rc.parent_run_context.nil?
rc
end
#
# The collection of resources intended to be converged (and able to be
# notified).
#
# @return [Chef::ResourceCollection]
#
# @see CookbookCompiler
#
attr_reader :resource_collection
#
# The list of control groups to execute during the audit phase
#
attr_reader :audits
#
# Notification handling
#
#
# A Hash containing the before notifications triggered by resources
# during the converge phase of the chef run.
#
# @return [Hash[String, Array[Chef::Resource::Notification]]] A hash from
# <notifying resource name> => <list of notifications it sent>
#
attr_reader :before_notification_collection
#
# A Hash containing the immediate notifications triggered by resources
# during the converge phase of the chef run.
#
# @return [Hash[String, Array[Chef::Resource::Notification]]] A hash from
# <notifying resource name> => <list of notifications it sent>
#
attr_reader :immediate_notification_collection
#
# A Hash containing the delayed (end of run) notifications triggered by
# resources during the converge phase of the chef run.
#
# @return [Hash[String, Array[Chef::Resource::Notification]]] A hash from
# <notifying resource name> => <list of notifications it sent>
#
attr_reader :delayed_notification_collection
#
# An Array containing the delayed (end of run) notifications triggered by
# resources during the converge phase of the chef run.
#
# @return [Array[Chef::Resource::Notification]] An array of notification objects
#
attr_reader :delayed_actions
# Creates a new Chef::RunContext object and populates its fields. This object gets
# used by the Chef Server to generate a fully compiled recipe list for a node.
#
# @param node [Chef::Node] The node to run against.
# @param cookbook_collection [Chef::CookbookCollection] The cookbooks
# involved in this run.
# @param events [EventDispatch::Dispatcher] The event dispatcher for this
# run.
#
def initialize(node, cookbook_collection, events)
@node = node
@cookbook_collection = cookbook_collection
@events = events
node.run_context = self
node.set_cookbook_attribute
@definitions = Hash.new
@loaded_recipes_hash = {}
@loaded_attributes_hash = {}
@reboot_info = {}
@cookbook_compiler = nil
@delayed_actions = []
initialize_child_state
end
#
# Triggers the compile phase of the chef run.
#
# @param run_list_expansion [Chef::RunList::RunListExpansion] The run list.
# @see Chef::RunContext::CookbookCompiler
#
def load(run_list_expansion)
@cookbook_compiler = CookbookCompiler.new(self, run_list_expansion, events)
cookbook_compiler.compile
end
#
# Initialize state that applies to both Chef::RunContext and Chef::ChildRunContext
#
def initialize_child_state
@audits = {}
@resource_collection = Chef::ResourceCollection.new(self)
@before_notification_collection = Hash.new { |h, k| h[k] = [] }
@immediate_notification_collection = Hash.new { |h, k| h[k] = [] }
@delayed_notification_collection = Hash.new { |h, k| h[k] = [] }
@delayed_actions = []
end
#
# Adds an before notification to the +before_notification_collection+.
#
# @param [Chef::Resource::Notification] The notification to add.
#
def notifies_before(notification)
# Note for the future, notification.notifying_resource may be an instance
# of Chef::Resource::UnresolvedSubscribes when calling {Resource#subscribes}
# with a string value.
before_notification_collection[notification.notifying_resource.declared_key] << notification
end
#
# Adds an immediate notification to the +immediate_notification_collection+.
#
# @param [Chef::Resource::Notification] The notification to add.
#
def notifies_immediately(notification)
# Note for the future, notification.notifying_resource may be an instance
# of Chef::Resource::UnresolvedSubscribes when calling {Resource#subscribes}
# with a string value.
immediate_notification_collection[notification.notifying_resource.declared_key] << notification
end
#
# Adds a delayed notification to the +delayed_notification_collection+.
#
# @param [Chef::Resource::Notification] The notification to add.
#
def notifies_delayed(notification)
# Note for the future, notification.notifying_resource may be an instance
# of Chef::Resource::UnresolvedSubscribes when calling {Resource#subscribes}
# with a string value.
delayed_notification_collection[notification.notifying_resource.declared_key] << notification
end
#
# Adds a delayed action to the +delayed_actions+.
#
def add_delayed_action(notification)
if delayed_actions.any? { |existing_notification| existing_notification.duplicates?(notification) }
Chef::Log.info( "#{notification.notifying_resource} not queuing delayed action #{notification.action} on #{notification.resource}"\
" (delayed), as it's already been queued")
else
delayed_actions << notification
end
end
#
# Get the list of before notifications sent by the given resource.
#
# @return [Array[Notification]]
#
def before_notifications(resource)
return before_notification_collection[resource.declared_key]
end
#
# Get the list of immediate notifications sent by the given resource.
#
# @return [Array[Notification]]
#
def immediate_notifications(resource)
return immediate_notification_collection[resource.declared_key]
end
#
# Get the list of delayed (end of run) notifications sent by the given
# resource.
#
# @return [Array[Notification]]
#
def delayed_notifications(resource)
return delayed_notification_collection[resource.declared_key]
end
#
# Cookbook and recipe loading
#
#
# Evaluates the recipes +recipe_names+. Used by DSL::IncludeRecipe
#
# @param recipe_names [Array[String]] The list of recipe names (e.g.
# 'my_cookbook' or 'my_cookbook::my_resource').
# @param current_cookbook The cookbook we are currently running in.
#
# @see DSL::IncludeRecipe#include_recipe
#
def include_recipe(*recipe_names, current_cookbook: nil)
result_recipes = Array.new
recipe_names.flatten.each do |recipe_name|
if result = load_recipe(recipe_name, current_cookbook: current_cookbook)
result_recipes << result
end
end
result_recipes
end
#
# Evaluates the recipe +recipe_name+. Used by DSL::IncludeRecipe
#
# TODO I am sort of confused why we have both this and include_recipe ...
# I don't see anything different beyond accepting and returning an
# array of recipes.
#
# @param recipe_names [Array[String]] The recipe name (e.g 'my_cookbook' or
# 'my_cookbook::my_resource').
# @param current_cookbook The cookbook we are currently running in.
#
# @return A truthy value if the load occurred; `false` if already loaded.
#
# @see DSL::IncludeRecipe#load_recipe
#
def load_recipe(recipe_name, current_cookbook: nil)
Chef::Log.debug("Loading recipe #{recipe_name} via include_recipe")
cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name, current_cookbook: current_cookbook)
if unreachable_cookbook?(cookbook_name) # CHEF-4367
Chef::Log.warn(<<-ERROR_MESSAGE)
MissingCookbookDependency:
Recipe `#{recipe_name}` is not in the run_list, and cookbook '#{cookbook_name}'
is not a dependency of any cookbook in the run_list. To load this recipe,
first add a dependency on cookbook '#{cookbook_name}' in the cookbook you're
including it from in that cookbook's metadata.
ERROR_MESSAGE
end
if loaded_fully_qualified_recipe?(cookbook_name, recipe_short_name)
Chef::Log.debug("I am not loading #{recipe_name}, because I have already seen it.")
false
else
loaded_recipe(cookbook_name, recipe_short_name)
node.loaded_recipe(cookbook_name, recipe_short_name)
cookbook = cookbook_collection[cookbook_name]
cookbook.load_recipe(recipe_short_name, self)
end
end
#
# Load the given recipe from a filename.
#
# @param recipe_file [String] The recipe filename.
#
# @return [Chef::Recipe] The loaded recipe.
#
# @raise [Chef::Exceptions::RecipeNotFound] If the file does not exist.
#
def load_recipe_file(recipe_file)
if !File.exist?(recipe_file)
raise Chef::Exceptions::RecipeNotFound, "could not find recipe file #{recipe_file}"
end
Chef::Log.debug("Loading recipe file #{recipe_file}")
recipe = Chef::Recipe.new("@recipe_files", recipe_file, self)
recipe.from_file(recipe_file)
recipe
end
#
# Look up an attribute filename.
#
# @param cookbook_name [String] The cookbook name of the attribute file.
# @param attr_file_name [String] The attribute file's name (not path).
#
# @return [String] The filename.
#
# @see DSL::IncludeAttribute#include_attribute
#
# @raise [Chef::Exceptions::CookbookNotFound] If the cookbook could not be found.
# @raise [Chef::Exceptions::AttributeNotFound] If the attribute file could not be found.
#
def resolve_attribute(cookbook_name, attr_file_name)
cookbook = cookbook_collection[cookbook_name]
raise Chef::Exceptions::CookbookNotFound, "could not find cookbook #{cookbook_name} while loading attribute #{name}" unless cookbook
attribute_filename = cookbook.attribute_filenames_by_short_filename[attr_file_name]
raise Chef::Exceptions::AttributeNotFound, "could not find filename for attribute #{attr_file_name} in cookbook #{cookbook_name}" unless attribute_filename
attribute_filename
end
#
# A list of all recipes that have been loaded.
#
# This is stored internally as a Hash, so ordering is predictable.
#
# TODO is the above statement true in a 1.9+ ruby world? Is it relevant?
#
# @return [Array[String]] A list of recipes in fully qualified form, e.g.
# the recipe "nginx" will be given as "nginx::default".
#
# @see #loaded_recipe? To determine if a particular recipe has been loaded.
#
def loaded_recipes
loaded_recipes_hash.keys
end
#
# A list of all attributes files that have been loaded.
#
# Stored internally using a Hash, so order is predictable.
#
# TODO is the above statement true in a 1.9+ ruby world? Is it relevant?
#
# @return [Array[String]] A list of attribute file names in fully qualified
# form, e.g. the "nginx" will be given as "nginx::default".
#
def loaded_attributes
loaded_attributes_hash.keys
end
#
# Find out if a given recipe has been loaded.
#
# @param cookbook [String] Cookbook name.
# @param recipe [String] Recipe name.
#
# @return [Boolean] `true` if the recipe has been loaded, `false` otherwise.
#
def loaded_fully_qualified_recipe?(cookbook, recipe)
loaded_recipes_hash.has_key?("#{cookbook}::#{recipe}")
end
#
# Find out if a given recipe has been loaded.
#
# @param recipe [String] Recipe name. "nginx" and "nginx::default" yield
# the same results.
#
# @return [Boolean] `true` if the recipe has been loaded, `false` otherwise.
#
def loaded_recipe?(recipe)
cookbook, recipe_name = Chef::Recipe.parse_recipe_name(recipe)
loaded_fully_qualified_recipe?(cookbook, recipe_name)
end
#
# Mark a given recipe as having been loaded.
#
# @param cookbook [String] Cookbook name.
# @param recipe [String] Recipe name.
#
def loaded_recipe(cookbook, recipe)
loaded_recipes_hash["#{cookbook}::#{recipe}"] = true
end
#
# Find out if a given attribute file has been loaded.
#
# @param cookbook [String] Cookbook name.
# @param attribute_file [String] Attribute file name.
#
# @return [Boolean] `true` if the recipe has been loaded, `false` otherwise.
#
def loaded_fully_qualified_attribute?(cookbook, attribute_file)
loaded_attributes_hash.has_key?("#{cookbook}::#{attribute_file}")
end
#
# Mark a given attribute file as having been loaded.
#
# @param cookbook [String] Cookbook name.
# @param attribute_file [String] Attribute file name.
#
def loaded_attribute(cookbook, attribute_file)
loaded_attributes_hash["#{cookbook}::#{attribute_file}"] = true
end
##
# Cookbook File Introspection
#
# Find out if the cookbook has the given template.
#
# @param cookbook [String] Cookbook name.
# @param template_name [String] Template name.
#
# @return [Boolean] `true` if the template is in the cookbook, `false`
# otherwise.
# @see Chef::CookbookVersion#has_template_for_node?
#
def has_template_in_cookbook?(cookbook, template_name)
cookbook = cookbook_collection[cookbook]
cookbook.has_template_for_node?(node, template_name)
end
#
# Find out if the cookbook has the given file.
#
# @param cookbook [String] Cookbook name.
# @param cb_file_name [String] File name.
#
# @return [Boolean] `true` if the file is in the cookbook, `false`
# otherwise.
# @see Chef::CookbookVersion#has_cookbook_file_for_node?
#
def has_cookbook_file_in_cookbook?(cookbook, cb_file_name)
cookbook = cookbook_collection[cookbook]
cookbook.has_cookbook_file_for_node?(node, cb_file_name)
end
#
# Find out whether the given cookbook is in the cookbook dependency graph.
#
# @param cookbook_name [String] Cookbook name.
#
# @return [Boolean] `true` if the cookbook is reachable, `false` otherwise.
#
# @see Chef::CookbookCompiler#unreachable_cookbook?
def unreachable_cookbook?(cookbook_name)
cookbook_compiler.unreachable_cookbook?(cookbook_name)
end
#
# Open a stream object that can be printed into and will dispatch to events
#
# @param name [String] The name of the stream.
# @param options [Hash] Other options for the stream.
#
# @return [EventDispatch::EventsOutputStream] The created stream.
#
# @yield If a block is passed, it will be run and the stream will be closed
# afterwards.
# @yieldparam stream [EventDispatch::EventsOutputStream] The created stream.
#
def open_stream(name: nil, **options)
stream = EventDispatch::EventsOutputStream.new(events, name: name, **options)
if block_given?
begin
yield stream
ensure
stream.close
end
else
stream
end
end
# there are options for how to handle multiple calls to these functions:
# 1. first call always wins (never change reboot_info once set).
# 2. last call always wins (happily change reboot_info whenever).
# 3. raise an exception on the first conflict.
# 4. disable reboot after this run if anyone ever calls :cancel.
# 5. raise an exception on any second call.
# 6. ?
def request_reboot(reboot_info)
Chef::Log.info "Changing reboot status from #{self.reboot_info.inspect} to #{reboot_info.inspect}"
@reboot_info = reboot_info
end
def cancel_reboot
Chef::Log.info "Changing reboot status from #{reboot_info.inspect} to {}"
@reboot_info = {}
end
def reboot_requested?
reboot_info.size > 0
end
#
# Create a child RunContext.
#
def create_child
ChildRunContext.new(self)
end
# @api private
attr_writer :resource_collection
protected
attr_reader :cookbook_compiler
attr_reader :loaded_attributes_hash
attr_reader :loaded_recipes_hash
module Deprecated
###
# These need to be settable so deploy can run a resource_collection
# independent of any cookbooks via +recipe_eval+
def audits=(value)
Chef.log_deprecation("Setting run_context.audits will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.")
@audits = value
end
def immediate_notification_collection=(value)
Chef.log_deprecation("Setting run_context.immediate_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.")
@immediate_notification_collection = value
end
def delayed_notification_collection=(value)
Chef.log_deprecation("Setting run_context.delayed_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.")
@delayed_notification_collection = value
end
end
prepend Deprecated
#
# A child run context. Delegates all root context calls to its parent.
#
# @api private
#
class ChildRunContext < RunContext
extend Forwardable
def_delegators :parent_run_context, *%w{
cancel_reboot
config
cookbook_collection
cookbook_compiler
definitions
events
has_cookbook_file_in_cookbook?
has_template_in_cookbook?
load
loaded_attribute
loaded_attributes
loaded_attributes_hash
loaded_fully_qualified_attribute?
loaded_fully_qualified_recipe?
loaded_recipe
loaded_recipe?
loaded_recipes
loaded_recipes_hash
node
open_stream
reboot_info
reboot_info=
reboot_requested?
request_reboot
resolve_attribute
unreachable_cookbook?
}
def initialize(parent_run_context)
@parent_run_context = parent_run_context
# We don't call super, because we don't bother initializing stuff we're
# going to delegate to the parent anyway. Just initialize things that
# every instance needs.
initialize_child_state
end
CHILD_STATE = %w{
audits
audits=
create_child
add_delayed_action
delayed_actions
delayed_notification_collection
delayed_notification_collection=
delayed_notifications
immediate_notification_collection
immediate_notification_collection=
immediate_notifications
before_notification_collection
before_notifications
include_recipe
initialize_child_state
load_recipe
load_recipe_file
notifies_before
notifies_immediately
notifies_delayed
parent_run_context
root_run_context
resource_collection
resource_collection=
}.map { |x| x.to_sym }
# Verify that we didn't miss any methods
unless @__skip_method_checking # hook specifically for compat_resource
missing_methods = superclass.instance_methods(false) - instance_methods(false) - CHILD_STATE
if !missing_methods.empty?
raise "ERROR: not all methods of RunContext accounted for in ChildRunContext! All methods must be marked as child methods with CHILD_STATE or delegated to the parent_run_context. Missing #{missing_methods.join(", ")}."
end
end
end
end
end
end

View File

@ -0,0 +1,153 @@
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!!
#
# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
#
if Gem::Requirement.new('< 12.16.42').satisfied_by?(Gem::Version.new(Chef::VERSION))
#--
# Author:: Adam Jacob (<adam@chef.io>)
# Author:: Christopher Walters (<cw@chef.io>)
# Author:: Tim Hinderliter (<tim@chef.io>)
# Copyright:: Copyright 2008-2016, Chef Software 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/exceptions"
require "chef/mixin/params_validate"
require "chef/node"
require "chef/resource_collection"
class Chef
# == Chef::Runner
# This class is responsible for executing the steps in a Chef run.
class Runner
attr_reader :run_context
include Chef::Mixin::ParamsValidate
def initialize(run_context)
@run_context = run_context
end
def delayed_actions
@run_context.delayed_actions
end
def events
@run_context.events
end
# Determine the appropriate provider for the given resource, then
# execute it.
def run_action(resource, action, notification_type = nil, notifying_resource = nil)
# If there are any before notifications, why-run the resource
# and notify anyone who needs notifying
before_notifications = run_context.before_notifications(resource) || []
unless before_notifications.empty?
forced_why_run do
Chef::Log.info("#{resource} running why-run #{action} action to support before action")
resource.run_action(action, notification_type, notifying_resource)
end
if resource.updated_by_last_action?
before_notifications.each do |notification|
Chef::Log.info("#{resource} sending #{notification.action} action to #{notification.resource} (before)")
run_action(notification.resource, notification.action, :before, resource)
end
resource.updated_by_last_action(false)
end
end
# Actually run the action for realsies
resource.run_action(action, notification_type, notifying_resource)
# Execute any immediate and queue up any delayed notifications
# associated with the resource, but only if it was updated *this time*
# we ran an action on it.
if resource.updated_by_last_action?
run_context.immediate_notifications(resource).each do |notification|
Chef::Log.info("#{resource} sending #{notification.action} action to #{notification.resource} (immediate)")
run_action(notification.resource, notification.action, :immediate, resource)
end
run_context.delayed_notifications(resource).each do |notification|
# send the notification to the run_context of the receiving resource
notification.resource.run_context.add_delayed_action(notification)
end
end
end
# Iterates over the +resource_collection+ in the +run_context+ calling
# +run_action+ for each resource in turn.
def converge
# Resolve all lazy/forward references in notifications
run_context.resource_collection.each do |resource|
resource.resolve_notification_references
end
# Execute each resource.
run_context.resource_collection.execute_each_resource do |resource|
Array(resource.action).each { |action| run_action(resource, action) }
end
rescue Exception => e
Chef::Log.info "Running queued delayed notifications before re-raising exception"
run_delayed_notifications(e)
else
run_delayed_notifications(nil)
true
end
private
# Run all our :delayed actions
def run_delayed_notifications(error = nil)
collected_failures = Exceptions::MultipleFailures.new
collected_failures.client_run_failure(error) unless error.nil?
delayed_actions.each do |notification|
result = run_delayed_notification(notification)
if result.kind_of?(Exception)
collected_failures.notification_failure(result)
end
end
collected_failures.raise!
end
def run_delayed_notification(notification)
Chef::Log.info( "#{notification.notifying_resource} sending #{notification.action}"\
" action to #{notification.resource} (delayed)")
# Struct of resource/action to call
run_action(notification.resource, notification.action, :delayed)
true
rescue Exception => e
e
end
# helper to run a block of code with why_run forced to true and then restore it correctly
def forced_why_run
saved = Chef::Config[:why_run]
Chef::Config[:why_run] = true
yield
ensure
Chef::Config[:why_run] = saved
end
end
end
end

View File

@ -0,0 +1,6 @@
require 'chef_compat/copied_from_chef/chef/property'
module ChefCompat
class Property < ChefCompat::CopiedFromChef::Chef::Property
end
end

View File

@ -0,0 +1,8 @@
require 'chef/recipe'
require 'chef_compat/copied_from_chef/chef/dsl/recipe'
module ChefCompat
class Recipe < Chef::Recipe
include ChefCompat::CopiedFromChef::Chef::DSL::Recipe::FullDSL
end
end

View File

@ -0,0 +1,56 @@
require 'chef_compat/monkeypatches'
require 'chef_compat/copied_from_chef/chef/resource'
# We do NOT want action defined if chefspec is engaged
if Chef::Provider::InlineResources::ClassMethods.instance_method(:action).source_location[0] =~ /chefspec/
ChefCompat::CopiedFromChef::Chef::Provider::InlineResources::ClassMethods.instance_eval do
remove_method(:action)
end
end
module ChefCompat
class Resource < ChefCompat::CopiedFromChef::Chef::Resource
def initialize(*args, &block)
super
# @resource_name is used in earlier Chef versions
@resource_name = self.class.resource_name
end
# Things we'll need to define ourselves:
# 1. provider
# 2. resource_name
def provider(*args, &block)
super || self.class.action_class
end
def provider=(arg)
provider(arg)
end
if !respond_to?(:resource_name)
def self.resource_name(name=Chef::NOT_PASSED)
# Setter
if name != Chef::NOT_PASSED
# remove_canonical_dsl
# Set the resource_name and call provides
if name
name = name.to_sym
# If our class is not already providing this name, provide it.
# Commented out: use of resource_name and provides will need to be
# mutually exclusive in this world, generally.
# if !Chef::ResourceResolver.includes_handler?(name, self)
provides name#, canonical: true
# end
@resource_name = name
else
@resource_name = nil
end
end
@resource_name
end
def self.resource_name=(name)
resource_name(name)
end
end
end
end

View File

@ -0,0 +1,44 @@
require 'chef_compat/resource'
require 'chef_compat/copied_from_chef/chef/resource'
require 'chef/mixin/convert_to_class_name'
require 'chef/mixin/from_file'
module ChefCompat
class Resource < ChefCompat::CopiedFromChef::Chef::Resource
class LWRPBase < ChefCompat::Resource
class<<self
include Chef::Mixin::ConvertToClassName
include Chef::Mixin::FromFile
alias :attribute :property
# Adds +action_names+ to the list of valid actions for this resource.
# Does not include superclass's action list when appending.
def actions(*action_names)
action_names = action_names.flatten
if !action_names.empty? && !@allowed_actions
self.allowed_actions = ([ :nothing ] + action_names).uniq
else
allowed_actions(*action_names)
end
end
alias :actions= :allowed_actions=
# @deprecated
def valid_actions(*args)
Chef::Log.warn("`valid_actions' is deprecated, please use allowed_actions `instead'!")
allowed_actions(*args)
end
# Set the run context on the class. Used to provide access to the node
# during class definition.
attr_accessor :run_context
def node
run_context ? run_context.node : nil
end
end
end
end
end

View File

@ -0,0 +1,3 @@
module ChefCompat
CHEF_UPSTREAM_VERSION="12.16.42"
end

View File

@ -0,0 +1,35 @@
require "chef/version"
if Gem::Requirement.new(">= 12.0").satisfied_by?(Gem::Version.new(Chef::VERSION))
require 'chef_compat/resource'
require 'chef_compat/property'
require 'chef_compat/mixin/properties'
resources_dir = File.expand_path("chef_compat/copied_from_chef/chef/resource", File.dirname(__FILE__))
providers_dir = File.expand_path("chef_compat/copied_from_chef/chef/provider", File.dirname(__FILE__))
Dir["#{resources_dir}/*.rb"].each {|file| require file }
Dir["#{providers_dir}/*.rb"].each {|file| require file }
else
class Chef
class Resource
def self.property(args, &block)
raise_chef_11_error
end
def self.resource_name(args, &block)
raise_chef_11_error
end
def self.action(args, &block)
raise_chef_11_error
end
def self.raise_chef_11_error
raise "This resource is written with Chef 12.5 custom resources, and requires at least Chef 12.0 used with the compat_resource cookbook, it will not work with Chef 11.x clients, and those users must pin their cookbooks to older versions or upgrade."
end
end
end
end

View File

@ -0,0 +1,31 @@
unless Gem::Requirement.new(">= 12.0").satisfied_by?(Gem::Version.new(Chef::VERSION))
raise "This resource is written with Chef 12.5 custom resources, and requires at least Chef 12.0 used with the compat_resource cookbook, it will not work with Chef 11.x clients, and those users must pin their cookbooks to older versions or upgrade."
end
# If users are on old verisons of ChefDK which activates an (old) gem via cheffish before this cookbook loads, then
# we just try to monkeypatch over the top of a monkeypatch. Its possible that we have checks in this cookbook which
# will defeat that purpose and fail to monkeypatch on top of monkeypatches -- in which case those checks should be
# removed -- this cookbook needs to win when it gets into a fight with the old gem versions.
if Gem.loaded_specs["compat_resource"]
Chef.log_deprecation "using compat_resource as a gem is deprecated; please update cheffish and chef-provisioning gems (or use the latest Chef/ChefDK packages) or else manually pin your compat_resource cookbook version to the same version as the gem you are using to remove this warning"
end
# we want to not pollute the libpath with our files until after we've done the version check
require_relative '../files/lib/chef_upstream_version'
# on any chef client later than the one we were based off of we just turn into a no-op
if Gem::Requirement.new("< #{ChefCompat::CHEF_UPSTREAM_VERSION}").satisfied_by?(Gem::Version.new(Chef::VERSION))
Chef::Log.debug "loading compat_resource based on chef-version #{ChefCompat::CHEF_UPSTREAM_VERSION} over chef version #{Gem::Version.new(Chef::VERSION)}"
$LOAD_PATH.unshift(File.expand_path("../files/lib", File.dirname(__FILE__)))
require 'compat_resource'
else
Chef::Log.debug "NOT LOADING compat_resource based on chef-version #{ChefCompat::CHEF_UPSTREAM_VERSION} over chef version #{Gem::Version.new(Chef::VERSION)}"
unless defined?(ChefCompat::Resource) && defined?(ChefCompat::Mixin::Properties)
module ChefCompat
Resource = Chef::Resource
module Mixin
Properties = Chef::Mixin::Properties
end
end
end
end

View File

@ -0,0 +1 @@
{"name":"compat_resource","version":"12.16.3","description":"Backports functionality introduced in the latest chef-client releases to any chef-client from 12.1 onwards","long_description":"# compat_resource cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/compat_resource.svg?branch=master)](https://travis-ci.org/chef-cookbooks/compat_resource) [![Cookbook Version](https://img.shields.io/cookbook/v/compat_resource.svg)](https://supermarket.chef.io/cookbooks/compat_resource)\n\nThis cookbook backports functionality introduced in the latest chef-client releases to any chef-client from 12.1 onwards. This includes [Custom Resource](https://docs.chef.io/custom_resources.html) functionality, notification improvements, as well as new resources added to core chef. It allows for the usage of these new resources in cookbooks without requiring the very latest Chef client release.\n\n## Backported functionality\n\n- [Custom Resources](https://docs.chef.io/custom_resources.html)\n- [apt_repository](https://docs.chef.io/resource_apt_repository.html)\n- [apt_update](https://docs.chef.io/resource_apt_update.html)\n- [systemd_unit](https://docs.chef.io/resource_systemd_unit.html)\n- [yum_repository](https://docs.chef.io/resource_yum_repository.html)\n- [:before notifications](https://docs.chef.io/resources.html#timers)\n\n## Requirements\n\n### Platforms\n\n- All platforms supported by Chef\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- none\n\n## Usage\n\nTo use this cookbook, put `depends 'compat_resource'` in the metadata.rb of your cookbook. Once this is done, you can use all the new custom resource features to define resources. It Just Works.\n\n## Custom Resources?\n\nCurious about how to use custom resources?\n\n- Docs: <https://docs.chef.io/custom_resources.html>\n- Slides: <https://docs.chef.io/decks/custom_resources.html>\n\n## License & Authors\n\n- Author:: Lamont Granquist ([lamont@chef.io](mailto:lamont@chef.io))\n- Author:: John Keiser ([jkeiser@chef.io](mailto:jkeiser@chef.io))\n\n```text\nCopyright:: 2015-2016 Chef Software, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Lamont Granquist","maintainer_email":"lamont@chef.io","license":"Apache 2.0","platforms":{},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/compat_resource","issues_url":"https://github.com/chef-cookbooks/compat_resource/issues","chef_version":">= 12.1","ohai_version":{}}

View File

@ -0,0 +1 @@
~FC005

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
Please refer to
https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD

View File

@ -0,0 +1,20 @@
<!-- This is a generated file. Please do not edit directly -->
# Maintainers
This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead.
Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead.
# Project Maintainer
* [Sean OMeara](https://github.com/someara)
# Maintainers
* [Jennifer Davis](https://github.com/sigje)
* [Sean OMeara](https://github.com/someara)
* [Tim Smith](https://github.com/tas50)
* [Thom May](https://github.com/thommay)
* [Anthony Scalisi](https://github.com/scalp42)
* [Chase Bolt](https://github.com/chasebolt)
* [Brian Flad](https://github.com/bflad)
* [Tom Duffield](https://github.com/tduffield)

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,301 @@
PATH
remote: .
specs:
excon (0.54.0)
GEM
remote: http://rubygems.org/
specs:
activesupport (3.2.6)
i18n (~> 0.6)
multi_json (~> 1.0)
backports (3.6.4)
chronic (0.6.7)
delorean (2.0.0)
chronic
diff-lcs (1.2.5)
eventmachine (1.0.4)
eventmachine (1.0.4-java)
ffi2-generators (0.1.1)
formatador (0.2.3)
i18n (0.6.0)
jruby-openssl (0.9.17-java)
json (1.8.2)
json (1.8.2-java)
kgio (2.9.2)
minitest (4.7.5)
multi_json (1.3.6)
open4 (1.3.0)
puma (3.6.0)
puma (3.6.0-java)
rack (1.6.0)
rack-protection (1.2.0)
rack
rack-test (0.6.3)
rack (>= 1.0)
raindrops (0.13.0)
rake (0.9.2.2)
rdoc (3.12)
json (~> 1.4)
rspec (3.5.0)
rspec-core (~> 3.5.0)
rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.5.0)
rspec-core (3.5.0)
rspec-support (~> 3.5.0)
rspec-expectations (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-mocks (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-support (3.5.0)
rubysl (2.0.14)
rubysl-abbrev (~> 2.0)
rubysl-base64 (~> 2.0)
rubysl-benchmark (~> 2.0)
rubysl-bigdecimal (~> 2.0)
rubysl-cgi (~> 2.0)
rubysl-cgi-session (~> 2.0)
rubysl-cmath (~> 2.0)
rubysl-complex (~> 2.0)
rubysl-continuation (~> 2.0)
rubysl-coverage (~> 2.0)
rubysl-csv (~> 2.0)
rubysl-curses (~> 2.0)
rubysl-date (~> 2.0)
rubysl-delegate (~> 2.0)
rubysl-digest (~> 2.0)
rubysl-drb (~> 2.0)
rubysl-e2mmap (~> 2.0)
rubysl-english (~> 2.0)
rubysl-enumerator (~> 2.0)
rubysl-erb (~> 2.0)
rubysl-etc (~> 2.0)
rubysl-expect (~> 2.0)
rubysl-fcntl (~> 2.0)
rubysl-fiber (~> 2.0)
rubysl-fileutils (~> 2.0)
rubysl-find (~> 2.0)
rubysl-forwardable (~> 2.0)
rubysl-getoptlong (~> 2.0)
rubysl-gserver (~> 2.0)
rubysl-io-console (~> 2.0)
rubysl-io-nonblock (~> 2.0)
rubysl-io-wait (~> 2.0)
rubysl-ipaddr (~> 2.0)
rubysl-irb (~> 2.0)
rubysl-logger (~> 2.0)
rubysl-mathn (~> 2.0)
rubysl-matrix (~> 2.0)
rubysl-mkmf (~> 2.0)
rubysl-monitor (~> 2.0)
rubysl-mutex_m (~> 2.0)
rubysl-net-ftp (~> 2.0)
rubysl-net-http (~> 2.0)
rubysl-net-imap (~> 2.0)
rubysl-net-pop (~> 2.0)
rubysl-net-protocol (~> 2.0)
rubysl-net-smtp (~> 2.0)
rubysl-net-telnet (~> 2.0)
rubysl-nkf (~> 2.0)
rubysl-observer (~> 2.0)
rubysl-open-uri (~> 2.0)
rubysl-open3 (~> 2.0)
rubysl-openssl (~> 2.0)
rubysl-optparse (~> 2.0)
rubysl-ostruct (~> 2.0)
rubysl-pathname (~> 2.0)
rubysl-prettyprint (~> 2.0)
rubysl-prime (~> 2.0)
rubysl-profile (~> 2.0)
rubysl-profiler (~> 2.0)
rubysl-pstore (~> 2.0)
rubysl-pty (~> 2.0)
rubysl-rational (~> 2.0)
rubysl-readline (~> 2.0)
rubysl-resolv (~> 2.0)
rubysl-rexml (~> 2.0)
rubysl-rinda (~> 2.0)
rubysl-rss (~> 2.0)
rubysl-scanf (~> 2.0)
rubysl-securerandom (~> 2.0)
rubysl-set (~> 2.0)
rubysl-shellwords (~> 2.0)
rubysl-singleton (~> 2.0)
rubysl-socket (~> 2.0)
rubysl-stringio (~> 2.0)
rubysl-strscan (~> 2.0)
rubysl-sync (~> 2.0)
rubysl-syslog (~> 2.0)
rubysl-tempfile (~> 2.0)
rubysl-test-unit (~> 2.0)
rubysl-thread (~> 2.0)
rubysl-thwait (~> 2.0)
rubysl-time (~> 2.0)
rubysl-timeout (~> 2.0)
rubysl-tmpdir (~> 2.0)
rubysl-tsort (~> 2.0)
rubysl-un (~> 2.0)
rubysl-uri (~> 2.0)
rubysl-weakref (~> 2.0)
rubysl-webrick (~> 2.0)
rubysl-xmlrpc (~> 2.0)
rubysl-yaml (~> 2.0)
rubysl-zlib (~> 2.0)
rubysl-abbrev (2.0.4)
rubysl-base64 (2.0.0)
rubysl-benchmark (2.0.1)
rubysl-bigdecimal (2.0.2)
rubysl-cgi (2.0.1)
rubysl-cgi-session (2.0.1)
rubysl-cmath (2.0.0)
rubysl-complex (2.0.0)
rubysl-continuation (2.0.0)
rubysl-coverage (2.0.3)
rubysl-csv (2.0.2)
rubysl-english (~> 2.0)
rubysl-curses (2.0.0)
rubysl-date (2.0.6)
rubysl-delegate (2.0.1)
rubysl-digest (2.0.3)
rubysl-drb (2.0.1)
rubysl-e2mmap (2.0.0)
rubysl-english (2.0.0)
rubysl-enumerator (2.0.0)
rubysl-erb (2.0.1)
rubysl-etc (2.0.3)
ffi2-generators (~> 0.1)
rubysl-expect (2.0.0)
rubysl-fcntl (2.0.4)
ffi2-generators (~> 0.1)
rubysl-fiber (2.0.0)
rubysl-fileutils (2.0.3)
rubysl-find (2.0.1)
rubysl-forwardable (2.0.1)
rubysl-getoptlong (2.0.0)
rubysl-gserver (2.0.0)
rubysl-socket (~> 2.0)
rubysl-thread (~> 2.0)
rubysl-io-console (2.0.0)
rubysl-io-nonblock (2.0.0)
rubysl-io-wait (2.0.0)
rubysl-ipaddr (2.0.0)
rubysl-irb (2.0.4)
rubysl-e2mmap (~> 2.0)
rubysl-mathn (~> 2.0)
rubysl-readline (~> 2.0)
rubysl-thread (~> 2.0)
rubysl-logger (2.0.0)
rubysl-mathn (2.0.0)
rubysl-matrix (2.1.0)
rubysl-e2mmap (~> 2.0)
rubysl-mkmf (2.0.1)
rubysl-fileutils (~> 2.0)
rubysl-shellwords (~> 2.0)
rubysl-monitor (2.0.0)
rubysl-mutex_m (2.0.0)
rubysl-net-ftp (2.0.1)
rubysl-net-http (2.0.4)
rubysl-cgi (~> 2.0)
rubysl-erb (~> 2.0)
rubysl-singleton (~> 2.0)
rubysl-net-imap (2.0.1)
rubysl-net-pop (2.0.1)
rubysl-net-protocol (2.0.1)
rubysl-net-smtp (2.0.1)
rubysl-net-telnet (2.0.0)
rubysl-nkf (2.0.1)
rubysl-observer (2.0.0)
rubysl-open-uri (2.0.0)
rubysl-open3 (2.0.0)
rubysl-openssl (2.0.4)
rubysl-optparse (2.0.1)
rubysl-shellwords (~> 2.0)
rubysl-ostruct (2.0.4)
rubysl-pathname (2.0.0)
rubysl-prettyprint (2.0.2)
rubysl-prime (2.0.0)
rubysl-profile (2.0.0)
rubysl-profiler (2.0.1)
rubysl-pstore (2.0.0)
rubysl-pty (2.0.2)
rubysl-rational (2.0.1)
rubysl-readline (2.0.2)
rubysl-resolv (2.0.0)
rubysl-rexml (2.0.2)
rubysl-rinda (2.0.0)
rubysl-rss (2.0.0)
rubysl-scanf (2.0.0)
rubysl-securerandom (2.0.0)
rubysl-set (2.0.1)
rubysl-shellwords (2.0.0)
rubysl-singleton (2.0.0)
rubysl-socket (2.0.1)
rubysl-stringio (2.0.0)
rubysl-strscan (2.0.0)
rubysl-sync (2.0.0)
rubysl-syslog (2.0.1)
ffi2-generators (~> 0.1)
rubysl-tempfile (2.0.1)
rubysl-test-unit (2.0.1)
minitest (~> 4.7)
rubysl-thread (2.0.2)
rubysl-thwait (2.0.0)
rubysl-time (2.0.3)
rubysl-timeout (2.0.0)
rubysl-tmpdir (2.0.0)
rubysl-tsort (2.0.1)
rubysl-un (2.0.0)
rubysl-fileutils (~> 2.0)
rubysl-optparse (~> 2.0)
rubysl-uri (2.0.0)
rubysl-weakref (2.0.0)
rubysl-webrick (2.0.0)
rubysl-xmlrpc (2.0.0)
rubysl-yaml (2.0.3)
rubysl-zlib (2.0.1)
shindo (0.3.4)
formatador (>= 0.1.1)
sinatra (1.3.2)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
sinatra-contrib (1.3.2)
backports (>= 2.0)
eventmachine
rack-protection
rack-test
sinatra (~> 1.3.0)
tilt (~> 1.3)
tilt (1.3.3)
unicorn (4.8.3)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
PLATFORMS
java
ruby
DEPENDENCIES
activesupport
delorean
eventmachine (>= 1.0.4)
excon!
jruby-openssl (~> 0.9)
json (>= 1.8.2)
open4
puma
rack (~> 1.6)
rake
rdoc
rspec (>= 3.5.0)
rubysl (~> 2.0)
shindo
sinatra
sinatra-contrib
unicorn
BUNDLED WITH
1.13.1

View File

@ -0,0 +1,196 @@
SHELL = /bin/sh
# V=0 quiet, V=1 verbose. other values don't work.
V = 0
Q1 = $(V:1=)
Q = $(Q1:0=@)
ECHO1 = $(V:1=@:)
ECHO = $(ECHO1:0=@echo)
NULLCMD = :
#### Start of system configuration section. ####
srcdir = .
topdir = /opt/chefdk/embedded/include/ruby-2.3.0
hdrdir = $(topdir)
arch_hdrdir = /opt/chefdk/embedded/include/ruby-2.3.0/x86_64-darwin13
PATH_SEPARATOR = :
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
prefix = $(DESTDIR)/opt/chefdk/embedded
rubysitearchprefix = $(rubylibprefix)/$(sitearch)
rubyarchprefix = $(rubylibprefix)/$(arch)
rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
exec_prefix = $(prefix)
vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
sitearchhdrdir = $(sitehdrdir)/$(sitearch)
rubyarchhdrdir = $(rubyhdrdir)/$(arch)
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
sitehdrdir = $(rubyhdrdir)/site_ruby
rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
vendorarchdir = $(vendorlibdir)/$(sitearch)
vendorlibdir = $(vendordir)/$(ruby_version)
vendordir = $(rubylibprefix)/vendor_ruby
sitearchdir = $(DESTDIR)./.gem.20170131-68034-1687ce7
sitelibdir = $(DESTDIR)./.gem.20170131-68034-1687ce7
sitedir = $(rubylibprefix)/site_ruby
rubyarchdir = $(rubylibdir)/$(arch)
rubylibdir = $(rubylibprefix)/$(ruby_version)
sitearchincludedir = $(includedir)/$(sitearch)
archincludedir = $(includedir)/$(arch)
sitearchlibdir = $(libdir)/$(sitearch)
archlibdir = $(libdir)/$(arch)
ridir = $(datarootdir)/$(RI_BASE_NAME)
mandir = $(datarootdir)/man
localedir = $(datarootdir)/locale
libdir = $(exec_prefix)/lib
psdir = $(docdir)
pdfdir = $(docdir)
dvidir = $(docdir)
htmldir = $(docdir)
infodir = $(datarootdir)/info
docdir = $(datarootdir)/doc/$(PACKAGE)
oldincludedir = $(DESTDIR)/usr/include
includedir = $(SDKROOT)$(prefix)/include
localstatedir = $(prefix)/var
sharedstatedir = $(prefix)/com
sysconfdir = $(prefix)/etc
datadir = $(datarootdir)
datarootdir = $(prefix)/share
libexecdir = $(exec_prefix)/libexec
sbindir = $(exec_prefix)/sbin
bindir = $(exec_prefix)/bin
archdir = $(rubyarchdir)
CC = clang
CXX = g++
LIBRUBY = $(LIBRUBY_SO)
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework CoreFoundation
empty =
OUTFLAG = -o $(empty)
COUTFLAG = -o $(empty)
RUBY_EXTCONF_H =
cflags = $(optflags) $(debugflags) $(warnflags)
cxxflags = $(optflags) $(debugflags) $(warnflags)
optflags = -O3 -fno-fast-math
debugflags = -ggdb3
warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -diag-disable=2259 -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens
CCDLFLAGS = -fno-common
CFLAGS = $(CCDLFLAGS) -I/opt/chefdk/embedded/include -O2 -I/opt/chefdk/embedded/include/ncurses -O3 -g -pipe -Qunused-arguments -fno-common $(ARCH_FLAG)
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
DEFS =
CPPFLAGS = -I/opt/chefdk/embedded/include -O2 -I/opt/chefdk/embedded/include/ncurses -arch x86_64 -m64 -O3 -g -pipe -Qunused-arguments -I/opt/chefdk/embedded/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags)
CXXFLAGS = $(CCDLFLAGS) -I/opt/chefdk/embedded/include -O2 -I/opt/chefdk/embedded/include/ncurses -O3 -g -pipe -Qunused-arguments $(ARCH_FLAG)
ldflags = -L. -L/opt/chefdk/embedded/lib -fstack-protector -L/opt/chefdk/embedded/lib
dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -L/opt/chefdk/embedded/lib
ARCH_FLAG = -m64
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
LDSHARED = $(CC) -dynamic -bundle
LDSHAREDXX = $(CXX) -dynamic -bundle
AR = ar
EXEEXT =
RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
RUBY_SO_NAME = ruby.2.3.0
RUBYW_INSTALL_NAME =
RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
RUBYW_BASE_NAME = rubyw
RUBY_BASE_NAME = ruby
arch = x86_64-darwin13
sitearch = $(arch)
ruby_version = 2.3.0
ruby = $(bindir)/$(RUBY_BASE_NAME)
RUBY = $(ruby)
ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h
RM = rm -f
RM_RF = $(RUBY) -run -e rm -- -rf
RMDIRS = rmdir -p
MAKEDIRS = mkdir -p
INSTALL = /usr/bin/install -c
INSTALL_PROG = $(INSTALL) -m 0755
INSTALL_DATA = $(INSTALL) -m 644
COPY = cp
TOUCH = exit >
#### End of system configuration section. ####
preload =
libpath = . $(libdir) /opt/chefdk/embedded/lib
LIBPATH = -L. -L$(libdir) -L/opt/chefdk/embedded/lib
DEFFILE =
CLEANFILES = mkmf.log
DISTCLEANFILES =
DISTCLEANDIRS =
extout =
extout_prefix =
target_prefix =
LOCAL_LIBS =
LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lobjc
ORIG_SRCS =
SRCS = $(ORIG_SRCS)
OBJS =
HDRS =
TARGET =
TARGET_NAME =
TARGET_ENTRY = Init_$(TARGET_NAME)
DLLIB =
EXTSTATIC =
STATIC_LIB =
TIMESTAMP_DIR = .
BINDIR = $(bindir)
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
TARGET_SO = $(DLLIB)
CLEANLIBS = $(TARGET).bundle
CLEANOBJS = *.o *.bak
all: Makefile
static: $(STATIC_LIB) install-rb
.PHONY: all install static install-so install-rb
.PHONY: clean clean-so clean-static clean-rb
clean-static::
clean-rb-default::
clean-rb::
clean-so::
clean: clean-so clean-static clean-rb-default clean-rb
-$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
distclean-rb-default::
distclean-rb::
distclean-so::
distclean-static::
distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
-$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
realclean: distclean
install: install-so install-rb
install-so: Makefile
install-rb: pre-install-rb install-rb-default
install-rb-default: pre-install-rb-default
pre-install-rb: Makefile
pre-install-rb-default: Makefile
pre-install-rb-default:
@$(NULLCMD)
site-install: site-install-so site-install-rb
site-install-so: install-so
site-install-rb: install-rb

View File

@ -0,0 +1,262 @@
SHELL = /bin/sh
# V=0 quiet, V=1 verbose. other values don't work.
V = 0
Q1 = $(V:1=)
Q = $(Q1:0=@)
ECHO1 = $(V:1=@:)
ECHO = $(ECHO1:0=@echo)
NULLCMD = :
#### Start of system configuration section. ####
srcdir = .
topdir = /opt/chefdk/embedded/include/ruby-2.3.0
hdrdir = $(topdir)
arch_hdrdir = /opt/chefdk/embedded/include/ruby-2.3.0/x86_64-darwin13
PATH_SEPARATOR = :
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
prefix = $(DESTDIR)/opt/chefdk/embedded
rubysitearchprefix = $(rubylibprefix)/$(sitearch)
rubyarchprefix = $(rubylibprefix)/$(arch)
rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
exec_prefix = $(prefix)
vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
sitearchhdrdir = $(sitehdrdir)/$(sitearch)
rubyarchhdrdir = $(rubyhdrdir)/$(arch)
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
sitehdrdir = $(rubyhdrdir)/site_ruby
rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
vendorarchdir = $(vendorlibdir)/$(sitearch)
vendorlibdir = $(vendordir)/$(ruby_version)
vendordir = $(rubylibprefix)/vendor_ruby
sitearchdir = $(DESTDIR)./.gem.20170131-68034-12q3abg
sitelibdir = $(DESTDIR)./.gem.20170131-68034-12q3abg
sitedir = $(rubylibprefix)/site_ruby
rubyarchdir = $(rubylibdir)/$(arch)
rubylibdir = $(rubylibprefix)/$(ruby_version)
sitearchincludedir = $(includedir)/$(sitearch)
archincludedir = $(includedir)/$(arch)
sitearchlibdir = $(libdir)/$(sitearch)
archlibdir = $(libdir)/$(arch)
ridir = $(datarootdir)/$(RI_BASE_NAME)
mandir = $(datarootdir)/man
localedir = $(datarootdir)/locale
libdir = $(exec_prefix)/lib
psdir = $(docdir)
pdfdir = $(docdir)
dvidir = $(docdir)
htmldir = $(docdir)
infodir = $(datarootdir)/info
docdir = $(datarootdir)/doc/$(PACKAGE)
oldincludedir = $(DESTDIR)/usr/include
includedir = $(SDKROOT)$(prefix)/include
localstatedir = $(prefix)/var
sharedstatedir = $(prefix)/com
sysconfdir = $(prefix)/etc
datadir = $(datarootdir)
datarootdir = $(prefix)/share
libexecdir = $(exec_prefix)/libexec
sbindir = $(exec_prefix)/sbin
bindir = $(exec_prefix)/bin
archdir = $(rubyarchdir)
CC = clang
CXX = g++
LIBRUBY = $(LIBRUBY_SO)
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework CoreFoundation
empty =
OUTFLAG = -o $(empty)
COUTFLAG = -o $(empty)
RUBY_EXTCONF_H =
cflags = $(optflags) $(debugflags) $(warnflags)
cxxflags = $(optflags) $(debugflags) $(warnflags)
optflags = -O3 -fno-fast-math
debugflags = -ggdb3
warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -diag-disable=2259 -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens
CCDLFLAGS = -fno-common
CFLAGS = $(CCDLFLAGS) -I/opt/chefdk/embedded/include -O2 -I/opt/chefdk/embedded/include/ncurses -O3 -g -pipe -Qunused-arguments -fno-common $(ARCH_FLAG)
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
DEFS =
CPPFLAGS = -DJSON_GENERATOR -I/opt/chefdk/embedded/include -O2 -I/opt/chefdk/embedded/include/ncurses -arch x86_64 -m64 -O3 -g -pipe -Qunused-arguments -I/opt/chefdk/embedded/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags)
CXXFLAGS = $(CCDLFLAGS) -I/opt/chefdk/embedded/include -O2 -I/opt/chefdk/embedded/include/ncurses -O3 -g -pipe -Qunused-arguments $(ARCH_FLAG)
ldflags = -L. -L/opt/chefdk/embedded/lib -fstack-protector -L/opt/chefdk/embedded/lib
dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -L/opt/chefdk/embedded/lib
ARCH_FLAG = -m64
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
LDSHARED = $(CC) -dynamic -bundle
LDSHAREDXX = $(CXX) -dynamic -bundle
AR = ar
EXEEXT =
RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
RUBY_SO_NAME = ruby.2.3.0
RUBYW_INSTALL_NAME =
RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
RUBYW_BASE_NAME = rubyw
RUBY_BASE_NAME = ruby
arch = x86_64-darwin13
sitearch = $(arch)
ruby_version = 2.3.0
ruby = $(bindir)/$(RUBY_BASE_NAME)
RUBY = $(ruby)
ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h
RM = rm -f
RM_RF = $(RUBY) -run -e rm -- -rf
RMDIRS = rmdir -p
MAKEDIRS = mkdir -p
INSTALL = /usr/bin/install -c
INSTALL_PROG = $(INSTALL) -m 0755
INSTALL_DATA = $(INSTALL) -m 644
COPY = cp
TOUCH = exit >
#### End of system configuration section. ####
preload =
libpath = . $(libdir) /opt/chefdk/embedded/lib
LIBPATH = -L. -L$(libdir) -L/opt/chefdk/embedded/lib
DEFFILE =
CLEANFILES = mkmf.log
DISTCLEANFILES =
DISTCLEANDIRS =
extout =
extout_prefix =
target_prefix = /json/ext
LOCAL_LIBS =
LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lobjc
ORIG_SRCS = generator.c
SRCS = $(ORIG_SRCS)
OBJS = generator.o
HDRS = $(srcdir)/generator.h
TARGET = generator
TARGET_NAME = generator
TARGET_ENTRY = Init_$(TARGET_NAME)
DLLIB = $(TARGET).bundle
EXTSTATIC =
STATIC_LIB =
TIMESTAMP_DIR = .
BINDIR = $(bindir)
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
TARGET_SO = $(DLLIB)
CLEANLIBS = $(TARGET).bundle
CLEANOBJS = *.o *.bak
all: $(DLLIB)
static: $(STATIC_LIB) install-rb
.PHONY: all install static install-so install-rb
.PHONY: clean clean-so clean-static clean-rb
clean-static::
clean-rb-default::
clean-rb::
clean-so::
clean: clean-so clean-static clean-rb-default clean-rb
-$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
distclean-rb-default::
distclean-rb::
distclean-so::
distclean-static::
distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
-$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
realclean: distclean
install: install-so install-rb
install-so: $(DLLIB) $(TIMESTAMP_DIR)/.RUBYARCHDIR.-.json.-.ext.time
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
clean-static::
-$(Q)$(RM) $(STATIC_LIB)
install-rb: pre-install-rb install-rb-default
install-rb-default: pre-install-rb-default
pre-install-rb: Makefile
pre-install-rb-default: Makefile
pre-install-rb-default:
@$(NULLCMD)
$(TIMESTAMP_DIR)/.RUBYARCHDIR.-.json.-.ext.time:
$(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR)
$(Q) $(TOUCH) $@
site-install: site-install-so site-install-rb
site-install-so: install-so
site-install-rb: install-rb
.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S
.cc.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.cc.S:
$(ECHO) translating $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
.mm.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.mm.S:
$(ECHO) translating $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
.cxx.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.cxx.S:
$(ECHO) translating $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
.cpp.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.cpp.S:
$(ECHO) translating $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
.c.o:
$(ECHO) compiling $(<)
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
.c.S:
$(ECHO) translating $(<)
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $<
.m.o:
$(ECHO) compiling $(<)
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
.m.S:
$(ECHO) translating $(<)
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $<
$(DLLIB): $(OBJS) Makefile
$(ECHO) linking shared-object json/ext/$(DLLIB)
-$(Q)$(RM) $(@)
$(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
$(Q) $(POSTLINK)
###
generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h

View File

@ -0,0 +1,262 @@
SHELL = /bin/sh
# V=0 quiet, V=1 verbose. other values don't work.
V = 0
Q1 = $(V:1=)
Q = $(Q1:0=@)
ECHO1 = $(V:1=@:)
ECHO = $(ECHO1:0=@echo)
NULLCMD = :
#### Start of system configuration section. ####
srcdir = .
topdir = /opt/chefdk/embedded/include/ruby-2.3.0
hdrdir = $(topdir)
arch_hdrdir = /opt/chefdk/embedded/include/ruby-2.3.0/x86_64-darwin13
PATH_SEPARATOR = :
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
prefix = $(DESTDIR)/opt/chefdk/embedded
rubysitearchprefix = $(rubylibprefix)/$(sitearch)
rubyarchprefix = $(rubylibprefix)/$(arch)
rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
exec_prefix = $(prefix)
vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
sitearchhdrdir = $(sitehdrdir)/$(sitearch)
rubyarchhdrdir = $(rubyhdrdir)/$(arch)
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
sitehdrdir = $(rubyhdrdir)/site_ruby
rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
vendorarchdir = $(vendorlibdir)/$(sitearch)
vendorlibdir = $(vendordir)/$(ruby_version)
vendordir = $(rubylibprefix)/vendor_ruby
sitearchdir = $(DESTDIR)./.gem.20170131-68034-1leg24r
sitelibdir = $(DESTDIR)./.gem.20170131-68034-1leg24r
sitedir = $(rubylibprefix)/site_ruby
rubyarchdir = $(rubylibdir)/$(arch)
rubylibdir = $(rubylibprefix)/$(ruby_version)
sitearchincludedir = $(includedir)/$(sitearch)
archincludedir = $(includedir)/$(arch)
sitearchlibdir = $(libdir)/$(sitearch)
archlibdir = $(libdir)/$(arch)
ridir = $(datarootdir)/$(RI_BASE_NAME)
mandir = $(datarootdir)/man
localedir = $(datarootdir)/locale
libdir = $(exec_prefix)/lib
psdir = $(docdir)
pdfdir = $(docdir)
dvidir = $(docdir)
htmldir = $(docdir)
infodir = $(datarootdir)/info
docdir = $(datarootdir)/doc/$(PACKAGE)
oldincludedir = $(DESTDIR)/usr/include
includedir = $(SDKROOT)$(prefix)/include
localstatedir = $(prefix)/var
sharedstatedir = $(prefix)/com
sysconfdir = $(prefix)/etc
datadir = $(datarootdir)
datarootdir = $(prefix)/share
libexecdir = $(exec_prefix)/libexec
sbindir = $(exec_prefix)/sbin
bindir = $(exec_prefix)/bin
archdir = $(rubyarchdir)
CC = clang
CXX = g++
LIBRUBY = $(LIBRUBY_SO)
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework CoreFoundation
empty =
OUTFLAG = -o $(empty)
COUTFLAG = -o $(empty)
RUBY_EXTCONF_H =
cflags = $(optflags) $(debugflags) $(warnflags)
cxxflags = $(optflags) $(debugflags) $(warnflags)
optflags = -O3 -fno-fast-math
debugflags = -ggdb3
warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -diag-disable=2259 -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens
CCDLFLAGS = -fno-common
CFLAGS = $(CCDLFLAGS) -I/opt/chefdk/embedded/include -O2 -I/opt/chefdk/embedded/include/ncurses -O3 -g -pipe -Qunused-arguments -fno-common $(ARCH_FLAG)
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
DEFS =
CPPFLAGS = -DHAVE_RB_ENC_RAISE -I/opt/chefdk/embedded/include -O2 -I/opt/chefdk/embedded/include/ncurses -arch x86_64 -m64 -O3 -g -pipe -Qunused-arguments -I/opt/chefdk/embedded/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags)
CXXFLAGS = $(CCDLFLAGS) -I/opt/chefdk/embedded/include -O2 -I/opt/chefdk/embedded/include/ncurses -O3 -g -pipe -Qunused-arguments $(ARCH_FLAG)
ldflags = -L. -L/opt/chefdk/embedded/lib -fstack-protector -L/opt/chefdk/embedded/lib
dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -L/opt/chefdk/embedded/lib
ARCH_FLAG = -m64
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
LDSHARED = $(CC) -dynamic -bundle
LDSHAREDXX = $(CXX) -dynamic -bundle
AR = ar
EXEEXT =
RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
RUBY_SO_NAME = ruby.2.3.0
RUBYW_INSTALL_NAME =
RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
RUBYW_BASE_NAME = rubyw
RUBY_BASE_NAME = ruby
arch = x86_64-darwin13
sitearch = $(arch)
ruby_version = 2.3.0
ruby = $(bindir)/$(RUBY_BASE_NAME)
RUBY = $(ruby)
ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h
RM = rm -f
RM_RF = $(RUBY) -run -e rm -- -rf
RMDIRS = rmdir -p
MAKEDIRS = mkdir -p
INSTALL = /usr/bin/install -c
INSTALL_PROG = $(INSTALL) -m 0755
INSTALL_DATA = $(INSTALL) -m 644
COPY = cp
TOUCH = exit >
#### End of system configuration section. ####
preload =
libpath = . $(libdir) /opt/chefdk/embedded/lib
LIBPATH = -L. -L$(libdir) -L/opt/chefdk/embedded/lib
DEFFILE =
CLEANFILES = mkmf.log
DISTCLEANFILES =
DISTCLEANDIRS =
extout =
extout_prefix =
target_prefix = /json/ext
LOCAL_LIBS =
LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lobjc
ORIG_SRCS = parser.c
SRCS = $(ORIG_SRCS)
OBJS = parser.o
HDRS = $(srcdir)/parser.h
TARGET = parser
TARGET_NAME = parser
TARGET_ENTRY = Init_$(TARGET_NAME)
DLLIB = $(TARGET).bundle
EXTSTATIC =
STATIC_LIB =
TIMESTAMP_DIR = .
BINDIR = $(bindir)
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
TARGET_SO = $(DLLIB)
CLEANLIBS = $(TARGET).bundle
CLEANOBJS = *.o *.bak
all: $(DLLIB)
static: $(STATIC_LIB) install-rb
.PHONY: all install static install-so install-rb
.PHONY: clean clean-so clean-static clean-rb
clean-static::
clean-rb-default::
clean-rb::
clean-so::
clean: clean-so clean-static clean-rb-default clean-rb
-$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
distclean-rb-default::
distclean-rb::
distclean-so::
distclean-static::
distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
-$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
realclean: distclean
install: install-so install-rb
install-so: $(DLLIB) $(TIMESTAMP_DIR)/.RUBYARCHDIR.-.json.-.ext.time
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
clean-static::
-$(Q)$(RM) $(STATIC_LIB)
install-rb: pre-install-rb install-rb-default
install-rb-default: pre-install-rb-default
pre-install-rb: Makefile
pre-install-rb-default: Makefile
pre-install-rb-default:
@$(NULLCMD)
$(TIMESTAMP_DIR)/.RUBYARCHDIR.-.json.-.ext.time:
$(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR)
$(Q) $(TOUCH) $@
site-install: site-install-so site-install-rb
site-install-so: install-so
site-install-rb: install-rb
.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S
.cc.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.cc.S:
$(ECHO) translating $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
.mm.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.mm.S:
$(ECHO) translating $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
.cxx.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.cxx.S:
$(ECHO) translating $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
.cpp.o:
$(ECHO) compiling $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
.cpp.S:
$(ECHO) translating $(<)
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
.c.o:
$(ECHO) compiling $(<)
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
.c.S:
$(ECHO) translating $(<)
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $<
.m.o:
$(ECHO) compiling $(<)
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
.m.S:
$(ECHO) translating $(<)
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $<
$(DLLIB): $(OBJS) Makefile
$(ECHO) linking shared-object json/ext/$(DLLIB)
-$(Q)$(RM) $(@)
$(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
$(Q) $(POSTLINK)
###
parser.o: parser.c parser.h $(srcdir)/../fbuffer/fbuffer.h

View File

@ -0,0 +1,13 @@
begin
gem 'docker-api', '= 1.33.2'
rescue LoadError
unless defined?(ChefSpec)
run_context = Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new)
require 'chef/resource/chef_gem'
docker = Chef::Resource::ChefGem.new('docker-api', run_context)
docker.version '= 1.33.2'
docker.run_action(:install)
end
end

View File

@ -0,0 +1,90 @@
module DockerCookbook
class DockerBase < Chef::Resource
require_relative 'helpers_auth'
require_relative 'helpers_base'
include DockerHelpers::Base
#########
# Classes
#########
class UnorderedArray < Array
def ==(other)
# If I (desired env) am a subset of the current env, let == return true
other.is_a?(Array) && all? { |val| other.include?(val) }
end
end
class ShellCommandString < String
def ==(other)
other.is_a?(String) && Shellwords.shellwords(self) == Shellwords.shellwords(other)
end
end
class PartialHash < Hash
def ==(other)
other.is_a?(Hash) && all? { |key, val| other.key?(key) && other[key] == val }
end
end
################
# Type Constants
#
# These will be used when declaring resource property types in the
# docker_service, docker_container, and docker_image resource.
#
################
ArrayType = property_type(
is: [Array, nil],
coerce: proc { |v| v.nil? ? nil : Array(v) }
) unless defined?(ArrayType)
Boolean = property_type(
is: [true, false],
default: false
) unless defined?(Boolean)
NonEmptyArray = property_type(
is: [Array, nil],
coerce: proc { |v| Array(v).empty? ? nil : Array(v) }
) unless defined?(NonEmptyArray)
ShellCommand = property_type(
is: [String],
coerce: proc { |v| coerce_shell_command(v) }
) unless defined?(ShellCommand)
UnorderedArrayType = property_type(
is: [UnorderedArray, nil],
coerce: proc { |v| v.nil? ? nil : UnorderedArray.new(Array(v)) }
) unless defined?(UnorderedArrayType)
PartialHashType = property_type(
is: [PartialHash, nil],
coerce: proc { |v| v.nil? ? nil : PartialHash[v] }
) unless defined?(PartialHashType)
#####################
# Resource properties
#####################
property :api_retries, Integer, default: 3, desired_state: false
property :read_timeout, [Integer, nil], default: 60, desired_state: false
property :write_timeout, [Integer, nil], desired_state: false
property :running_wait_time, [Integer, nil], default: 20, desired_state: false
property :tls, [Boolean, nil], default: lazy { default_tls }, desired_state: false
property :tls_verify, [Boolean, nil], default: lazy { default_tls_verify }, desired_state: false
property :tls_ca_cert, [String, nil], default: lazy { default_tls_cert_path('ca') }, desired_state: false
property :tls_server_cert, [String, nil], desired_state: false
property :tls_server_key, [String, nil], desired_state: false
property :tls_client_cert, [String, nil], default: lazy { default_tls_cert_path('cert') }, desired_state: false
property :tls_client_key, [String, nil], default: lazy { default_tls_cert_path('key') }, desired_state: false
declare_action_class.class_eval do
include DockerHelpers::Authentication
end
end
end

View File

@ -0,0 +1,437 @@
module DockerCookbook
class DockerContainer < DockerBase
require 'docker'
require 'shellwords'
require_relative 'helpers_container'
include DockerHelpers::Container
resource_name :docker_container
###########################################################
# In Chef 12.5 and later, we no longer have to use separate
# classes for resource and providers. Instead, we have
# everything in a single class.
#
# For the purposes of my own sanity, I'm going to place all the
# "resource" related bits at the top of the files, and the
# providerish bits at the bottom.
#
#
# Methods for default values and coersion are found in
# helpers_container.rb
###########################################################
# ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
# Begin classic Chef "resource" section
# ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
# The non-standard types Boolean, ArrayType, ShellCommand, etc
# are found in the DockerBase class.
property :container_name, String, name_property: true
property :repo, String, default: lazy { container_name }
property :tag, String, default: 'latest'
property :command, ShellCommand
property :attach_stderr, Boolean, default: false, desired_state: false
property :attach_stdin, Boolean, default: false, desired_state: false
property :attach_stdout, Boolean, default: false, desired_state: false
property :autoremove, Boolean, desired_state: false
property :cap_add, NonEmptyArray
property :cap_drop, NonEmptyArray
property :cgroup_parent, String, default: ''
property :cpu_shares, [Integer, nil], default: 0
property :cpuset_cpus, String, default: ''
property :detach, Boolean, default: true, desired_state: false
property :devices, Array, default: []
property :dns, Array, default: []
property :dns_search, Array, default: []
property :domain_name, String, default: ''
property :entrypoint, ShellCommand
property :env, UnorderedArrayType, default: []
property :extra_hosts, NonEmptyArray
property :exposed_ports, PartialHashType, default: {}
property :force, Boolean, desired_state: false
property :host, [String, nil], default: lazy { default_host }, desired_state: false
property :hostname, String
property :ipc_mode, String, default: ''
property :labels, [String, Array, Hash], default: {}, coerce: proc { |v| coerce_labels(v) }
property :links, UnorderedArrayType, coerce: proc { |v| coerce_links(v) }
property :log_driver, %w( json-file syslog journald gelf fluentd awslogs splunk etwlogs gcplogs none ), default: 'json-file', desired_state: false
property :log_opts, [Hash, nil], coerce: proc { |v| coerce_log_opts(v) }, desired_state: false
property :ip_address, String
property :mac_address, String
property :memory, Integer, default: 0
property :memory_swap, Integer, default: 0
property :network_disabled, Boolean, default: false
property :network_mode, [String, NilClass], default: 'bridge'
property :open_stdin, Boolean, default: false, desired_state: false
property :outfile, [String, NilClass]
property :port_bindings, PartialHashType, default: {}
property :pid_mode, String, default: ''
property :privileged, Boolean, default: false
property :publish_all_ports, Boolean, default: false
property :remove_volumes, Boolean
property :restart_maximum_retry_count, Integer, default: 0
property :restart_policy, String
property :ro_rootfs, Boolean, default: false
property :security_opts, [String, ArrayType]
property :signal, String, default: 'SIGTERM'
property :stdin_once, Boolean, default: false, desired_state: false
property :sysctls, Hash, default: {}
property :timeout, [Integer, nil], desired_state: false
property :tty, Boolean, default: false
property :ulimits, [Array, nil], coerce: proc { |v| coerce_ulimits(v) }
property :user, String, default: ''
property :userns_mode, String, default: ''
property :uts_mode, String, default: ''
property :volumes, PartialHashType, default: {}, coerce: proc { |v| coerce_volumes(v) }
property :volumes_from, ArrayType
property :volume_driver, String
property :working_dir, [String, NilClass], default: ''
# Used to store the bind property since binds is an alias to volumes
property :volumes_binds, Array
# Used to store the state of the Docker container
property :container, Docker::Container, desired_state: false
# Used by :stop action. If the container takes longer than this
# many seconds to stop, kill itinstead. -1 (the default) means
# never kill the container.
property :kill_after, Numeric, default: -1, desired_state: false
alias cmd command
alias additional_host extra_hosts
alias rm autoremove
alias remove_automatically autoremove
alias host_name hostname
alias domainname domain_name
alias dnssearch dns_search
alias restart_maximum_retries restart_maximum_retry_count
alias volume volumes
alias binds volumes
alias volume_from volumes_from
alias destination outfile
alias workdir working_dir
# ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
# Begin classic Chef "provider" section
# ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
########################################################
# Load Current Value
########################################################
load_current_value do
# Grab the container and assign the container property
begin
with_retries { container Docker::Container.get(container_name, {}, connection) }
rescue Docker::Error::NotFoundError
current_value_does_not_exist!
end
# Go through everything in the container and set corresponding properties:
# c.info['Config']['ExposedPorts'] -> exposed_ports
(container.info['Config'].to_a + container.info['HostConfig'].to_a).each do |key, value|
next if value.nil? || key == 'RestartPolicy' || key == 'Binds' || key == 'ReadonlyRootfs'
# Image => image
# Set exposed_ports = ExposedPorts (etc.)
property_name = to_snake_case(key)
public_send(property_name, value) if respond_to?(property_name)
end
# load container specific labels (without engine/image ones)
load_container_labels
# these are a special case for us because our names differ from theirs
restart_policy container.info['HostConfig']['RestartPolicy']['Name']
restart_maximum_retry_count container.info['HostConfig']['RestartPolicy']['MaximumRetryCount']
volumes_binds container.info['HostConfig']['Binds']
ro_rootfs container.info['HostConfig']['ReadonlyRootfs']
end
#########
# Actions
#########
# Super handy visual reference!
# http://gliderlabs.com/images/docker_events.png
default_action :run
declare_action_class.class_eval do
def whyrun_supported?
true
end
def call_action(action)
send("action_#{action}")
load_current_resource
end
def state
current_resource ? current_resource.state : {}
end
end
# Loads container specific labels excluding those of engine or image.
# This insures idempotency.
def load_container_labels
image_labels = Docker::Image.get(container.info['Image'], {}, connection).info['Config']['Labels'] || {}
engine_labels = Docker.info(connection)['Labels'] || {}
labels = (container.info['Config']['Labels'] || {}).reject do |key, val|
image_labels.any? { |k, v| k == key && v == val } ||
engine_labels.any? { |k, v| k == key && v == val }
end
public_send(:labels, labels)
end
def validate_container_create
if property_is_set?(:restart_policy) &&
restart_policy != 'no' &&
restart_policy != 'always' &&
restart_policy != 'unless-stopped' &&
restart_policy != 'on-failure'
raise Chef::Exceptions::ValidationFailed, 'restart_policy must be either no, always, unless-stopped, or on-failure.'
end
if autoremove == true && (property_is_set?(:restart_policy) && restart_policy != 'no')
raise Chef::Exceptions::ValidationFailed, 'Conflicting options restart_policy and autoremove.'
end
if detach == true &&
(
attach_stderr == true ||
attach_stdin == true ||
attach_stdout == true ||
stdin_once == true
)
raise Chef::Exceptions::ValidationFailed, 'Conflicting options detach, attach_stderr, attach_stdin, attach_stdout, stdin_once.'
end
if network_mode == 'host' &&
(
!(hostname.nil? || hostname.empty?) ||
!(mac_address.nil? || mac_address.empty?)
)
raise Chef::Exceptions::ValidationFailed, 'Cannot specify hostname or mac_address when network_mode is host.'
end
if network_mode == 'container' &&
(
!(hostname.nil? || hostname.empty?) ||
!(dns.nil? || dns.empty?) ||
!(dns_search.nil? || dns_search.empty?) ||
!(mac_address.nil? || mac_address.empty?) ||
!(extra_hosts.nil? || extra_hosts.empty?) ||
!(exposed_ports.nil? || exposed_ports.empty?) ||
!(port_bindings.nil? || port_bindings.empty?) ||
!(publish_all_ports.nil? || publish_all_ports.empty?) ||
!port.nil?
)
raise Chef::Exceptions::ValidationFailed, 'Cannot specify hostname, dns, dns_search, mac_address, extra_hosts, exposed_ports, port_bindings, publish_all_ports, port when network_mode is container.'
end
end
def parsed_hostname
return nil if network_mode == 'host'
hostname
end
action :create do
validate_container_create
converge_if_changed do
action_delete
with_retries do
config = {
'name' => container_name,
'Image' => "#{repo}:#{tag}",
'Labels' => labels,
'Cmd' => to_shellwords(command),
'AttachStderr' => attach_stderr,
'AttachStdin' => attach_stdin,
'AttachStdout' => attach_stdout,
'Domainname' => domain_name,
'Entrypoint' => to_shellwords(entrypoint),
'Env' => env,
'ExposedPorts' => exposed_ports,
'Hostname' => parsed_hostname,
'MacAddress' => mac_address,
'NetworkDisabled' => network_disabled,
'OpenStdin' => open_stdin,
'StdinOnce' => stdin_once,
'Tty' => tty,
'User' => user,
'Volumes' => volumes,
'WorkingDir' => working_dir,
'HostConfig' => {
'Binds' => volumes_binds,
'CapAdd' => cap_add,
'CapDrop' => cap_drop,
'CgroupParent' => cgroup_parent,
'CpuShares' => cpu_shares,
'CpusetCpus' => cpuset_cpus,
'Devices' => devices,
'Dns' => dns,
'DnsSearch' => dns_search,
'ExtraHosts' => extra_hosts,
'IpcMode' => ipc_mode,
'Links' => links,
'LogConfig' => log_config,
'Memory' => memory,
'MemorySwap' => memory_swap,
'NetworkMode' => network_mode,
'Privileged' => privileged,
'PidMode' => pid_mode,
'PortBindings' => port_bindings,
'PublishAllPorts' => publish_all_ports,
'RestartPolicy' => {
'Name' => restart_policy,
'MaximumRetryCount' => restart_maximum_retry_count,
},
'ReadonlyRootfs' => ro_rootfs,
'Sysctls' => sysctls,
'Ulimits' => ulimits_to_hash,
'UsernsMode' => userns_mode,
'UTSMode' => uts_mode,
'VolumesFrom' => volumes_from,
'VolumeDriver' => volume_driver,
},
}
net_config = {
'NetworkingConfig' => {
'EndpointsConfig' => {
network_mode => {
'IPAMConfig' => {
'IPv4Address' => ip_address,
},
},
},
},
} if network_mode
config.merge! net_config
Docker::Container.create(config, connection)
end
end
end
action :start do
return if state['Restarting']
return if state['Running']
converge_by "starting #{container_name}" do
with_retries do
container.start
timeout ? container.wait(timeout) : container.wait unless detach
end
wait_running_state(true) if detach
end
end
action :stop do
return unless state['Running']
kill_after_str = " (will kill after #{kill_after}s)" if kill_after != -1
converge_by "stopping #{container_name} #{kill_after_str}" do
begin
with_retries do
container.stop!('timeout' => kill_after)
wait_running_state(false)
end
rescue Docker::Error::TimeoutError
raise Docker::Error::TimeoutError, "Container failed to stop, consider adding kill_after to the container #{container_name}"
end
end
end
action :kill do
return unless state['Running']
converge_by "killing #{container_name}" do
with_retries { container.kill(signal: signal) }
end
end
action :run do
validate_container_create
call_action(:create)
call_action(:start)
call_action(:delete) if autoremove
end
action :run_if_missing do
return if current_resource
call_action(:run)
end
action :pause do
return if state['Paused']
converge_by "pausing #{container_name}" do
with_retries { container.pause }
end
end
action :unpause do
return if current_resource && !state['Paused']
converge_by "unpausing #{container_name}" do
with_retries { container.unpause }
end
end
action :restart do
kill_after_str = " (will kill after #{kill_after}s)" if kill_after != -1
converge_by "restarting #{container_name} #{kill_after_str}" do
current_resource ? container.restart('timeout' => kill_after) : call_action(:run)
end
end
action :reload do
converge_by "reloading #{container_name}" do
with_retries { container.kill(signal: 'SIGHUP') }
end
end
action :redeploy do
validate_container_create
# never start containers resulting from a previous action :create #432
should_create = state['Running'] == false && state['StartedAt'] == '0001-01-01T00:00:00Z'
call_action(:delete)
call_action(should_create ? :create : :run)
end
action :delete do
return unless current_resource
call_action(:unpause)
call_action(:stop)
converge_by "deleting #{container_name}" do
with_retries { container.delete(force: force, v: remove_volumes) }
end
end
action :remove do
call_action(:delete)
end
action :commit do
converge_by "committing #{container_name}" do
with_retries do
new_image = container.commit
new_image.tag('repo' => repo, 'tag' => tag, 'force' => force)
end
end
end
action :export do
raise "Please set outfile property on #{container_name}" if outfile.nil?
converge_by "exporting #{container_name}" do
with_retries do
::File.open(outfile, 'w') { |f| container.export { |chunk| f.write(chunk) } }
end
end
end
end
end

View File

@ -0,0 +1,21 @@
module DockerCookbook
class DockerExec < DockerBase
resource_name :docker_exec
property :host, [String, nil], default: lazy { default_host }
property :command, Array
property :container, String
property :timeout, Numeric, default: 60
property :container_obj, Docker::Container, desired_state: false
alias cmd command
action :run do
converge_by "executing #{command} on #{container}" do
with_retries { container_obj Docker::Container.get(container, {}, connection) }
container_obj.exec(command, wait: timeout)
end
end
end
end

View File

@ -0,0 +1,94 @@
module DockerCookbook
class DockerImage < DockerBase
require 'docker'
require_relative 'helpers_image'
resource_name :docker_image
# Modify the default of read_timeout from 60 to 120
property :read_timeout, default: 120, desired_state: false
# https://docs.docker.com/reference/api/docker_remote_api_v1.20/
property :destination, [String, nil]
property :force, Boolean, default: false
property :host, [String, nil], default: lazy { default_host }, desired_state: false
property :nocache, Boolean, default: false
property :noprune, Boolean, default: false
property :repo, String, name_property: true
property :rm, Boolean, default: true
property :source, String
property :tag, String, default: 'latest'
alias image repo
alias image_name repo
alias no_cache nocache
alias no_prune noprune
#########
# Actions
#########
default_action :pull
declare_action_class.class_eval do
include DockerHelpers::Image
def whyrun_supported?
true
end
end
action :build do
converge_by "Build image #{image_identifier}" do
build_image
end
end
action :build_if_missing do
return if Docker::Image.exist?(image_identifier, {}, connection)
action_build
end
action :import do
return if Docker::Image.exist?(image_identifier, {}, connection)
converge_by "Import image #{image_identifier}" do
import_image
end
end
action :pull do
# We already did the work, but we need to report what we did!
converge_by "Pull image #{image_identifier}" do
end if pull_image
end
action :pull_if_missing do
return if Docker::Image.exist?(image_identifier, {}, connection)
action_pull
end
action :push do
converge_by "Push image #{image_identifier}" do
push_image
end
end
action :remove do
return unless Docker::Image.exist?(image_identifier, {}, connection)
converge_by "Remove image #{image_identifier}" do
remove_image
end
end
action :save do
converge_by "Save image #{image_identifier}" do
save_image
end
end
action :load do
converge_by "load image #{image_identifier}" do
load_image
end
end
end
end

View File

@ -0,0 +1,40 @@
module DockerCookbook
class DockerInstallationBinary < DockerBase
require_relative 'helpers_installation_binary'
include DockerHelpers::InstallationBinary
#####################
# Resource properties
#####################
resource_name :docker_installation_binary
property :checksum, String, default: lazy { default_checksum }, desired_state: false
property :source, String, default: lazy { default_source }, desired_state: false
property :version, String, default: lazy { default_version }, desired_state: false
default_action :create
#########
# Actions
#########
action :create do
# Pull a precompiled binary off the network
remote_file docker_bin do
source new_resource.source
checksum new_resource.checksum
owner 'root'
group 'root'
mode '0755'
action :create
end
end
action :delete do
file docker_bin do
action :delete
end
end
end
end

View File

@ -0,0 +1,32 @@
module DockerCookbook
class DockerInstallationPackage < DockerBase
require_relative 'helpers_installation_package'
include DockerHelpers::InstallationPackage
# Resource properties
resource_name :docker_installation_package
provides :docker_installation, platform: 'amazon'
property :package_name, String, default: lazy { default_package_name }, desired_state: false
property :package_version, String, default: lazy { version_string(version) }, desired_state: false
property :version, String, default: lazy { default_docker_version }, desired_state: false
property :package_options, String, desired_state: false
# Actions
action :create do
package package_name do
version package_version
options package_options
action :install
end
end
action :delete do
package package_name do
action :remove
end
end
end
end

View File

@ -0,0 +1,51 @@
module DockerCookbook
class DockerInstallationScript < DockerBase
#####################
# Resource properties
#####################
resource_name :docker_installation_script
provides :docker_installation, os: 'linux'
property :repo, %w(main test experimental), default: 'main', desired_state: false
property :script_url, String, default: lazy { default_script_url }, desired_state: false
default_action :create
################
# helper methods
################
def default_script_url
case repo
when 'main'
'https://get.docker.com/'
when 'test'
'https://test.docker.com/'
when 'experimental'
'https://experimental.docker.com/'
end
end
#########
# Actions
#########
action :create do
package 'curl' do
action :install
end
execute 'install docker' do
command "curl -sSL #{script_url} | sh"
creates '/usr/bin/docker'
end
end
action :delete do
package 'docker-engine' do
action :remove
end
end
end
end

View File

@ -0,0 +1,47 @@
module DockerCookbook
class DockerInstallationTarball < DockerBase
require_relative 'helpers_installation_tarball'
include DockerHelpers::InstallationTarball
#####################
# Resource properties
#####################
resource_name :docker_installation_tarball
property :checksum, String, default: lazy { default_checksum }, desired_state: false
property :source, String, default: lazy { default_source }, desired_state: false
property :version, String, default: lazy { default_version }, desired_state: false
default_action :create
#########
# Actions
#########
action :create do
# Pull a precompiled binary off the network
remote_file docker_tarball do
source new_resource.source
checksum new_resource.checksum
owner 'root'
group 'root'
mode '0755'
action :create
notifies :run, 'execute[extract tarball]', :immediately
end
execute 'extract tarball' do
action :nothing
command "tar -xzf #{docker_tarball} --strip-components=1 -C #{docker_bin_prefix}"
creates docker_bin
end
end
action :delete do
file docker_bin do
action :delete
end
end
end
end

View File

@ -0,0 +1,127 @@
module DockerCookbook
class DockerNetwork < DockerBase
require 'docker'
require_relative 'helpers_network'
include DockerHelpers::Network
resource_name :docker_network
property :auxiliary_addresses, [String, Array, nil], coerce: proc { |v| coerce_auxiliary_addresses(v) }
property :container, String, desired_state: false
property :driver, String
property :driver_opts, PartialHashType
property :gateway, [String, Array, nil], coerce: proc { |v| coerce_gateway(v) }
property :host, [String, nil], default: lazy { default_host }, desired_state: false
property :id, String
property :ip_range, [String, Array, nil], coerce: proc { |v| coerce_ip_range(v) }
property :ipam_driver, String
property :network, Docker::Network, desired_state: false
property :network_name, String, name_property: true
property :subnet, [String, Array, nil], coerce: proc { |v| coerce_subnet(v) }
alias aux_address auxiliary_addresses
load_current_value do
begin
with_retries { network Docker::Network.get(network_name, {}, connection) }
rescue Docker::Error::NotFoundError
current_value_does_not_exist!
end
aux_addr_ray = []
gateway_ray = []
ip_range_ray = []
subnet_ray = []
network.info['IPAM']['Config'].to_a.each do |conf|
conf.each do |key, value|
case key
when 'AuxiliaryAddresses'
aux_addr_ray << value
when 'Gateway'
gateway_ray << value
when 'IPRange'
ip_range_ray << value
when 'Subnet'
subnet_ray << value
end
end
end
auxiliary_addresses aux_addr_ray
gateway gateway_ray
ip_range ip_range_ray
subnet subnet_ray
driver network.info['Driver']
driver_opts network.info['Options']
end
action :create do
converge_if_changed do
action_delete
with_retries do
options = {}
options['Driver'] = driver if driver
options['Options'] = driver_opts if driver_opts
ipam_options = consolidate_ipam(subnet, ip_range, gateway, aux_address)
options['IPAM'] = { 'Config' => ipam_options } unless ipam_options.empty?
options['IPAM']['Driver'] = ipam_driver if ipam_driver
Docker::Network.create(network_name, options)
end
end
end
action :delete do
return unless current_resource
converge_by "deleting #{network_name}" do
with_retries do
network.delete
end
end
end
action :remove do
action_delete
end
action :connect do
unless container
raise Chef::Exceptions::ValidationFailed, 'Container id or name is required for action :connect'
end
if current_resource
container_index = network.info['Containers'].values.index { |c| c['Name'] == container }
if container_index.nil?
converge_by("connect #{container}") do
with_retries do
network.connect(container)
end
end
end
else
Chef::Log.warn("Cannot connect to #{network_name}: network does not exist")
end
end
action :disconnect do
unless container
raise Chef::Exceptions::ValidationFailed, 'Container id or name is required for action :disconnect'
end
if current_resource
container_index = network.info['Containers'].values.index { |c| c['Name'] == container }
unless container_index.nil?
converge_by("disconnect #{container}") do
with_retries do
network.disconnect(container)
end
end
end
else
Chef::Log.warn("Cannot disconnect from #{network_name}: network does not exist")
end
end
end
end

View File

@ -0,0 +1,38 @@
module DockerCookbook
class DockerRegistry < DockerBase
require 'docker'
require_relative 'helpers_auth'
resource_name :docker_registry
property :email, [String, nil]
property :password, [String, nil]
property :serveraddress, [String, nil], name_property: true
property :username, [String, nil]
action :login do
tries = api_retries
registry_host = parse_registry_host(serveraddress)
(node.run_state['docker_auth'] ||= {})[registry_host] = {
'serveraddress' => registry_host,
'username' => username,
'password' => password,
'email' => email,
}
begin
Docker.connection.post(
'/auth', {},
body: node.run_state['docker_auth'][registry_host].to_json
)
rescue Docker::Error::ServerError, Docker::Error::UnauthorizedError
raise Docker::Error::AuthenticationError, "#{username} failed to authenticate with #{serveraddress}" if (tries -= 1) == 0
retry
end
true
end
end
end

View File

@ -0,0 +1,129 @@
module DockerCookbook
require_relative 'docker_service_base'
class DockerService < DockerServiceBase
resource_name :docker_service
# register with the resource resolution system
provides :docker_service
# installation type and service_manager
property :install_method, %w(binary script package tarball none auto), default: 'auto', desired_state: false
property :service_manager, %w(execute sysvinit upstart systemd auto), default: 'auto', desired_state: false
# docker_installation_script
property :repo, desired_state: false
property :script_url, String, desired_state: false
# docker_installation_binary and tarball
property :checksum, String, desired_state: false
property :docker_bin, String, desired_state: false
property :source, String, desired_state: false
# docker_installation_package
property :package_version, String, desired_state: false
# binary, package and tarball
property :version, String, desired_state: false
property :package_options, [String, nil], desired_state: false
################
# Helper Methods
################
def validate_install_method
if property_is_set?(:version) &&
install_method != 'binary' &&
install_method != 'package' &&
install_method != 'tarball'
raise Chef::Exceptions::ValidationFailed, 'Version property only supported for binary, package and tarball installation methods'
end
end
def copy_properties_to(to, *properties)
properties = self.class.properties.keys if properties.empty?
properties.each do |p|
# If the property is set on from, and exists on to, set the
# property on to
if to.class.properties.include?(p) && property_is_set?(p)
to.send(p, send(p))
end
end
end
action_class.class_eval do
def installation(&block)
case install_method
when 'auto'
install = docker_installation(name, &block)
when 'binary'
install = docker_installation_binary(name, &block)
when 'script'
install = docker_installation_script(name, &block)
when 'package'
install = docker_installation_package(name, &block)
when 'tarball'
install = docker_installation_tarball(name, &block)
when 'none'
Chef::Log.info('Skipping Docker installation. Assuming it was handled previously.')
return
end
copy_properties_to(install)
install
end
def svc_manager(&block)
case service_manager
when 'auto'
svc = docker_service_manager(name, &block)
when 'execute'
svc = docker_service_manager_execute(name, &block)
when 'sysvinit'
svc = docker_service_manager_sysvinit(name, &block)
when 'upstart'
svc = docker_service_manager_upstart(name, &block)
when 'systemd'
svc = docker_service_manager_systemd(name, &block)
end
copy_properties_to(svc)
svc
end
end
#########
# Actions
#########
action :create do
validate_install_method
installation do
action :create
notifies :restart, new_resource, :immediately
end
end
action :delete do
installation do
action :delete
end
end
action :start do
svc_manager do
action :start
end
end
action :stop do
svc_manager do
action :stop
end
end
action :restart do
svc_manager do
action :restart
end
end
end
end

View File

@ -0,0 +1,123 @@
module DockerCookbook
class DockerServiceBase < DockerBase
################
# Helper Methods
################
require 'docker'
require_relative 'helpers_service'
include DockerHelpers::Service
#####################
# resource properties
#####################
resource_name :docker_service_base
# register with the resource resolution system
provides :docker_service_manager
# daemon management
property :instance, String, name_property: true, required: true, desired_state: false
property :auto_restart, Boolean, default: false
property :api_cors_header, [String, nil]
property :bridge, [String, nil]
property :bip, [IPV4_ADDR, IPV4_CIDR, IPV6_ADDR, IPV6_CIDR, nil]
property :cluster_store, [String, nil]
property :cluster_advertise, [String, nil]
property :cluster_store_opts, ArrayType
property :debug, [Boolean, nil]
property :daemon, Boolean, default: true
property :dns, ArrayType
property :dns_search, [Array, nil]
property :exec_driver, ['native', 'lxc', nil]
property :exec_opts, ArrayType
property :fixed_cidr, [String, nil]
property :fixed_cidr_v6, [String, nil]
property :group, [String, nil]
property :graph, [String, nil]
property :host, [String, Array], coerce: proc { |v| coerce_host(v) }
property :icc, [Boolean, nil]
property :insecure_registry, [Array, String, nil], coerce: proc { |v| coerce_insecure_registry(v) }
property :ip, [IPV4_ADDR, IPV6_ADDR, nil]
property :ip_forward, [Boolean, nil]
property :ipv4_forward, Boolean, default: true
property :ipv6_forward, Boolean, default: true
property :ip_masq, [Boolean, nil]
property :iptables, [Boolean, nil]
property :ipv6, [Boolean, nil]
property :log_level, [:debug, :info, :warn, :error, :fatal, nil]
property :labels, [String, Array], coerce: proc { |v| coerce_daemon_labels(v) }, desired_state: false
property :log_driver, %w( json-file syslog journald gelf fluentd awslogs splunk none )
property :log_opts, ArrayType
property :mount_flags, String, default: 'slave'
property :mtu, [String, nil]
property :pidfile, String, default: lazy { "/var/run/#{docker_name}.pid" }
property :registry_mirror, [String, nil]
property :storage_driver, ArrayType
property :selinux_enabled, [Boolean, nil]
property :storage_opts, ArrayType
property :default_ulimit, ArrayType
property :userland_proxy, [Boolean, nil]
property :disable_legacy_registry, [Boolean, nil]
property :userns_remap, [String, nil]
# These are options specific to systemd configuration such as
# LimitNOFILE or TasksMax that you may wannt to use to customize
# the environment in which Docker runs.
property :systemd_opts, ArrayType
# These are unvalidated daemon arguments passed in as a string.
property :misc_opts, [String, nil]
# environment variables to set before running daemon
property :http_proxy, [String, nil]
property :https_proxy, [String, nil]
property :no_proxy, [String, nil]
property :tmpdir, [String, nil]
# logging
property :logfile, String, default: '/var/log/docker.log'
# docker-wait-ready timeout
property :service_timeout, Integer, default: 20
allowed_actions :start, :stop, :restart
alias label labels
alias tlscacert tls_ca_cert
alias tlscert tls_server_cert
alias tlskey tls_server_key
alias tlsverify tls_verify
alias run_group group
declare_action_class.class_eval do
def libexec_dir
return '/usr/libexec/docker' if node['platform_family'] == 'rhel'
'/usr/lib/docker'
end
def create_docker_wait_ready
directory libexec_dir do
owner 'root'
group 'root'
mode '0755'
action :create
end
template "#{libexec_dir}/#{docker_name}-wait-ready" do
source 'default/docker-wait-ready.erb'
owner 'root'
group 'root'
mode '0755'
variables(
docker_cmd: docker_cmd,
libexec_dir: libexec_dir,
service_timeout: service_timeout
)
cookbook 'docker'
action :create
end
end
end
end
end

View File

@ -0,0 +1,56 @@
module DockerCookbook
class DockerServiceManagerExecute < DockerServiceBase
resource_name :docker_service_manager_execute
provides :docker_service_manager, os: 'linux'
# Start the service
action :start do
# enable ipv4 forwarding
execute 'enable net.ipv4.conf.all.forwarding' do
command '/sbin/sysctl net.ipv4.conf.all.forwarding=1'
not_if '/sbin/sysctl -q -n net.ipv4.conf.all.forwarding | grep ^1$'
action :run
end
# enable ipv6 forwarding
execute 'enable net.ipv6.conf.all.forwarding' do
command '/sbin/sysctl net.ipv6.conf.all.forwarding=1'
not_if '/sbin/sysctl -q -n net.ipv6.conf.all.forwarding | grep ^1$'
action :run
end
# Go doesn't support detaching processes natively, so we have
# to manually fork it from the shell with &
# https://github.com/docker/docker/issues/2758
bash "start docker #{name}" do
code "#{docker_daemon_cmd} >> #{logfile} 2>&1 &"
environment 'HTTP_PROXY' => http_proxy,
'HTTPS_PROXY' => https_proxy,
'NO_PROXY' => no_proxy,
'TMPDIR' => tmpdir
not_if "ps -ef | grep -v grep | grep #{Shellwords.escape(docker_daemon_cmd)}"
action :run
end
create_docker_wait_ready
execute 'docker-wait-ready' do
command "#{libexec_dir}/#{docker_name}-wait-ready"
end
end
action :stop do
execute "stop docker #{name}" do
command "kill `cat #{pidfile}` && while [ -e #{pidfile} ]; do sleep 1; done"
timeout 10
only_if "#{docker_cmd} ps | head -n 1 | grep ^CONTAINER"
end
end
action :restart do
action_stop
action_start
end
end
end

View File

@ -0,0 +1,116 @@
module DockerCookbook
class DockerServiceManagerSystemd < DockerServiceBase
resource_name :docker_service_manager_systemd
provides :docker_service_manager, platform: 'fedora'
provides :docker_service_manager, platform: %w(redhat centos scientific oracle) do |node| # ~FC005
node['platform_version'].to_f >= 7.0
end
provides :docker_service_manager, platform: 'debian' do |node|
node['platform_version'].to_f >= 8.0
end
provides :docker_service_manager, platform: 'ubuntu' do |node|
node['platform_version'].to_f >= 15.04
end
action :start do
create_docker_wait_ready
# stock systemd unit file
template "/lib/systemd/system/#{docker_name}.service" do
source 'systemd/docker.service.erb'
owner 'root'
group 'root'
mode '0644'
variables(
docker_name: docker_name,
docker_socket: connect_socket.sub(%r{unix://|fd://}, ''),
docker_mount_flags: mount_flags
)
cookbook 'docker'
action :create
not_if { docker_name == 'default' && ::File.exist?('/lib/systemd/system/docker.service') }
end
# stock systemd socket file
template "/lib/systemd/system/#{docker_name}.socket" do
source 'systemd/docker.socket.erb'
owner 'root'
group 'root'
mode '0644'
variables(
docker_name: docker_name,
docker_socket: connect_socket.sub(%r{unix://|fd://}, '')
)
cookbook 'docker'
action :create
not_if { docker_name == 'default' && ::File.exist?('/lib/systemd/system/docker.socket') }
end
template "/etc/systemd/system/#{docker_name}.service" do
source 'systemd/docker.service-override.erb'
owner 'root'
group 'root'
mode '0644'
variables(
config: new_resource,
docker_daemon_cmd: docker_daemon_cmd,
systemd_args: systemd_args,
docker_wait_ready: "#{libexec_dir}/#{docker_name}-wait-ready",
docker_mount_flags: mount_flags
)
cookbook 'docker'
notifies :run, 'execute[systemctl daemon-reload]', :immediately
action :create
end
# this overrides the main systemd socket
template "/etc/systemd/system/#{docker_name}.socket" do
source 'systemd/docker.socket-override.erb'
owner 'root'
group 'root'
mode '0644'
variables(
config: new_resource,
docker_name: docker_name,
docker_socket: connect_socket.sub(%r{unix://|fd://}, '')
)
cookbook 'docker'
notifies :run, 'execute[systemctl daemon-reload]', :immediately
action :create
end
# avoid 'Unit file changed on disk' warning
execute 'systemctl daemon-reload' do
command '/bin/systemctl daemon-reload'
action :nothing
end
# service management resource
service docker_name do
provider Chef::Provider::Service::Systemd
supports status: true
action [:enable, :start]
only_if { ::File.exist?("/lib/systemd/system/#{docker_name}.service") }
end
end
action :stop do
# service management resource
service docker_name do
provider Chef::Provider::Service::Systemd
supports status: true
action [:disable, :stop]
only_if { ::File.exist?("/lib/systemd/system/#{docker_name}.service") }
end
end
action :restart do
action_stop
action_start
end
end
end

View File

@ -0,0 +1,87 @@
module DockerCookbook
class DockerServiceManagerSysvinitDebian < DockerServiceBase
resource_name :docker_service_manager_sysvinit_debian
provides :docker_service_manager, platform: 'debian' do |node|
node['platform_version'].to_f < 8.0
end
provides :docker_service_manager, platform: 'ubuntu' do |node|
node['platform_version'].to_f < 12.04
end
provides :docker_service_manager_sysvinit, platform: 'debian' do |node|
node['platform_version'].to_f < 8.0
end
provides :docker_service_manager_sysvinit, platform: 'ubuntu' do |node|
node['platform_version'].to_f < 12.04
end
action :start do
create_docker_wait_ready
create_init
create_service
end
action :stop do
create_init
s = create_service
s.action :stop
end
action :restart do
action_stop
action_start
end
action_class.class_eval do
def create_init
execute 'groupadd docker' do
not_if 'getent group docker'
action :run
end
link dockerd_bin_link do
to dockerd_bin
link_type :hard
action :create
end
template "/etc/init.d/#{docker_name}" do
source 'sysvinit/docker-debian.erb'
owner 'root'
group 'root'
mode '0755'
variables(
docker_name: docker_name,
dockerd_bin_link: dockerd_bin_link,
docker_daemon_arg: docker_daemon_arg,
docker_wait_ready: "#{libexec_dir}/#{docker_name}-wait-ready"
)
cookbook 'docker'
action :create
end
template "/etc/default/#{docker_name}" do
source 'default/docker.erb'
variables(
config: new_resource,
dockerd_bin_link: dockerd_bin_link,
docker_daemon_opts: docker_daemon_opts.join(' ')
)
cookbook 'docker'
action :create
end
end
def create_service
service docker_name do
provider Chef::Provider::Service::Init::Debian
supports restart: true, status: true
action [:enable, :start]
end
end
end
end
end

View File

@ -0,0 +1,81 @@
module DockerCookbook
class DockerServiceManagerSysvinitRhel < DockerServiceBase
resource_name :docker_service_manager_sysvinit_rhel
provides :docker_service_manager, platform: 'amazon'
provides :docker_service_manager, platform: 'suse'
provides :docker_service_manager, platform: %w(redhat centos scientific oracle) do |node| # ~FC005
node['platform_version'].to_f <= 7.0
end
provides :docker_service_manager_sysvinit, platform: 'amazon'
provides :docker_service_manager_sysvinit, platform: 'suse'
provides :docker_service_manager_sysvinit, platform: %w(redhat centos scientific oracle) do |node| # ~FC005
node['platform_version'].to_f <= 7.0
end
action :start do
create_docker_wait_ready
create_init
create_service
end
action :stop do
create_init
s = create_service
s.action :stop
end
action :restart do
action_stop
action_start
end
action_class.class_eval do
def create_init
execute 'groupadd docker' do
not_if 'getent group docker'
action :run
end
link dockerd_bin_link do
to dockerd_bin
link_type :hard
action :create
end
template "/etc/init.d/#{docker_name}" do
source 'sysvinit/docker-rhel.erb'
owner 'root'
group 'root'
mode '0755'
variables(
docker_name: docker_name,
dockerd_bin_link: dockerd_bin_link,
docker_daemon_cmd: docker_daemon_cmd,
docker_wait_ready: "#{libexec_dir}/#{docker_name}-wait-ready"
)
cookbook 'docker'
action :create
end
template "/etc/sysconfig/#{docker_name}" do
source 'sysconfig/docker.erb'
variables(
config: new_resource,
docker_daemon_opts: docker_daemon_opts.join(' ')
)
cookbook 'docker'
action :create
end
end
def create_service
service docker_name do
supports restart: true, status: true
action [:enable, :start]
end
end
end
end
end

View File

@ -0,0 +1,63 @@
module DockerCookbook
class DockerServiceManagerUpstart < DockerServiceBase
resource_name :docker_service_manager_upstart
provides :docker_service_manager, platform: 'ubuntu'
provides :docker_service_manager, platform: 'linuxmint'
action :start do
create_docker_wait_ready
link dockerd_bin_link do
to dockerd_bin
link_type :hard
action :create
end
template "/etc/init/#{docker_name}.conf" do
source 'upstart/docker.conf.erb'
owner 'root'
group 'root'
mode '0644'
variables(
docker_name: docker_name,
dockerd_bin_link: dockerd_bin_link,
docker_daemon_arg: docker_daemon_arg,
docker_wait_ready: "#{libexec_dir}/#{docker_name}-wait-ready"
)
cookbook 'docker'
action :create
end
template "/etc/default/#{docker_name}" do
source 'default/docker.erb'
variables(
config: new_resource,
dockerd_bin_link: dockerd_bin_link,
docker_daemon_opts: docker_daemon_opts.join(' ')
)
cookbook 'docker'
action :create
end
service docker_name do
provider Chef::Provider::Service::Upstart
supports status: true
action :start
end
end
action :stop do
service docker_name do
provider Chef::Provider::Service::Upstart
supports status: true
action :stop
end
end
action :restart do
action_stop
action_start
end
end
end

View File

@ -0,0 +1,27 @@
module DockerCookbook
class DockerTag < DockerBase
resource_name :docker_tag
property :target_repo, String, name_property: true
property :target_tag, String
property :to_repo, String
property :to_tag, String
property :force, Boolean, default: false
#########
# Actions
#########
action :tag do
return if force == false && Docker::Image.exist?("#{to_repo}:#{to_tag}")
begin
converge_by "update #{target_repo}:#{target_tag} to #{to_repo}:#{to_tag}" do
i = Docker::Image.get("#{target_repo}:#{target_tag}")
i.tag('repo' => to_repo, 'tag' => to_tag, 'force' => force)
end
rescue Docker::Error => e
raise e.message
end
end
end
end

View File

@ -0,0 +1,33 @@
module DockerCookbook
class DockerVolume < DockerBase
require 'docker'
resource_name :docker_volume
property :driver, String, desired_state: false
property :host, [String, nil], default: lazy { default_host }, desired_state: false
property :opts, [String, Array, nil], desired_state: false
property :volume, Docker::Volume, desired_state: false
property :volume_name, String, name_property: true
load_current_value do
begin
with_retries { volume Docker::Volume.get(volume_name, connection) }
rescue Docker::Error::NotFoundError
current_value_does_not_exist!
end
end
action :create do
converge_by "creating volume #{volume_name}" do
Docker::Volume.create(volume_name, {}, connection)
end if volume.nil?
end
action :remove do
converge_by "removing volume #{volume_name}" do
volume.remove
end unless volume.nil?
end
end
end

View File

@ -0,0 +1,10 @@
module DockerCookbook
module DockerHelpers
module Authentication
# https://github.com/docker/docker/blob/4fcb9ac40ce33c4d6e08d5669af6be5e076e2574/registry/auth.go#L231
def parse_registry_host(val)
val.sub(%r{https?://}, '').split('/').first
end
end
end
end

View File

@ -0,0 +1,110 @@
module DockerCookbook
module DockerHelpers
module Base
require 'shellwords'
# Misc
def to_snake_case(name)
# ExposedPorts -> _exposed_ports
name = name.gsub(/[A-Z]/) { |x| "_#{x.downcase}" }
# _exposed_ports -> exposed_ports
name = name[1..-1] if name.start_with?('_')
name
end
##########
# coersion
##########
def coerce_labels(v)
case v
when Hash, nil
v
else
Array(v).each_with_object({}) do |label, h|
parts = label.split(':')
h[parts[0]] = parts[1]
end
end
end
def coerce_shell_command(v)
return nil if v.nil?
return DockerBase::ShellCommandString.new(
::Shellwords.join(v)
) if v.is_a?(Array)
DockerBase::ShellCommandString.new(v)
end
################
# Helper methods
################
def api_version
@api_version ||= Docker.version(connection)['ApiVersion']
end
def connection
@connection ||= begin
opts = {}
opts[:read_timeout] = read_timeout if read_timeout
opts[:write_timeout] = write_timeout if write_timeout
if host =~ /^tcp:/
opts[:scheme] = 'https' if tls || !tls_verify.nil?
opts[:ssl_ca_file] = tls_ca_cert if tls_ca_cert
opts[:client_cert] = tls_client_cert if tls_client_cert
opts[:client_key] = tls_client_key if tls_client_key
end
Docker::Connection.new(host || Docker.url, opts)
end
end
def with_retries(&_block)
tries = api_retries
begin
yield
# Only catch errors that can be fixed with retries.
rescue Docker::Error::ServerError, # 404
Docker::Error::UnexpectedResponseError, # 400
Docker::Error::TimeoutError,
Docker::Error::IOError
tries -= 1
retry if tries > 0
raise
end
end
def call_action(_action)
new_resource.run_action
end
def default_host
return nil unless ENV['DOCKER_HOST']
ENV['DOCKER_HOST']
end
def default_tls
return nil unless ENV['DOCKER_TLS']
ENV['DOCKER_TLS']
end
def default_tls_verify
return nil unless ENV['DOCKER_TLS_VERIFY']
ENV['DOCKER_TLS_VERIFY']
end
def default_tls_cert_path(v)
return nil unless ENV['DOCKER_CERT_PATH']
case v
when 'ca'
"#{ENV['DOCKER_CERT_PATH']}/ca.pem"
when 'cert'
"#{ENV['DOCKER_CERT_PATH']}/cert.pem"
when 'key'
"#{ENV['DOCKER_CERT_PATH']}/key.pem"
end
end
end
end
end

Some files were not shown because too many files have changed in this diff Show More