Add Java to vagrant image using chef

This commit is contained in:
Neil Lalonde 2013-03-21 18:51:18 -04:00
parent d81a3230b5
commit 4d237c46a0
74 changed files with 5821 additions and 0 deletions

1
Vagrantfile vendored
View file

@ -50,5 +50,6 @@ Vagrant.configure("2") do |config|
chef.add_recipe "recipe[apt]"
chef.add_recipe "recipe[build-essential]"
chef.add_recipe "recipe[vim]"
chef.add_recipe "recipe[java]"
end
end

View file

@ -0,0 +1,28 @@
## v1.1.4:
* [COOK-2146] - style updates
## v1.1.2:
* [COOK-1989] - fix scope for handler local variable to the enable block
## v1.1.0:
* [COOK-1645] - properly delete old handlers
* [COOK-1322] - support platforms that use 'wheel' as root group'
## v1.0.8:
* [COOK-1177] - doesn't work on windows due to use of unix specific attributes
## v1.0.6:
* [COOK-1069] - typo in chef_handler readme
## v1.0.4:
* [COOK-654] dont try and access a class before it has been loaded
* fix bad boolean check (if vs unless)
## v1.0.2:
* [COOK-620] ensure handler code is reloaded during daemonized chef runs

View file

@ -0,0 +1,29 @@
If you would like to contribute, please open a ticket in JIRA:
* http://tickets.opscode.com
Create the ticket in the COOK project and use the cookbook name as the
component.
For all code contributions, we ask that contributors sign a
contributor license agreement (CLA). Instructions may be found here:
* http://wiki.opscode.com/display/chef/How+to+Contribute
When contributing changes to individual cookbooks, please do not
modify the version number in the metadata.rb. Also please do not
update the CHANGELOG.md for a new version. Not all changes to a
cookbook may be merged and released in the same versions. Opscode will
handle the version updates during the release process. You are welcome
to correct typos or otherwise make updates to documentation in the
README.
If a contribution adds new platforms or platform versions, indicate
such in the body of the commit message(s), and update the relevant
COOK ticket. When writing commit messages, it is helpful for others if
you indicate the COOK ticket. For example:
git commit -m '[COOK-1041] Updated pool resource to correctly delete.'
In the ticket itself, it is also helpful if you include log output of
a successful Chef run, but this is not absolutely required.

View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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,103 @@
Description
===========
Creates a configured handler path for distributing [Chef report and exception handlers](http://wiki.opscode.com/display/chef/Exception+and+Report+Handlers). Also exposes an LWRP for enabling Chef handlers from within recipe code (as opposed to hard coding in the client.rb file). This is useful for cookbook authors who may want to ship a product specific handler (see the `cloudkick` cookbook for an example) with their cookbook.
Attributes
==========
`node["chef_handler"]["handler_path"]` - location to drop off handlers directory, default is `/var/chef/handlers`.
Resource/Provider
=================
`chef_handler`
--------------
Requires, configures and enables handlers on the node for the current Chef run. Also has the ability to pass arguments to the handlers initializer. This allows initialization data to be pulled from a node's attribute data.
It is best to declare `chef_handler` resources early on in the compile phase so they are available to fire for any exceptions during the Chef run. If you have a base role you would want any recipes that register Chef handlers to come first in the run_list.
### Actions
- :enable: Enables the Chef handler for the current Chef run on the current node
- :disable: Disables the Chef handler for the current Chef run on the current node
### Attribute Parameters
- class_name: name attribute. The name of the handler class (can be module name-spaced).
- source: full path to the handler file. can also be a gem path if the handler ships as part of a Ruby gem.
- arguments: an array of arguments to pass the handler's class initializer
- supports: type of Chef Handler to register as, ie :report, :exception or both. default is `:report => true, :exception => true`
### Example
# register the Chef::Handler::JsonFile handler
# that ships with the Chef gem
chef_handler "Chef::Handler::JsonFile" do
source "chef/handler/json_file"
arguments :path => '/var/chef/reports'
action :enable
end
# do the same but during the compile phase
chef_handler "Chef::Handler::JsonFile" do
source "chef/handler/json_file"
arguments :path => '/var/chef/reports'
action :nothing
end.run_action(:enable)
# handle exceptions only
chef_handler "Chef::Handler::JsonFile" do
source "chef/handler/json_file"
arguments :path => '/var/chef/reports'
supports :exception => true
action :enable
end
# enable the CloudkickHandler which was
# dropped off in the default handler path.
# passes the oauth key/secret to the handler's
# intializer.
chef_handler "CloudkickHandler" do
source "#{node['chef_handler']['handler_path']}/cloudkick_handler.rb"
arguments [node['cloudkick']['oauth_key'], node['cloudkick']['oauth_secret']]
action :enable
end
Usage
=====
default
-------
Put the recipe `chef_handler` at the start of the node's run list to make sure that custom handlers are dropped off early on in the Chef run and available for later recipes.
For information on how to write report and exception handlers for Chef, please see the Chef wiki pages:
http://wiki.opscode.com/display/chef/Exception+and+Report+Handlers
json_file
---------
Leverages the `chef_handler` LWRP to automatically register the `Chef::Handler::JsonFile` handler that ships as part of Chef. This handler serializes the run status data to a JSON file located at `/var/chef/reports`.
License and Author
==================
Author:: Seth Chisamore (<schisamo@opscode.com>)
Copyright:: 2011, Opscode, 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,30 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: chef_handlers
# Attribute:: default
#
# Copyright 2011-2013, Opscode, 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.
#
default["chef_handler"]["root_user"] = "root"
case platform
when "openbsd", "freebsd", "mac_os_x", "mac_os_x_server"
default["chef_handler"]["root_group"] = "wheel"
else
default["chef_handler"]["root_group"] = "root"
end
default["chef_handler"]["handler_path"] = "#{File.expand_path(File.join(Chef::Config[:file_cache_path], '..'))}/handlers"

View file

@ -0,0 +1 @@
This directory contains Chef handlers to distribute to your nodes.

View file

@ -0,0 +1,29 @@
{
"name": "chef_handler",
"description": "Distribute and enable Chef Exception and Report handlers",
"long_description": "Description\n===========\n\nCreates a configured handler path for distributing [Chef report and exception handlers](http://wiki.opscode.com/display/chef/Exception+and+Report+Handlers). Also exposes an LWRP for enabling Chef handlers from within recipe code (as opposed to hard coding in the client.rb file). This is useful for cookbook authors who may want to ship a product specific handler (see the `cloudkick` cookbook for an example) with their cookbook.\n\nAttributes\n==========\n\n`node[\"chef_handler\"][\"handler_path\"]` - location to drop off handlers directory, default is `/var/chef/handlers`.\n\nResource/Provider\n=================\n\n`chef_handler`\n--------------\n\nRequires, configures and enables handlers on the node for the current Chef run. Also has the ability to pass arguments to the handlers initializer. This allows initialization data to be pulled from a node's attribute data.\n\nIt is best to declare `chef_handler` resources early on in the compile phase so they are available to fire for any exceptions during the Chef run. If you have a base role you would want any recipes that register Chef handlers to come first in the run_list.\n\n### Actions\n\n- :enable: Enables the Chef handler for the current Chef run on the current node\n- :disable: Disables the Chef handler for the current Chef run on the current node\n\n### Attribute Parameters\n\n- class_name: name attribute. The name of the handler class (can be module name-spaced).\n- source: full path to the handler file. can also be a gem path if the handler ships as part of a Ruby gem.\n- arguments: an array of arguments to pass the handler's class initializer\n- supports: type of Chef Handler to register as, ie :report, :exception or both. default is `:report => true, :exception => true`\n\n### Example\n\n # register the Chef::Handler::JsonFile handler\n # that ships with the Chef gem\n chef_handler \"Chef::Handler::JsonFile\" do\n source \"chef/handler/json_file\"\n arguments :path => '/var/chef/reports'\n action :enable\n end\n\n # do the same but during the compile phase\n chef_handler \"Chef::Handler::JsonFile\" do\n source \"chef/handler/json_file\"\n arguments :path => '/var/chef/reports'\n action :nothing\n end.run_action(:enable)\n\n # handle exceptions only\n chef_handler \"Chef::Handler::JsonFile\" do\n source \"chef/handler/json_file\"\n arguments :path => '/var/chef/reports'\n supports :exception => true\n action :enable\n end\n\n\n # enable the CloudkickHandler which was\n # dropped off in the default handler path.\n # passes the oauth key/secret to the handler's\n # intializer.\n chef_handler \"CloudkickHandler\" do\n source \"#{node['chef_handler']['handler_path']}/cloudkick_handler.rb\"\n arguments [node['cloudkick']['oauth_key'], node['cloudkick']['oauth_secret']]\n action :enable\n end\n\n\nUsage\n=====\n\ndefault\n-------\n\nPut the recipe `chef_handler` at the start of the node's run list to make sure that custom handlers are dropped off early on in the Chef run and available for later recipes.\n\nFor information on how to write report and exception handlers for Chef, please see the Chef wiki pages:\nhttp://wiki.opscode.com/display/chef/Exception+and+Report+Handlers\n\njson_file\n---------\n\nLeverages the `chef_handler` LWRP to automatically register the `Chef::Handler::JsonFile` handler that ships as part of Chef. This handler serializes the run status data to a JSON file located at `/var/chef/reports`.\n\nLicense and Author\n==================\n\nAuthor:: Seth Chisamore (<schisamo@opscode.com>)\n\nCopyright:: 2011, Opscode, 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",
"maintainer": "Opscode, Inc.",
"maintainer_email": "cookbooks@opscode.com",
"license": "Apache 2.0",
"platforms": {
},
"dependencies": {
},
"recommendations": {
},
"suggestions": {
},
"conflicting": {
},
"providing": {
},
"replacing": {
},
"attributes": {
},
"groupings": {
},
"recipes": {
},
"version": "1.1.4"
}

View file

@ -0,0 +1,7 @@
name "chef_handler"
maintainer "Opscode, Inc."
maintainer_email "cookbooks@opscode.com"
license "Apache 2.0"
description "Distribute and enable Chef Exception and Report handlers"
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version "1.1.4"

View file

@ -0,0 +1,93 @@
#
# Author:: Seth Chisamore <schisamo@opscode.com>
# Cookbook Name:: chef_handler
# Provider:: default
#
# Copyright:: 2011-2013, Opscode, Inc <legal@opscode.com>
#
# 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.
#
def whyrun_supported?
true
end
action :enable do
# use load instead of require to ensure the handler file
# is reloaded into memory each chef run. fixes COOK-620
handler = nil
converge_by("load #{@new_resource.source}") do
begin
Object.send(:remove_const, klass)
GC.start
rescue
Chef::Log.debug("#{@new_resource.class_name} has not been loaded.")
end
file_name = @new_resource.source
file_name << ".rb" unless file_name =~ /.*\.rb$/
load file_name
handler = klass.send(:new, *collect_args(@new_resource.arguments))
end
@new_resource.supports.each do |type, enable|
if enable
# we have to re-enable the handler every chef run
# to ensure daemonized Chef always has the latest
# handler code. TODO: add a :reload action
converge_by("enable #{@new_resource} as a #{type} handler") do
Chef::Log.info("Enabling #{@new_resource} as a #{type} handler")
Chef::Config.send("#{type.to_s}_handlers").delete_if { |v| v.class.to_s.include? @new_resource.class_name.split('::', 3).last }
Chef::Config.send("#{type.to_s}_handlers") << handler
end
end
end
end
action :disable do
@new_resource.supports.each_key do |type|
if enabled?(type)
converge_by("disable #{@new_resource} as a #{type} handler") do
Chef::Log.info("Disabling #{@new_resource} as a #{type} handler")
Chef::Config.send("#{type.to_s}_handlers").delete_if { |v| v.class.to_s.include? @new_resource.class_name.split('::', 3).last }
end
end
end
end
def load_current_resource
@current_resource = Chef::Resource::ChefHandler.new(@new_resource.name)
@current_resource.class_name(@new_resource.class_name)
@current_resource.source(@new_resource.source)
@current_resource
end
private
def enabled?(type)
Chef::Config.send("#{type.to_s}_handlers").select do |handler|
handler.class.to_s.include? @new_resource.class_name
end.size >= 1
end
def collect_args(resource_args = [])
if resource_args.is_a? Array
resource_args
else
[resource_args]
end
end
def klass
@klass ||= begin
@new_resource.class_name.split('::').inject(Kernel) { |scope, const_name| scope.const_get(const_name) }
end
end

View file

@ -0,0 +1,33 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: chef_handlers
# Recipe:: default
#
# Copyright 2011, Opscode, 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.
#
Chef::Log.info("Chef Handlers will be at: #{node['chef_handler']['handler_path']}")
remote_directory node['chef_handler']['handler_path'] do
source 'handlers'
# Just inherit permissions on Windows, don't try to set POSIX perms
if node["platform"] != "windows"
owner node['chef_handler']['root_user']
group node['chef_handler']['root_group']
mode "0755"
recursive true
end
action :nothing
end.run_action(:create)

View file

@ -0,0 +1,28 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: chef_handlers
# Recipe:: json_file
#
# Copyright 2011, Opscode, 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.
#
# force resource actions in compile phase so exception handler
# fires for compile phase exceptions
chef_handler "Chef::Handler::JsonFile" do
source "chef/handler/json_file"
arguments :path => '/var/chef/reports'
action :nothing
end.run_action(:enable)

View file

@ -0,0 +1,34 @@
#
# Author:: Seth Chisamore <schisamo@opscode.com>
# Cookbook Name:: chef_handler
# Resource:: default
#
# Copyright:: 2011-2013, Opscode, Inc <legal@opscode.com>
#
# 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.
#
actions :enable, :disable
attribute :class_name, :kind_of => String, :name_attribute => true
attribute :source, :default => nil, :kind_of => String
attribute :arguments, :default => []
attribute :supports, :kind_of => Hash, :default => { :report => true, :exception => true }
# we have to set default for the supports attribute
# in initializer since it is a 'reserved' attribute name
def initialize(*args)
super
@action = :enable
@supports = { :report => true, :exception => true }
end

7
chef/cookbooks/java/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
.bundle
.cache
.kitchen
bin
#*#
*~
.#*#

View file

@ -0,0 +1,92 @@
## v1.10.0:
* [COOK-2400] - Allow java ark :url to be https
* [COOK-2436] - Upgrade needed for oracle jdk in java cookbook
## v1.9.6:
* [COOK-2412] - add support for Oracle Linux
## v1.9.4:
* [COOK-2083] - Run set-env-java-home in Java cookbook only if necessary
* [COOK-2332] - ark provider does not allow for *.tgz tarballs to be used
* [COOK-2345] - Java cookbook fails on CentOS6 (update-java-alternatives)
## v1.9.2:
* [COOK-2306] - FoodCritic fixes for java cookbook
## v1.9.0:
* [COOK-2236] - Update the Oracle Java version in the Java cookbook to
release 1.7u11
## v1.8.2:
* [COOK-2205] - Fix for missing /usr/lib/jvm/default-java on Debian
## v1.8.0:
* [COOK-2095] - Add windows support
## v1.7.0:
* [COOK-2001] - improvements for Oracle update-alternatives
- When installing an Oracle JDK it is now registered with a higher
priority than OpenJDK. (Related to COOK-1131.)
- When running both the oracle and oracle_i386 recipes, alternatives
are now created for both JDKs.
- Alternatives are now created for all binaries listed in version
specific attributes. (Related to COOK-1563 and COOK-1635.)
- When installing Oracke JDKs on Ubuntu, create .jinfo files for use
with update-java-alternatives. Commands to set/install
alternatives now only run if needed.
## v1.6.4:
* [COOK-1930] - fixed typo in attribute for java 5 on i586
## v1.6.2:
* whyrun support in `java_ark` LWRP
* CHEF-1804 compatibility
* [COOK-1786]- install Java 6u37 and Java 7u9
* [COOK-1819] -incorrect warning text about
`node['java']['oracle']['accept_oracle_download_terms']`
## v1.6.0:
* [COOK-1218] - Install Oracle JDK from Oracle download directly
* [COOK-1631] - set JAVA_HOME in openjdk recipe
* [COOK-1655] - Install correct architecture on Amazon Linux
## v1.5.4:
* [COOK-885] - update alternatives called on wrong file
* [COOK-1607] - use shellout instead of execute resource to update
alternatives
## v1.5.2:
* [COOK-1200] - remove sun-java6-jre on Ubuntu before installing
Oracle's Java
* [COOK-1260] - fails on Ubuntu 12.04 64bit with openjdk7
* [COOK-1265] - Oracle Java should symlink the jar command
## v1.5.0:
* [COOK-1146] - Oracle now prevents download of JDK via non-browser
* [COOK-1114] - fix File.exists?
## v1.4.2:
* [COOK-1051] - fix attributes typo and platform case switch
consistency
## v1.4.0:
* [COOK-858] - numerous updates: handle jdk6 and 7, switch from sun to
oracle, make openjdk default, add `java_ark` LWRP.
* [COOK-942] - FreeBSD support
* [COOK-520] - ArchLinux support

View file

@ -0,0 +1,257 @@
# Contributing to Opscode Cookbooks
We are glad you want to contribute to Opscode Cookbooks! The first
step is the desire to improve the project.
You can find the answers to additional frequently asked questions
[on the wiki](http://wiki.opscode.com/display/chef/How+to+Contribute).
You can find additional information about
[contributing to cookbooks](http://wiki.opscode.com/display/chef/How+to+Contribute+to+Opscode+Cookbooks)
on the wiki as well.
## Quick-contribute
* Create an account on our [bug tracker](http://tickets.opscode.com)
* Sign our contributor agreement (CLA)
[ online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L)
(keep reading if you're contributing on behalf of your employer)
* Create a ticket for your change on the
[bug tracker](http://tickets.opscode.com)
* Link to your patch as a rebased git branch or pull request from the
ticket
* Resolve the ticket as fixed
We regularly review contributions and will get back to you if we have
any suggestions or concerns.
## The Apache License and the CLA/CCLA
Licensing is very important to open source projects, it helps ensure
the software continues to be available under the terms that the author
desired. Chef uses the Apache 2.0 license to strike a balance between
open contribution and allowing you to use the software however you
would like to.
The license tells you what rights you have that are provided by the
copyright holder. It is important that the contributor fully
understands what rights they are licensing and agrees to them.
Sometimes the copyright holder isn't the contributor, most often when
the contributor is doing work for a company.
To make a good faith effort to ensure these criteria are met, Opscode
requires a Contributor License Agreement (CLA) or a Corporate
Contributor License Agreement (CCLA) for all contributions. This is
without exception due to some matters not being related to copyright
and to avoid having to continually check with our lawyers about small
patches.
It only takes a few minutes to complete a CLA, and you retain the
copyright to your contribution.
You can complete our contributor agreement (CLA)
[ online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L).
If you're contributing on behalf of your employer, have your employer
fill out our
[Corporate CLA](https://secure.echosign.com/public/hostedForm?formid=PIE6C7AX856)
instead.
## Ticket Tracker (JIRA)
The [ticket tracker](http://tickets.opscode.com) is the most important
documentation for the code base. It provides significant historical
information, such as:
* Which release a bug fix is included in
* Discussion regarding the design and merits of features
* Error output to aid in finding similar bugs
Each ticket should aim to fix one bug or add one feature.
## Using git
You can get a quick copy of the repository for this cookbook by
running `git clone
git://github.com/opscode-coobkooks/COOKBOOKNAME.git`.
For collaboration purposes, it is best if you create a Github account
and fork the repository to your own account. Once you do this you will
be able to push your changes to your Github repository for others to
see and use.
If you have another repository in your GitHub account named the same
as the cookbook, we suggest you suffix the repository with -cookbook.
### Branches and Commits
You should submit your patch as a git branch named after the ticket,
such as COOK-1337. This is called a _topic branch_ and allows users to
associate a branch of code with the ticket.
It is a best practice to have your commit message have a _summary
line_ that includes the ticket number, followed by an empty line and
then a brief description of the commit. This also helps other
contributors understand the purpose of changes to the code.
[COOK-1757] - platform_family and style
* use platform_family for platform checking
* update notifies syntax to "resource_type[resource_name]" instead of
resources() lookup
* COOK-692 - delete config files dropped off by packages in conf.d
* dropped debian 4 support because all other platforms have the same
values, and it is older than "old stable" debian release
Remember that not all users use Chef in the same way or on the same
operating systems as you, so it is helpful to be clear about your use
case and change so they can understand it even when it doesn't apply
to them.
### Github and Pull Requests
All of Opscode's open source cookbook projects are available on
[Github](http://www.github.com/opscode-cookbooks).
We don't require you to use Github, and we will even take patch diffs
attached to tickets on the tracker. However Github has a lot of
convenient features, such as being able to see a diff of changes
between a pull request and the main repository quickly without
downloading the branch.
If you do choose to use a pull request, please provide a link to the
pull request from the ticket __and__ a link to the ticket from the
pull request. Because pull requests only have two states, open and
closed, we can't easily filter pull requests that are waiting for a
reply from the author for various reasons.
### More information
Additional help with git is available on the
[Working with Git](http://wiki.opscode.com/display/chef/Working+with+Git)
wiki page.
## Functional and Unit Tests
This cookbook is set up to run tests under
[Opscode's test-kitchen](https://github.com/opscode/test-kitchen). It
uses minitest-chef to run integration tests after the node has been
converged to verify that the state of the node.
Test kitchen should run completely without exception using the default
[baseboxes provided by Opscode](https://github.com/opscode/bento).
Because Test Kitchen creates VirtualBox machines and runs through
every configuration in the Kitchenfile, it may take some time for
these tests to complete.
If your changes are only for a specific recipe, run only its
configuration with Test Kitchen. If you are adding a new recipe, or
other functionality such as a LWRP or definition, please add
appropriate tests and ensure they run with Test Kitchen.
If any don't pass, investigate them before submitting your patch.
Any new feature should have unit tests included with the patch with
good code coverage to help protect it from future changes. Similarly,
patches that fix a bug or regression should have a _regression test_.
Simply put, this is a test that would fail without your patch but
passes with it. The goal is to ensure this bug doesn't regress in the
future. Consider a regular expression that doesn't match a certain
pattern that it should, so you provide a patch and a test to ensure
that the part of the code that uses this regular expression works as
expected. Later another contributor may modify this regular expression
in a way that breaks your use cases. The test you wrote will fail,
signalling to them to research your ticket and use case and accounting
for it.
If you need help writing tests, please ask on the Chef Developer's
mailing list, or the #chef-hacking IRC channel.
## Code Review
Opscode regularly reviews code contributions and provides suggestions
for improvement in the code itself or the implementation.
We find contributions by searching the ticket tracker for _resolved_
tickets with a status of _fixed_. If we have feedback we will reopen
the ticket and you should resolve it again when you've made the
changes or have a response to our feedback. When we believe the patch
is ready to be merged, we will tag the _Code Reviewed_ field with
_Reviewed_.
Depending on the project, these tickets are then merged within a week
or two, depending on the current release cycle.
## Release Cycle
The versioning for Opscode Cookbook projects is X.Y.Z.
* X is a major release, which may not be fully compatible with prior
major releases
* Y is a minor release, which adds both new features and bug fixes
* Z is a patch release, which adds just bug fixes
A released version of a cookbook will end in an even number, e.g.
"1.2.4" or "0.8.0". When development for the next version of the
cookbook begins, the "Z" patch number is incremented to the next odd
number, however the next release of the cookbook may be a major or
minor incrementing version.
Releases of Opscode's cookbooks are usually announced on the Chef user
mailing list. Releases of several cookbooks may be batched together
and announced on the [Opscode Blog](http://www.opscode.com/blog).
## Working with the community
These resources will help you learn more about Chef and connect to
other members of the Chef community:
* [chef](http://lists.opscode.com/sympa/info/chef) and
[chef-dev](http://lists.opscode.com/sympa/info/chef-dev) mailing
lists
* #chef and #chef-hacking IRC channels on irc.freenode.net
* [Community Cookbook site](http://community.opscode.com)
* [Chef wiki](http://wiki.opscode.com/display/chef)
* Opscode Chef [product page](http://www.opscode.com/chef)
## Cookbook Contribution Do's and Don't's
Please do include tests for your contribution. If you need help, ask
on the
[chef-dev mailing list](http://lists.opscode.com/sympa/info/chef-dev)
or the
[#chef-hacking IRC channel](http://community.opscode.com/chat/chef-hacking).
Not all platforms that a cookbook supports may be supported by Test
Kitchen. Please provide evidence of testing your contribution if it
isn't trivial so we don't have to duplicate effort in testing. Chef
10.14+ "doc" formatted output is sufficient.
Please do indicate new platform (families) or platform versions in the
commit message, and update the relevant ticket.
If a contribution adds new platforms or platform versions, indicate
such in the body of the commit message(s), and update the relevant
COOK ticket. When writing commit messages, it is helpful for others if
you indicate the COOK ticket. For example:
git commit -m '[COOK-1041] - Updated pool resource to correctly
delete.'
Please do use [foodcritic](http://acrmp.github.com/foodcritic) to
lint-check the cookbook. Except FC007, it should pass all correctness
rules. FC007 is okay as long as the dependent cookbooks are *required*
for the default behavior of the cookbook, such as to support an
uncommon platform, secondary recipe, etc.
Please do ensure that your changes do not break or modify behavior for
other platforms supported by the cookbook. For example if your changes
are for Debian, make sure that they do not break on CentOS.
Please do not modify the version number in the metadata.rb, Opscode
will select the appropriate version based on the release cycle
information above.
Please do not update the CHANGELOG.md for a new version. Not all
changes to a cookbook may be merged and released in the same versions.
Opscode will update the CHANGELOG.md when releasing a new version of
the cookbook.

View file

@ -0,0 +1,3 @@
source :rubygems
gem 'test-kitchen', '< 1.0'

201
chef/cookbooks/java/LICENSE Normal file
View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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,213 @@
Description
===========
Installs a Java. Uses OpenJDK by default but supports installation of Oracle's JDK.
This cookbook contains the `java_ark` LWPR which has been deprecated
in favor of [ark](https://github.com/opscode-cookbooks/ark).
**IMPORTANT NOTE**
As of 26 March 2012 you can no longer directly download
the JDK from Oracle's website without using a special cookie. This cookbook uses
that cookie to download the oracle recipe on your behalf, but . . .
the java::oracle recipe forces you to set either override
the `node['java']['oracle']['accept_oracle_download_terms']` to true or set up a
private repository accessible by HTTP.
Example
### override the `accept_oracle_download_terms`
roles/base.rb
This cookbook also provides the `java_ark` LWRP which other java
cookbooks can use to install java-related applications from binary
packages.
default_attributes(
:java => {
:oracle => {
"accept_oracle_download_terms" => true
}
}
)
You are most encouraged to voice your complaints to Oracle and/or
switch to OpenJDK.
Requirements
============
Platform
--------
* Debian, Ubuntu
* CentOS, Red Hat, Fedora, Scientific, Amazon
* ArchLinux
* FreeBSD
* Windows
Attributes
==========
See `attributes/default.rb` for default values.
* `node["java"]["install_flavor"]` - Flavor of JVM you would like installed (`oracle` or
`openjdk`), default `openjdk`.
* `node['java']['java_home']` - Default location of the "`$JAVA_HOME`".
* `node['java']['tarball']` - Name of the tarball to retrieve from your corporate
repository default `jdk1.6.0_29_i386.tar.gz`
* `node['java']['tarball_checksum']` - Checksum for the tarball, if you use a different
tarball, you also need to create a new sha256 checksum
* `node['java']['jdk']` - Version and architecture specific attributes for setting the
URL on Oracle's site for the JDK, and the checksum of the .tar.gz.
* `node['java']['remove_deprecated_packages']` - Removes the now deprecated Ubuntu JDK
packages from the system, default `false`
* `node['java']['oracle']['accept_oracle_download_terms']` - Indicates that you accept
Oracle's EULA
* `node['java']['windows']['url']` - The internal location of your java install for windows
* `node['java']['windows']['package_name']` - The package name used by windows_package to
check in the registry to determine if the install has already been run
Recipes
=======
default
-------
Include the default recipe in a run list, to get `java`. By default
the `openjdk` flavor of Java is installed, but this can be changed by
using the `install_flavor` attribute. If the platform is windows it
will include the windows recipe instead.
OpenJDK is the default because of licensing changes made upstream by
Oracle. See notes on the `oracle` recipe below.
openjdk
-------
This recipe installs the `openjdk` flavor of Java.
oracle
------
This recipe installs the `oracle` flavor of Java. This recipe does not
use distribution packages as Oracle changed the licensing terms with
JDK 1.6u27 and prohibited the practice for both the debian and EL worlds.
For both debian and centos/rhel, this recipe pulls the binary
distribution from the Oracle website, and installs it in the default
JAVA_HOME for each distribution. For debian/ubuntu, this is
/usr/lib/jvm/default-java. For Centos/RHEL, this is /usr/lib/jvm/java
After putting the binaries in place, the oracle recipe updates
/usr/bin/java to point to the installed JDK using the
`update-alternatives` script
oracle_i386
-----------
This recipe installs the 32-bit Java virtual machine without setting
it as the default. This can be useful if you have applications on the
same machine that require different versions of the JVM.
windows
-------
Because there is no easy way to pull the java msi off oracle's site,
this recipe requires you to host it internally on your own http repo.
Resources/Providers
===================
This cookbook contains the `java_ark` LWPR which has been deprecated
in favor of [ark](https://github.com/opscode-cookbooks/ark).
By default, the extracted directory is extracted to
`app_root/extracted_dir_name` and symlinked to `app_root/default`
# Actions
- `:install`: extracts the tarball and makes necessary symlinks
- `:remove`: removes the tarball and run update-alternatives for all
symlinked `bin_cmds`
# Attribute Parameters
- `url`: path to tarball, .tar.gz, .bin (oracle-specific), and .zip
currently supported
- `checksum`: sha256 checksum, not used for security but avoid
redownloading the archive on each chef-client run
- `app_home`: the default for installations of this type of
application, for example, `/usr/lib/tomcat/default`. If your
application is not set to the default, it will be placed at the same
level in the directory hierarchy but the directory name will be
`app_root/extracted_directory_name + "_alt"`
- `app_home_mode`: file mode for app_home, is an integer
- `bin_cmds`: array of binary commands that should be symlinked to
/usr/bin, examples are mvn, java, javac, etc. These cmds must be in
the bin/ subdirectory of the extracted folder. Will be ignored if this
java_ark is not the default
- `owner`: owner of extracted directory, set to "root" by default
- `default`: whether this the default installation of this package,
boolean true or false
# Examples
# install jdk6 from Oracle
java_ark "jdk" do
url 'http://download.oracle.com/otn-pub/java/jdk/6u29-b11/jdk-6u29-linux-x64.bin'
checksum 'a8603fa62045ce2164b26f7c04859cd548ffe0e33bfc979d9fa73df42e3b3365'
app_home '/usr/local/java/default'
bin_cmds ["java", "javac"]
action :install
end
Usage
=====
Simply include the `java` recipe where ever you would like Java installed.
To install Oracle flavored Java on Debian or Ubuntu override the `node['java']['install_flavor']` attribute with in role:
name "java"
description "Install Oracle Java on Ubuntu"
override_attributes(
"java" => {
"install_flavor" => "oracle"
}
)
run_list(
"recipe[java]"
)
Development
===========
This cookbook uses
[test-kitchen](https://github.com/opscode/test-kitchen) for
integration tests. Pull requests should pass existing tests in
files/default/tests/minitest-handler. Additional tests are always welcome.
License and Author
==================
Author:: Seth Chisamore (<schisamo@opscode.com>)
Author:: Bryan W. Berry (<bryan.berry@gmail.com>)
Copyright:: 2008-2012, Opscode, 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,77 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: java
# Attributes:: default
#
# Copyright 2010, Opscode, 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.
# remove the deprecated Ubuntu jdk packages
default['java']['remove_deprecated_packages'] = false
# default jdk attributes
default['java']['install_flavor'] = "openjdk"
default['java']['jdk_version'] = '6'
default['java']['arch'] = kernel['machine'] =~ /x86_64/ ? "x86_64" : "i586"
case platform
when "centos","redhat","fedora","scientific","amazon","oracle"
default['java']['java_home'] = "/usr/lib/jvm/java"
when "freebsd"
default['java']['java_home'] = "/usr/local/openjdk#{java['jdk_version']}"
when "arch"
default['java']['java_home'] = "/usr/lib/jvm/java-#{java['jdk_version']}-openjdk"
when "windows"
default['java']['install_flavor'] = "windows"
default['java']['windows']['url'] = nil
default['java']['windows']['package_name'] = "Java(TM) SE Development Kit 7 (64-bit)"
else
default['java']['java_home'] = "/usr/lib/jvm/default-java"
end
# if you change this to true, you can download directly from Oracle
default['java']['oracle']['accept_oracle_download_terms'] = false
# direct download paths for oracle, you have been warned!
# jdk6 attributes
default['java']['jdk']['6']['bin_cmds'] = [ "appletviewer", "apt", "ControlPanel", "extcheck", "HtmlConverter", "idlj", "jar", "jarsigner",
"java", "javac", "javadoc", "javah", "javap", "javaws", "jconsole", "jcontrol", "jdb", "jhat",
"jinfo", "jmap", "jps", "jrunscript", "jsadebugd", "jstack", "jstat", "jstatd", "jvisualvm",
"keytool", "native2ascii", "orbd", "pack200", "policytool", "rmic", "rmid", "rmiregistry",
"schemagen", "serialver", "servertool", "tnameserv", "unpack200", "wsgen", "wsimport", "xjc" ]
# x86_64
default['java']['jdk']['6']['x86_64']['url'] = 'http://download.oracle.com/otn-pub/java/jdk/6u43-b01/jdk-6u43-linux-x64.bin'
default['java']['jdk']['6']['x86_64']['checksum'] = '653c35ec6c64c3b127dea0afed1f16ba2b32efcaeae86fc02777b70e3e166aee'
# i586
default['java']['jdk']['6']['i586']['url'] = 'http://download.oracle.com/otn-pub/java/jdk/6u43-b01/jdk-6u43-linux-i586.bin'
default['java']['jdk']['6']['i586']['checksum'] = '616df04eddac146b1c67de00ae07bb2d1179f470f35f9e661e1f5075423cf4e1'
# jdk7 attributes
default['java']['jdk']['7']['bin_cmds'] = [ "appletviewer", "apt", "ControlPanel", "extcheck", "idlj", "jar", "jarsigner", "java", "javac",
"javadoc", "javafxpackager", "javah", "javap", "javaws", "jcmd", "jconsole", "jcontrol", "jdb",
"jhat", "jinfo", "jmap", "jps", "jrunscript", "jsadebugd", "jstack", "jstat", "jstatd", "jvisualvm",
"keytool", "native2ascii", "orbd", "pack200", "policytool", "rmic", "rmid", "rmiregistry",
"schemagen", "serialver", "servertool", "tnameserv", "unpack200", "wsgen", "wsimport", "xjc" ]
# x86_64
default['java']['jdk']['7']['x86_64']['url'] = 'http://download.oracle.com/otn-pub/java/jdk/7u17-b02/jdk-7u17-linux-x64.tar.gz'
default['java']['jdk']['7']['x86_64']['checksum'] = '8611ce31e0b7ecb99d34703ad89b29a545a3fb30356553be3674366cbe722782'
# i586
default['java']['jdk']['7']['i586']['url'] = 'http://download.oracle.com/otn-pub/java/jdk/7u17-b02/jdk-7u17-linux-i586.tar.gz'
default['java']['jdk']['7']['i586']['checksum'] = '4046e941e05717538dd4deb1b1f55cb8bb6bd38793c7317034d1f5019086d956'

View file

@ -0,0 +1,25 @@
require 'minitest/spec'
require 'open3'
describe_recipe 'java::openjdk' do
include MiniTest::Chef::Assertions
include MiniTest::Chef::Context
include MiniTest::Chef::Resources
it "installs the correct version of the jdk" do
stdin,stdout,stderr = Open3.popen3( "java -version" )
version_line = stderr.readline
jdk_version = version_line.scan(/\.([678])\./)[0][0]
assert_equal node['java']['jdk_version'], jdk_version
end
it "properly sets JAVA_HOME environment variable" do
stdin,stdout,stderr = Open3.popen3( "echo $JAVA_HOME" )
java_home = stdout.readline.rstrip
assert_equal node['java']['java_home'], java_home
end
end

View file

@ -0,0 +1,24 @@
require 'minitest/spec'
require 'open3'
describe_recipe 'java::oracle' do
include MiniTest::Chef::Assertions
include MiniTest::Chef::Context
include MiniTest::Chef::Resources
it "installs the correct version of the jdk" do
stdin,stdout,stderr = Open3.popen3( "java -version" )
version_line = stderr.readline
jdk_version = version_line.scan(/\.([678])\./)[0][0]
assert_equal node['java']['jdk_version'], jdk_version
end
it "properly sets JAVA_HOME environment variable" do
stdin,stdout,stderr = Open3.popen3( "echo $JAVA_HOME" )
java_home = stdout.readline.rstrip
assert_equal node['java']['java_home'], java_home
end
end

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,19 @@
name "java"
maintainer "Opscode, Inc."
maintainer_email "cookbooks@opscode.com"
license "Apache 2.0"
description "Installs Java runtime."
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version "1.10.0"
recipe "java", "Installs Java runtime"
recipe "java::openjdk", "Installs the OpenJDK flavor of Java"
recipe "java::oracle", "Installs the Oracle flavor of Java"
recipe "java::oracle_i386", "Installs the 32-bit jvm without setting it as the default"
%w{ debian ubuntu centos redhat scientific fedora amazon arch oracle freebsd windows }.each do |os|
supports os
end
depends "windows"

View file

@ -0,0 +1,264 @@
#
# Author:: Bryan W. Berry (<bryan.berry@gmail.com>)
# Cookbook Name:: java
# Provider:: ark
#
# Copyright 2011, Bryan w. Berry
#
# 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.
def whyrun_supported?
true
end
def parse_app_dir_name url
file_name = url.split('/')[-1]
# funky logic to parse oracle's non-standard naming convention
# for jdk1.6
if file_name =~ /^(jre|jdk).*$/
major_num = file_name.scan(/\d/)[0]
update_num = file_name.scan(/\d+/)[1]
# pad a single digit number with a zero
if update_num.length < 2
update_num = "0" + update_num
end
package_name = file_name.scan(/[a-z]+/)[0]
app_dir_name = "#{package_name}1.#{major_num}.0_#{update_num}"
else
app_dir_name = file_name.split(/(.tgz|.tar.gz|.zip)/)[0]
app_dir_name = app_dir_name.split("-bin")[0]
end
[app_dir_name, file_name]
end
def oracle_downloaded?(download_path, new_resource)
if ::File.exists? download_path
require 'digest'
downloaded_sha = Digest::SHA256.file(download_path).hexdigest
downloaded_sha == new_resource.checksum
else
return false
end
end
def download_direct_from_oracle(tarball_name, new_resource)
download_path = "#{Chef::Config[:file_cache_path]}/#{tarball_name}"
jdk_id = new_resource.url.scan(/\/([6789]u[0-9][0-9]?-b[0-9][0-9])\//)[0][0]
cookie = "oraclelicensejdk-#{jdk_id}-oth-JPR=accept-securebackup-cookie;gpw_e24=http://edelivery.oracle.com"
if node['java']['oracle']['accept_oracle_download_terms']
# install the curl package
p = package "curl" do
action :nothing
end
# no converge_by block since the package provider will take care of this run_action
p.run_action(:install)
description = "download oracle tarball straight from the server"
converge_by(description) do
Chef::Log.debug "downloading oracle tarball straight from the source"
cmd = Chef::ShellOut.new(
%Q[ curl -L --cookie "#{cookie}" #{new_resource.url} -o #{download_path} ]
)
cmd.run_command
cmd.error!
end
else
Chef::Application.fatal!("You must set the attribute node['java']['oracle']['accept_oracle_download_terms'] to true if you want to download directly from the oracle site!")
end
end
action :install do
app_dir_name, tarball_name = parse_app_dir_name(new_resource.url)
app_root = new_resource.app_home.split('/')[0..-2].join('/')
app_dir = app_root + '/' + app_dir_name
unless new_resource.default
Chef::Log.debug("processing alternate jdk")
app_dir = app_dir + "_alt"
app_home = new_resource.app_home + "_alt"
else
app_home = new_resource.app_home
end
unless ::File.exists?(app_dir)
Chef::Log.info "Adding #{new_resource.name} to #{app_dir}"
require 'fileutils'
unless ::File.exists?(app_root)
description = "create dir #{app_root} and change owner to #{new_resource.owner}"
converge_by(description) do
FileUtils.mkdir app_root, :mode => new_resource.app_home_mode
FileUtils.chown new_resource.owner, new_resource.owner, app_root
end
end
if new_resource.url =~ /^http:\/\/download.oracle.com.*$/
download_path = "#{Chef::Config[:file_cache_path]}/#{tarball_name}"
if oracle_downloaded?(download_path, new_resource)
Chef::Log.debug("oracle tarball already downloaded, not downloading again")
else
download_direct_from_oracle tarball_name, new_resource
end
else
Chef::Log.debug("downloading tarball from an unofficial repository")
r = remote_file "#{Chef::Config[:file_cache_path]}/#{tarball_name}" do
source new_resource.url
checksum new_resource.checksum
mode 0755
action :nothing
end
#no converge by on run_action remote_file takes care of it.
r.run_action(:create_if_missing)
end
require 'tmpdir'
description = "create tmpdir, extract compressed data into tmpdir,
move extracted data to #{app_dir} and delete tmpdir"
converge_by(description) do
tmpdir = Dir.mktmpdir
case tarball_name
when /^.*\.bin/
cmd = Chef::ShellOut.new(
%Q[ cd "#{tmpdir}";
cp "#{Chef::Config[:file_cache_path]}/#{tarball_name}" . ;
bash ./#{tarball_name} -noregister
] ).run_command
unless cmd.exitstatus == 0
Chef::Application.fatal!("Failed to extract file #{tarball_name}!")
end
when /^.*\.zip/
cmd = Chef::ShellOut.new(
%Q[ unzip "#{Chef::Config[:file_cache_path]}/#{tarball_name}" -d "#{tmpdir}" ]
).run_command
unless cmd.exitstatus == 0
Chef::Application.fatal!("Failed to extract file #{tarball_name}!")
end
when /^.*\.(tar.gz|tgz)/
cmd = Chef::ShellOut.new(
%Q[ tar xvzf "#{Chef::Config[:file_cache_path]}/#{tarball_name}" -C "#{tmpdir}" ]
).run_command
unless cmd.exitstatus == 0
Chef::Application.fatal!("Failed to extract file #{tarball_name}!")
end
end
cmd = Chef::ShellOut.new(
%Q[ mv "#{tmpdir}/#{app_dir_name}" "#{app_dir}" ]
).run_command
unless cmd.exitstatus == 0
Chef::Application.fatal!(%Q[ Command \' mv "#{tmpdir}/#{app_dir_name}" "#{app_dir}" \' failed ])
end
FileUtils.rm_r tmpdir
end
new_resource.updated_by_last_action(true)
end
#set up .jinfo file for update-java-alternatives
java_name = app_home.split('/')[-1]
jinfo_file = "#{app_root}/.#{java_name}.jinfo"
if platform_family?("debian") && !::File.exists?(jinfo_file)
description = "Add #{jinfo_file} for debian"
converge_by(description) do
Chef::Log.debug "Adding #{jinfo_file} for debian"
template jinfo_file do
source "oracle.jinfo.erb"
variables(
:priority => new_resource.alternatives_priority,
:bin_cmds => new_resource.bin_cmds,
:name => java_name,
:app_dir => app_home
)
action :create
end
end
new_resource.updated_by_last_action(true)
end
#link app_home to app_dir
Chef::Log.debug "app_home is #{app_home} and app_dir is #{app_dir}"
current_link = ::File.symlink?(app_home) ? ::File.readlink(app_home) : nil
if current_link != app_dir
description = "Symlink #{app_dir} to #{app_home}"
converge_by(description) do
Chef::Log.debug "Symlinking #{app_dir} to #{app_home}"
FileUtils.rm_f app_home
FileUtils.ln_sf app_dir, app_home
end
end
#update-alternatives
if new_resource.bin_cmds
new_resource.bin_cmds.each do |cmd|
bin_path = "/usr/bin/#{cmd}"
alt_path = "#{app_home}/bin/#{cmd}"
priority = new_resource.alternatives_priority
# install the alternative if needed
alternative_exists = Chef::ShellOut.new("update-alternatives --display #{cmd} | grep #{alt_path}").run_command.exitstatus == 0
unless alternative_exists
description = "Add alternative for #{cmd}"
converge_by(description) do
Chef::Log.debug "Adding alternative for #{cmd}"
install_cmd = Chef::ShellOut.new("update-alternatives --install #{bin_path} #{cmd} #{alt_path} #{priority}").run_command
unless install_cmd.exitstatus == 0
Chef::Application.fatal!(%Q[ set alternative failed ])
end
end
new_resource.updated_by_last_action(true)
end
# set the alternative if default
if new_resource.default
alternative_is_set = Chef::ShellOut.new("update-alternatives --display #{cmd} | grep \"link currently points to #{alt_path}\"").run_command.exitstatus == 0
unless alternative_is_set
description = "Set alternative for #{cmd}"
converge_by(description) do
Chef::Log.debug "Setting alternative for #{cmd}"
set_cmd = Chef::ShellOut.new("update-alternatives --set #{cmd} #{alt_path}").run_command
unless set_cmd.exitstatus == 0
Chef::Application.fatal!(%Q[ set alternative failed ])
end
end
new_resource.updated_by_last_action(true)
end
end
end
end
end
action :remove do
app_dir_name, tarball_name = parse_app_dir_name(new_resource.url)
app_root = new_resource.app_home.split('/')[0..-2].join('/')
app_dir = app_root + '/' + app_dir_name
if ::File.exists?(app_dir)
new_resource.bin_cmds.each do |cmd|
cmd = execute "update_alternatives" do
command "update-alternatives --remove #{cmd} #{app_dir} "
returns [0,2]
action :nothing
end
# the execute resource will take care of of the run_action(:run)
cmd.run_action(:run)
end
description = "remove #{new_resource.name} at #{app_dir}"
converge_by(description) do
Chef::Log.info "Removing #{new_resource.name} at #{app_dir}"
FileUtils.rm_rf app_dir
end
new_resource.updated_by_last_action(true)
end
end

View file

@ -0,0 +1,33 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: java
# Recipe:: default
#
# Copyright 2008-2011, Opscode, 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.
#
if node['platform_family'] == "windows"
include_recipe "java::windows"
else
include_recipe "java::#{node['java']['install_flavor']}"
end
# Purge the deprecated Sun Java packages if remove_deprecated_packages is true
%w[sun-java6-jdk sun-java6-bin sun-java6-jre].each do |pkg|
package pkg do
action :purge
only_if { node['java']['remove_deprecated_packages'] }
end
end

View file

@ -0,0 +1,97 @@
# Author:: Bryan W. Berry (<bryan.berry@gmail.com>)
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: java
# Recipe:: openjdk
#
# Copyright 2010-2011, Opscode, 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.
jdk_version = node['java']['jdk_version'].to_i
java_home = node['java']['java_home']
java_home_parent = ::File.dirname java_home
jdk_home = ""
pkgs = value_for_platform(
["centos","redhat","fedora","scientific","amazon","oracle"] => {
"default" => ["java-1.#{jdk_version}.0-openjdk","java-1.#{jdk_version}.0-openjdk-devel"]
},
["debian","ubuntu"] => {
"default" => ["openjdk-#{jdk_version}-jdk","default-jre-headless"]
},
["arch","freebsd"] => {
"default" => ["openjdk#{jdk_version}"]
},
"default" => ["openjdk-#{jdk_version}-jdk"]
)
# done by special request for rberger
ruby_block "set-env-java-home" do
block do
ENV["JAVA_HOME"] = java_home
end
not_if { ENV["JAVA_HOME"] == java_home }
end
file "/etc/profile.d/jdk.sh" do
content <<-EOS
export JAVA_HOME=#{node['java']['java_home']}
EOS
mode 0755
end
if platform?("ubuntu","debian","redhat","centos","fedora","scientific","amazon","oracle")
ruby_block "update-java-alternatives" do
block do
arch = node['kernel']['machine'] =~ /x86_64/ ? "x86_64" : "i386"
arch = 'amd64' if arch == 'x86_64' && platform?("ubuntu") && node["platform_version"].to_f >= 12.04
if platform?("ubuntu", "debian") and jdk_version == 6
java_name = if node["platform_version"].to_f >= 11.10
"java-1.6.0-openjdk"
else
"java-6-openjdk"
end
java_name += "-i386" if arch == "i386" && node['platform_version'].to_f >= 12.04
Chef::ShellOut.new("update-java-alternatives","-s", java_name, :returns => [0,2]).run_command
else
# have to do this on ubuntu for version 7 because Ubuntu does
# not currently set jdk 7 as the default jvm on installation
require "fileutils"
Chef::Log.debug("glob is #{java_home_parent}/java*#{jdk_version}*openjdk*#{arch}")
jdk_home = Dir.glob("#{java_home_parent}/java*#{jdk_version}*openjdk*#{arch}").first
Chef::Log.debug("jdk_home is #{jdk_home}")
if jdk_home
FileUtils.rm_f java_home if ::File.exists? java_home
FileUtils.ln_sf jdk_home, java_home
end
cmd = Chef::ShellOut.new(
%Q[ update-alternatives --install /usr/bin/java java #{java_home}/bin/java 1;
update-alternatives --set java #{java_home}/bin/java ]
).run_command
unless cmd.exitstatus == 0 or cmd.exitstatus == 2
Chef::Application.fatal!("Failed to update-alternatives for openjdk!")
end
end
end
action :nothing
end
end
pkgs.each do |pkg|
package pkg do
action :install
notifies :create, "ruby_block[update-java-alternatives]", :immediately if platform?("ubuntu","debian","redhat","centos","fedora","scientific","amazon","oracle")
end
end

View file

@ -0,0 +1,68 @@
#
# Author:: Bryan W. Berry (<bryan.berry@gmail.com>)
# Cookbook Name:: java
# Recipe:: oracle
#
# Copyright 2011, Bryan w. Berry
#
# 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.
java_home = node['java']["java_home"]
arch = node['java']['arch']
jdk_version = node['java']['jdk_version']
#convert version number to a string if it isn't already
if jdk_version.instance_of? Fixnum
jdk_version = jdk_version.to_s
end
case jdk_version
when "6"
tarball_url = node['java']['jdk']['6'][arch]['url']
tarball_checksum = node['java']['jdk']['6'][arch]['checksum']
bin_cmds = node['java']['jdk']['6']['bin_cmds']
when "7"
tarball_url = node['java']['jdk']['7'][arch]['url']
tarball_checksum = node['java']['jdk']['7'][arch]['checksum']
bin_cmds = node['java']['jdk']['7']['bin_cmds']
end
if tarball_url =~ /example.com/
Chef::Application.fatal!("You must change the download link to your private repository. You can no longer download java directly from http://download.oracle.com without a web broswer")
end
ruby_block "set-env-java-home" do
block do
ENV["JAVA_HOME"] = java_home
end
not_if { ENV["JAVA_HOME"] == java_home }
end
file "/etc/profile.d/jdk.sh" do
content <<-EOS
export JAVA_HOME=#{node['java']['java_home']}
EOS
mode 0755
end
java_ark "jdk" do
url tarball_url
checksum tarball_checksum
app_home java_home
bin_cmds bin_cmds
alternatives_priority 1062
action :install
end

View file

@ -0,0 +1,52 @@
#
# Author:: Bryan W. Berry (<bryan.berry@gmail.com>)
# Cookbook Name:: java
# Recipe:: oracle_i386
#
# Copyright 2010-2011, Opscode, 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.
java_home = node['java']["java_home"]
case node['java']['jdk_version']
when "6"
tarball_url = node['java']['jdk']['6']['i586']['url']
tarball_checksum = node['java']['jdk']['6']['i586']['checksum']
bin_cmds = node['java']['jdk']['6']['bin_cmds']
when "7"
tarball_url = node['java']['jdk']['7']['i586']['url']
tarball_checksum = node['java']['jdk']['7']['i586']['checksum']
bin_cmds = node['java']['jdk']['7']['bin_cmds']
end
ruby_block "set-env-java-home" do
block do
ENV["JAVA_HOME"] = java_home
end
not_if { ENV["JAVA_HOME"] == java_home }
end
yum_package "glibc" do
arch "i686"
only_if { platform_family?( "rhel", "fedora" ) }
end
java_ark "jdk-alt" do
url tarball_url
checksum tarball_checksum
app_home java_home
bin_cmds bin_cmds
action :install
default false
end

View file

@ -0,0 +1,28 @@
#
# Author:: Kendrick Martin (<kendrick.martin@webtrends.com>)
# Cookbook Name:: java
# Recipe:: windows
#
# Copyright 2008-2012 Webtrends, 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.
#
Chef::Log.warn("No download url set for java installer.") unless node['java']['windows']['url']
windows_package node['java']['windows']['package_name'] do
source node['java']['windows']['url']
action :install
installer_type :custom
options "/s"
end

View file

@ -0,0 +1,38 @@
#
# Author:: Bryan W. Berry (<bryan.berry@gmail.com>)
# Cookbook Name:: java
# Resource:: ark
#
# Copyright 2011, Bryan w. Berry
#
# 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.
actions :install, :remove
attribute :url, :regex => /^https?:\/\/.*(tar.gz|tgz|bin|zip)$/, :default => nil
attribute :mirrorlist, :kind_of => Array, :default => nil
attribute :checksum, :regex => /^[a-zA-Z0-9]{64}$/, :default => nil
attribute :app_home, :kind_of => String, :default => nil
attribute :app_home_mode, :kind_of => Integer, :default => 0755
attribute :bin_cmds, :kind_of => Array, :default => nil
attribute :owner, :default => "root"
attribute :default, :equal_to => [true, false], :default => true
attribute :alternatives_priority, :kind_of => Integer, :default => 1
# we have to set default for the supports attribute
# in initializer since it is a 'reserved' attribute name
def initialize(*args)
super
@action = :install
@supports = {:report => true, :exception => true}
end

View file

@ -0,0 +1,6 @@
name=<%= @name %>
priority=<%= @priority %>
section=main
<% @bin_cmds.each do |cmd| -%>jdk <%= cmd %> <%= @app_dir %>/bin/<%= cmd %>
<% end -%>

View file

@ -0,0 +1,161 @@
## Future
* package preseeding/response_file support
* package installation location via a `target_dir` attribute.
* [COOK-666] `windows_package` should support CoApp packages
* windows_registry :force_modify action should use RegNotifyChangeKeyValue from WinAPI
* WindowsRebootHandler/`windows_reboot` LWRP should support kicking off subsequent chef run on reboot.
## v1.8.4:
* [COOK-2336] - MSI That requires reboot returns with RC 3010 and
causes chef run failure
* [COOK-2368] - `version` attribute of the `windows_package` provider
should be documented
## v1.8.2:
**Important**: Use powershell in nodes expanded run lists to ensure
powershell is downloaded, as powershell has a dependency on this
cookbook; v1.8.0 created a circular dependency.
* [COOK-2301] - windows 1.8.0 has circular dependency on powershell
## v1.8.0:
* [COOK-2126] - Add checksum attribute to windows_zipfile
* [COOK-2142] - Add printer and printer_port LWRPs
* [COOK-2149] - Chef::Log.debug Windows Package command line
* [COOK-2155] -`windows_package` does not send checksum to
`cached_file` in `installer_type`
## v1.7.0:
* [COOK-1745] - allow for newer versions of rubyzip
## v1.6.0:
* [COOK-2048] - undefined method for Falseclass on task :change when
action is :nothing (and task doesn't exist)
* [COOK-2049] - Add `windows_pagefile` resource
## v1.5.0:
* [COOK-1251] - Fix LWRP "NotImplementedError"
* [COOK-1921] - Task LWRP will return true for resource exists when no
other scheduled tasks exist
* [COOK-1932] - Include :change functionality to windows task lwrp
## v1.4.0:
* [COOK-1571] - windows_package resource (with msi provider) does not
accept spaces in filename
* [COOK-1581] - Windows cookbook needs a scheduled tasks LWRP
* [COOK-1584] - `windows_registry` should support all registry types
## v1.3.4:
* [COOK-1173] - windows_registry throws Win32::Registry::Error for
action :remove on a nonexistent key
* [COOK-1182] - windows package sets start window title instead of
quoting a path
* [COOK-1476] - zipfile lwrp should support :zip action
* [COOK-1485] - package resource fails to perform install correctly
when "source" contains quote
* [COOK-1519] - add action :remove for path lwrp
## v1.3.2:
* [COOK-1033] - remove the `libraries/ruby_19_patches.rb` file which
causes havoc on non-Windows systems.
* [COOK-811] - add a timeout parameter attribute for `windows_package`
## v1.3.0:
* [COOK-1323] - Update for changes in Chef 0.10.10.
- Setting file mode doesn't make sense on Windows (package provider
- and reboot_handler recipe)
- Prefix ::Win32 to avoid namespace collision with Chef::Win32
- (registry_helper library)
- Use chef_gem instead of gem_package so gems get installed correctly
under the Ruby environment Chef runs in (reboot_handler recipe,
zipfile provider)
## v1.2.12:
* [COOK-1037] - specify version for rubyzip gem
* [COOK-1007] - windows_feature does not work to remove features with
dism
* [COOK-667] - shortcut resource + provider for Windows platforms
## v1.2.10
* [COOK-939] - add `type` parameter to `windows_registry` to allow binary registry keys.
* [COOK-940] - refactor logic so multiple values get created.
## v1.2.8
* FIX: Older Windows (Windows Server 2003) sometimes return 127 on successful forked commands
* FIX: `windows_package`, ensure we pass the WOW* registry redirection flags into reg.open
## v1.2.6
* patch to fix [CHEF-2684], Open4 is named Open3 in Ruby 1.9
* Ruby 1.9's Open3 returns 0 and 42 for successful commands
* retry keyword can only be used in a rescue block in Ruby 1.9
## v1.2.4
* windows_package - catch Win32::Registry::Error that pops up when searching certain keys
## v1.2.2
* combined numerous helper libarires for easier sharing across libaries/LWRPs
* renamed Chef::Provider::WindowsFeature::Base file to the more descriptive `feature_base.rb`
* refactored windows_path LWRP
* :add action should MODIFY the the underlying ENV variable (vs CREATE)
* deleted greedy :remove action until it could be made more idempotent
* added a windows_batch resource/provider for running batch scripts remotely
## v1.2.0
* [COOK-745] gracefully handle required server restarts on Windows platform
* WindowsRebootHandler for requested and pending reboots
* windows_reboot LWRP for requesting (receiving notifies) reboots
* reboot_handler recipe for enabling WindowsRebootHandler as a report handler
* [COOK-714] Correct initialize misspelling
* RegistryHelper - new `get_values` method which returns all values for a particular key.
## v1.0.8
* [COOK-719] resource/provider for managing windows features
* [COOK-717] remove `windows_env_vars` resource as env resource exists in core chef
* new `Windows::Version` helper class
* refactored `Windows::Helper` mixin
## v1.0.6
* added `force_modify` action to `windows_registry` resource
* add `win_friendly_path` helper
* re-purpose default recipe to install useful supporting windows related gems
## v1.0.4
* [COOK-700] new resources and improvements to the `windows_registry` provider (thanks Paul Morton!)
* Open the registry in the bitednes of the OS
* Provide convenience methods to check if keys and values exit
* Provide convenience method for reading registry values
* NEW - `windows_auto_run` resource/provider
* NEW - `windows_env_vars` resource/provider
* NEW - `windows_path` resource/provider
* re-write of the windows_package logic for determining current installed packages
* new checksum attribute for windows_package resource...useful for remote packages
## v1.0.2:
* [COOK-647] account for Wow6432Node registry redirecter
* [COOK-656] begin/rescue on win32/registry
## 1.0.0:
* [COOK-612] initial release

View file

@ -0,0 +1,29 @@
If you would like to contribute, please open a ticket in JIRA:
* http://tickets.opscode.com
Create the ticket in the COOK project and use the cookbook name as the
component.
For all code contributions, we ask that contributors sign a
contributor license agreement (CLA). Instructions may be found here:
* http://wiki.opscode.com/display/chef/How+to+Contribute
When contributing changes to individual cookbooks, please do not
modify the version number in the metadata.rb. Also please do not
update the CHANGELOG.md for a new version. Not all changes to a
cookbook may be merged and released in the same versions. Opscode will
handle the version updates during the release process. You are welcome
to correct typos or otherwise make updates to documentation in the
README.
If a contribution adds new platforms or platform versions, indicate
such in the body of the commit message(s), and update the relevant
COOK ticket. When writing commit messages, it is helpful for others if
you indicate the COOK ticket. For example:
git commit -m '[COOK-1041] Updated pool resource to correctly delete.'
In the ticket itself, it is also helpful if you include log output of
a successful Chef run, but this is not absolutely required.

View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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,609 @@
Description
===========
Provides a set of Windows-specific primitives (Chef resources) meant to aid in the creation of cookbooks/recipes targeting the Windows platform.
Requirements
============
Version 1.3.0+ of this cookbook requires Chef 0.10.10+.
Platform
--------
* Windows XP
* Windows Vista
* Windows Server 2003 R2
* Windows 7
* Windows Server 2008 (R1, R2)
The `windows_task` LWRP requires Windows Server 2008 due to its API usage.
Cookbooks
---------
The following cookbooks provided by Opscode are required as noted:
* chef_handler (`windows::reboot_handler` leverages the chef_handler LWRP)
* powershell - The Printer and Printer Port LWRP require Powershell.
**NOTE** We cannot specifically depend on Opscode's powershell,
because powershell depends on this cookbook. Ensure that
`recipe[powershell]` exists in the node's expanded run list so it
gets downloaded where the printer LWRPs are used.
Attributes
==========
* `node['windows']['allow_pending_reboots']` - used to configure the `WindowsRebootHandler` (via the `windows::reboot_handler` recipe) to act on pending reboots. default is true (ie act on pending reboots). The value of this attribute only has an effect if the `windows::reboot_handler` is in a node's run list.
Resource/Provider
=================
windows\_auto\_run
------------------
### Actions
- :create: Create an item to be run at login
- :remove: Remove an item that was previously setup to run at login
### Attribute Parameters
- :name: Name attribute. The name of the value to be stored in the registry
- :program: The program to be run at login
- :args: The arguments for the program
### Examples
# Run BGInfo at login
windows_auto_run 'BGINFO' do
program "C:/Sysinternals/bginfo.exe"
args "\"C:/Sysinternals/Config.bgi\" /NOLICPROMPT /TIMER:0"
not_if { Registry.value_exists?(AUTO_RUN_KEY, 'BGINFO') }
action :create
end
windows\_batch
--------------
Execute a batch script using the cmd.exe interpreter (much like the script resources for bash, csh, powershell, perl, python and ruby). A temporary file is created and executed like other script resources, rather than run inline. By their nature, Script resources are not idempotent, as they are completely up to the user's imagination. Use the `not_if` or `only_if` meta parameters to guard the resource for idempotence.
### Actions
- :run: run the batch file
### Attribute Parameters
- command: name attribute. Name of the command to execute.
- code: quoted string of code to execute.
- creates: a file this command creates - if the file exists, the command will not be run.
- cwd: current working directory to run the command from.
- flags: command line flags to pass to the interpreter when invoking.
- user: A user name or user ID that we should change to before running this command.
- group: A group name or group ID that we should change to before running this command.
### Examples
windows_batch "unzip_and_move_ruby" do
code <<-EOH
7z.exe x #{Chef::Config[:file_cache_path]}/ruby-1.8.7-p352-i386-mingw32.7z -oC:\\source -r -y
xcopy C:\\source\\ruby-1.8.7-p352-i386-mingw32 C:\\ruby /e /y
EOH
end
windows_batch "echo some env vars" do
code <<-EOH
echo %TEMP%
echo %SYSTEMDRIVE%
echo %PATH%
echo %WINDIR%
EOH
end
windows\_feature
----------------
Windows Roles and Features can be thought of as built-in operating system packages that ship with the OS. A server role is a set of software programs that, when they are installed and properly configured, lets a computer perform a specific function for multiple users or other computers within a network. A Role can have multiple Role Services that provide functionality to the Role. Role services are software programs that provide the functionality of a role. Features are software programs that, although they are not directly parts of roles, can support or augment the functionality of one or more roles, or improve the functionality of the server, regardless of which roles are installed. Collectively we refer to all of these attributes as 'features'.
This resource allows you to manage these 'features' in an unattended, idempotent way.
There are two providers for the `windows_features` which map into Microsoft's two major tools for managing roles/features: [Deployment Image Servicing and Management (DISM)](http://msdn.microsoft.com/en-us/library/dd371719(v=vs.85).aspx) and [Servermanagercmd](http://technet.microsoft.com/en-us/library/ee344834(WS.10).aspx) (The CLI for Server Manager). As Servermanagercmd is deprecated, Chef will set the default provider to `Chef::Provider::WindowsFeature::DISM` if DISM is present on the system being configured. The default provider will fall back to `Chef::Provider::WindowsFeature::ServerManagerCmd`.
For more information on Roles, Role Services and Features see the [Microsoft TechNet article on the topic](http://technet.microsoft.com/en-us/library/cc754923.aspx). For a complete list of all features that are available on a node type either of the following commands at a command prompt:
dism /online /Get-Features
servermanagercmd -query
### Actions
- :install: install a Windows role/feature
- :remove: remove a Windows role/feature
### Attribute Parameters
- feature_name: name of the feature/role to install. The same feature may have different names depending on the provider used (ie DHCPServer vs DHCP; DNS-Server-Full-Role vs DNS).
### Providers
- **Chef::Provider::WindowsFeature::DISM**: Uses Deployment Image Servicing and Management (DISM) to manage roles/features.
- **Chef::Provider::WindowsFeature::ServerManagerCmd**: Uses Server Manager to manage roles/features.
### Examples
# enable the node as a DHCP Server
windows_feature "DHCPServer" do
action :install
end
# enable TFTP
windows_feature "TFTP" do
action :install
end
# disable Telnet client/server
%w{ TelnetServer TelnetClient }.each do |feature|
windows_feature feature do
action :remove
end
end
windows\_package
----------------
Manage Windows application packages in an unattended, idempotent way.
The following application installers are currently supported:
* MSI packages
* InstallShield
* Wise InstallMaster
* Inno Setup
* Nullsoft Scriptable Install System
If the proper installer type is not passed into the resource's installer_type attribute, the provider will do it's best to identify the type by introspecting the installation package. If the installation type cannot be properly identified the `:custom` value can be passed into the installer_type attribute along with the proper flags for silent/quiet installation (using the `options` attribute..see example below).
__PLEASE NOTE__ - For proper idempotence the resource's `package_name` should be the same as the 'DisplayName' registry value in the uninstallation data that is created during package installation. The easiest way to definitively find the proper 'DisplayName' value is to install the package on a machine and search for the uninstall information under the following registry keys:
* `HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall`
* `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall`
* `HKEY_LOCAL_MACHINE\Software\Wow6464Node\Microsoft\Windows\CurrentVersion\Uninstall`
For maximum flexibility the `source` attribute supports both remote and local installation packages.
### Actions
- :install: install a package
- :remove: remove a package. The remove action is completely hit or miss as many application uninstallers do not support a full silent/quiet mode.
### Attribute Parameters
- package_name: name attribute. The 'DisplayName' of the application installation package.
- source: The source of the windows installer. This can either be a URI or a local path.
- installer_type: They type of windows installation package. valid values are: :msi, :inno, :nsis, :wise, :installshield, :custom. If this value is not provided, the provider will do it's best to identify the installer type through introspection of the file.
- checksum: useful if source is remote, the SHA-256 checksum of the file--if the local file matches the checksum, Chef will not download it
- options: Additional options to pass the underlying installation command
- timeout: set a timeout for the package download (default 600 seconds)
- version: The version number of this package, as indicated by the 'DisplayVersion' value in one of the 'Uninstall' registry keys. If the given version number does equal the 'DisplayVersion' in the registry, the package will be installed.
- success_codes: set an array of possible successful installation
return codes. Previously this was hardcoded, but certain MSIs may
have a different return code, e.g. 3010 for reboot required. Must be
an array, and defaults to `[0, 42, 127]`.
### Examples
# install PuTTY (InnoSetup installer)
windows_package "PuTTY version 0.60" do
source "http://the.earth.li/~sgtatham/putty/latest/x86/putty-0.60-installer.exe"
installer_type :inno
action :install
end
# install 7-Zip (MSI installer)
windows_package "7-Zip 9.20 (x64 edition)" do
source "http://downloads.sourceforge.net/sevenzip/7z920-x64.msi"
action :install
end
# install Notepad++ (Y U No Emacs?) using a local installer
windows_package "Notepad++" do
source "c:/installation_files/npp.5.9.2.Installer.exe"
action :install
end
# install VLC for that Xvid (NSIS installer)
windows_package "VLC media player 1.1.10" do
source "http://superb-sea2.dl.sourceforge.net/project/vlc/1.1.10/win32/vlc-1.1.10-win32.exe"
action :install
end
# install Firefox as custom installer and manually set the silent install flags
windows_package "Mozilla Firefox 5.0 (x86 en-US)" do
source "http://archive.mozilla.org/pub/mozilla.org/mozilla.org/firefox/releases/5.0/win32/en-US/Firefox%20Setup%205.0.exe"
options "-ms"
installer_type :custom
action :install
end
# Google Chrome FTW (MSI installer)
windows_package "Google Chrome" do
source "https://dl-ssl.google.com/tag/s/appguid%3D%7B8A69D345-D564-463C-AFF1-A69D9E530F96%7D%26iid%3D%7B806F36C0-CB54-4A84-A3F3-0CF8A86575E0%7D%26lang%3Den%26browser%3D3%26usagestats%3D0%26appname%3DGoogle%2520Chrome%26needsadmin%3Dfalse/edgedl/chrome/install/GoogleChromeStandaloneEnterprise.msi"
action :install
end
# remove Google Chrome (but why??)
windows_package "Google Chrome" do
action :remove
end
# remove 7-Zip
windows_package "7-Zip 9.20 (x64 edition)" do
action :remove
end
windows\_printer\_port
----------------------
**Note** Include `recipe[powershell]` on the node's expanded run list
to ensure the powershell cookbook is downloaded to avoid circular
dependency.
Create and delete TCP/IPv4 printer ports.
### Actions
- :create: Create a TCIP/IPv4 printer port. This is the default action.
- :delete: Delete a TCIP/IPv4 printer port
### Attribute Parameters
- :ipv4_address: Name attribute. Required. IPv4 address, e.g. "10.0.24.34"
- :port_name: Port name. Optional. Defaults to "IP_" + :ipv4_address
- :port_number: Port number. Optional. Defaults to 9100.
- :port_description: Port description. Optional.
- :snmp_enabled: Boolean. Optional. Defaults to false.
- :port_protocol: Port protocol, 1 (RAW), or 2 (LPR). Optional. Defaults to 1.
### Examples
# simplest example. Creates a TCP/IP printer port named "IP_10.4.64.37"
# with all defaults
windows_printer_port '10.4.64.37' do
end
# delete a printer port
windows_printer_port '10.4.64.37' do
action :delete
end
# delete a port with a custom port_name
windows_printer_port '10.4.64.38' do
port_name "My awesome port"
action :delete
end
# Create a port with more options
windows_printer_port '10.4.64.39' do
port_name "My awesome port"
snmp_enabled true
port_protocol 2
end
windows\_printer
----------------
**Note** Include `recipe[powershell]` on the node's expanded run list
to ensure the powershell cookbook is downloaded to avoid circular
dependency.
Create Windows printer. Note that this doesn't currently install a printer
driver. You must already have the driver installed on the system.
The Windows Printer LWRP will automatically create a TCP/IP printer port for you using the `ipv4_address` property. If you want more granular control over the printer port, just create it using the `windows_printer_port` LWRP before creating the printer.
### Actions
- :create: Create a new printer
- :delete: Delete a new printer
### Attribute Parameters
- :device_id: Name attribute. Required. Printer queue name, e.g. "HP LJ 5200 in fifth floor copy room"
- :comment: Optional string describing the printer queue.
- :default: Boolean. Optional. Defaults to false. Note that Windows sets the first printer defined to the default printer regardless of this setting.
- :driver_name: String. Required. Exact name of printer driver. Note that the printer driver must already be installed on the node.
- :location: Printer location, e.g. "Fifth floor copy room", or "US/NYC/Floor42/Room4207"
- :shared: Boolean. Defaults to false.
- :share_name: Printer share name.
- :ipv4_address: Printer IPv4 address, e.g. "10.4.64.23". You don't have to be able to ping the IP addresss to set it. Required.
### Examples
# create a printer
windows_printer 'HP LaserJet 5th Floor' do
driver_name 'HP LaserJet 4100 Series PCL6'
ipv4_address '10.4.64.38'
end
# delete a printer
# Note: this doesn't delete the associated printer port.
# See `windows_printer_port` above for how to delete the port.
windows_printer 'HP LaserJet 5th Floor' do
action :delete
end
windows\_reboot
---------------
Sets required data in the node's run_state to notify `WindowsRebootHandler` a reboot is requested. If Chef run completes successfully a reboot will occur if the `WindowsRebootHandler` is properly registered as a report handler. As an action of `:request` will cause a node to reboot every Chef run, this resource is usually notified by other resources...ie restart node after a package is installed (see example below).
### Actions
- :request: requests a reboot at completion of successful Cher run. requires `WindowsRebootHandler` to be registered as a report handler.
- :cancel: remove reboot request from node.run_state. this will cancel *ALL* previously requested reboots as this is a binary state.
### Attribute Parameters
- :timeout: Name attribute. timeout delay in seconds to wait before proceeding with the requested reboot. default is 60 seconds
- :reason: comment on the reason for the reboot. default is 'Opscode Chef initiated reboot'
### Examples
# if the package installs, schedule a reboot at end of chef run
windows_reboot 60 do
reason 'cause chef said so'
action :nothing
end
windows_package 'some_package' do
action :install
notifies :request, 'windows_reboot[60]'
end
# cancel the previously requested reboot
windows_reboot 60 do
action :cancel
end
windows\_registry
-----------------
Creates and modifies Windows registry keys.
*Change in v1.3.0: The Win32 classes use `::Win32` to avoid namespace conflict with `Chef::Win32` (introduced in Chef 0.10.10).*
### Actions
- :create: create a new registry key with the provided values.
- :modify: modify an existing registry key with the provided values.
- :force_modify: modify an existing registry key with the provided values. ensures the value is actually set by checking multiple times. useful for fighting race conditions where two processes are trying to set the same registry key. This will be updated in the near future to use 'RegNotifyChangeKeyValue' which is exposed by the WinAPI and allows a process to register for notification on a registry key change.
- :remove: removes a value from an existing registry key
### Attribute Parameters
- key_name: name attribute. The registry key to create/modify.
- values: hash of the values to set under the registry key. The individual hash items will become respective 'Value name' => 'Value data' items in the registry key.
- type: Type of key to create, defaults to REG_SZ. Must be a symbol, see the overview below for valid values.
### Registry key types
- :binary: REG_BINARY
- :string: REG_SZ
- :multi_string: REG_MULTI_SZ
- :expand_string: REG_EXPAND_SZ
- :dword: REG_DWORD
- :dword_big_endian: REG_DWORD_BIG_ENDIAN
- :qword: REG_QWORD
### Examples
# make the local windows proxy match the one set for Chef
proxy = URI.parse(Chef::Config[:http_proxy])
windows_registry 'HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings' do
values 'ProxyEnable' => 1, 'ProxyServer' => "#{proxy.host}:#{proxy.port}", 'ProxyOverride' => '<local>'
end
# enable Remote Desktop and poke the firewall hole
windows_registry 'HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server' do
values 'FdenyTSConnections' => 0
end
# Delete an item from the registry
windows_registry 'HKCU\Software\Test' do
#Key is the name of the value that you want to delete the value is always empty
values 'ValueToDelete' => ''
action :remove
end
# Add a REG_MULTI_SZ value to the registry
windows_registry 'HKCU\Software\Test' do
values 'MultiString' => ['line 1', 'line 2', 'line 3']
type :multi_string
end
### Library Methods
Registry.value_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run','BGINFO')
Registry.key_exists?('HKLM\SOFTWARE\Microsoft')
BgInfo = Registry.get_value('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run','BGINFO')
windows\_path
-------------
### Actions
- :add: Add an item to the system path
- :remove: Remove an item from the system path
### Attribute Parameters
- :path: Name attribute. The name of the value to add to the system path
### Examples
#Add Sysinternals to the system path
windows_path 'C:\Sysinternals' do
action :add
end
#Remove 7-Zip from the system path
windows_path 'C:\7-Zip' do
action :remove
end
windows\_task
-------------
Creates, deletes or runs a Windows scheduled task. Requires Windows
Server 2008 due to API usage.
### Actions
- :create: creates a task
- :delete: deletes a task
- :run: runs a task
- :change: changes the un/pw or command of a task
### Attribute Parameters
- name: name attribute, The task name.
- command: The command the task will run.
- cwd: The directory the task will be run from.
- user: The user to run the task as. (requires password)
- password: The user's password. (requires user)
- run_level: Run with limited or highest privileges.
- frequency: Frequency with which to run the task. (hourly, daily, ect.)
- frequency_modifier: Multiple for frequency. (15 minutes, 2 days)
### Examples
# Run Chef every 15 minutes
windows_task "Chef client" do
user "Administrator"
password "$ecR3t"
cwd "C:\chef\bin"
command "chef-client -L C:\tmp\"
run_level :highest
frequency :minute
frequency_modifier 15
end
# Update Chef Client task with new password and log location
windows_task "Chef client" do
user "Administrator"
password "N3wPassW0Rd"
cwd "C:\chef\bin"
command "chef-client -L C:\chef\logs\"
action :change
end
# Delete a taks named "old task"
windows_task "old task" do
action :delete
end
windows\_zipfile
----------------
Most version of Windows do not ship with native cli utility for managing compressed files. This resource provides a pure-ruby implementation for managing zip files. Be sure to use the `not_if` or `only_if` meta parameters to guard the resource for idempotence or action will be taken on the zip file every Chef run.
### Actions
- :unzip: unzip a compressed file
### Attribute Parameters
- path: name attribute. The path where files will be unzipped to.
- source: The source of the zip file. This can either be a URI or a local path.
- overwrite: force an overwrite of the files if the already exists.
- checksum: useful if source is remote, the SHA-256 checksum of the file--if the local file matches the checksum, Chef will not download it
### Examples
# unzip a remote zip file locally
windows_zipfile "c:/bin" do
source "http://download.sysinternals.com/Files/SysinternalsSuite.zip"
action :unzip
not_if {::File.exists?("c:/bin/PsExec.exe")}
end
# unzip a local zipfile
windows_zipfile "c:/the_codez" do
source "c:/foo/baz/the_codez.zip"
action :unzip
end
Exception/Report Handlers
=========================
WindowsRebootHandler
--------------------
Required reboots are a necessary evil of configuring and managing Windows nodes. This report handler (ie fires at the end of successful Chef runs) acts on requested (Chef initiated) or pending (as determined by the OS per configuration action we performed) reboots. The `allow_pending_reboots` initialization argument should be set to false if you do not want the handler to automatically reboot a node if it has been determined a reboot is pending. Reboots can still be requested explicitly via the `windows_reboot` LWRP.
## Initialization Arguments
- `allow_pending_reboots`: indicator on whether the handler should act on a the Window's 'pending reboot' state. default is true
- `timeout`: timeout delay in seconds to wait before proceeding with the reboot. default is 60 seconds
- `reason`: comment on the reason for the reboot. default is 'Opscode Chef initiated reboot'
Usage
=====
Place an explicit dependency on this cookbook (using depends in the cookbook's metadata.rb) from any cookbook where you would like to use the Windows-specific resources/providers that ship with this cookbook.
depends "windows"
default
-------
Convenience recipe that installs supporting gems for many of the resources/providers that ship with this cookbook.
*Change in v1.3.0: Uses chef_gem instead of gem_package to ensure gem installation in Chef 0.10.10.*
reboot\_handler
--------------
Leverages the `chef_handler` LWRP to register the `WindowsRebootHandler` report handler that ships as part of this cookbook. By default this handler is set to automatically act on pending reboots. If you would like to change this behavior override `node['windows']['allow_pending_reboots']` and set the value to false. For example:
% cat roles/base.rb
name "base"
description "base role"
override_attributes(
"windows" => {
"allow_pending_reboots" => false
}
)
This will still allow a reboot to be explicitly requested via the `windows_reboot` LWRP.
License and Author
==================
Author:: Seth Chisamore (<schisamo@opscode.com>)
Author:: Doug MacEachern (<dougm@vmware.com>)
Author:: Paul Morton (<pmorton@biaprotect.com>)
Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
Copyright:: 2011, Opscode, Inc.
Copyright:: 2010, VMware, Inc.
Copyright:: 2011, Business Intelligence Associates, Inc
Copyright:: 2012, Nordstrom, 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,22 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Attribute:: default
#
# Copyright 2011, Opscode, 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.
#
default['windows']['allow_pending_reboots'] = true
default['windows']['rubyzipversion'] = nil

View file

@ -0,0 +1,76 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Copyright:: Copyright (c) 2011 Opscode, Inc
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class WindowsRebootHandler < Chef::Handler
include Chef::Mixin::ShellOut
def initialize(allow_pending_reboots = true, timeout = 60, reason = "Opscode Chef initiated reboot")
@allow_pending_reboots = allow_pending_reboots
@timeout = timeout
@reason = reason
end
def report
log_message, reboot = begin
if reboot_requested?
["chef_handler[#{self.class}] requested reboot will occur in #{timeout} seconds", true]
elsif reboot_pending?
if @allow_pending_reboots
["chef_handler[#{self.class}] reboot pending - automatic reboot will occur in #{timeout} seconds", true]
else
["chef_handler[#{self.class}] reboot pending but handler not configured to act on pending reboots - please reboot node manually", false]
end
else
["chef_handler[#{self.class}] no reboot requested or pending", false]
end
end
Chef::Log.warn(log_message)
shell_out!("shutdown /r /t #{timeout} /c \"#{reason}\"") if reboot
end
private
# reboot cause CHEF says so:
# reboot explicitly requested in our cookbook code
def reboot_requested?
node.run_state[:reboot_requested] == true
end
# reboot cause WIN says so:
# reboot pending because of some configuration action we performed
def reboot_pending?
# Any files listed here means reboot needed
(Registry.key_exists?('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations') &&
Registry.get_value('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager','PendingFileRenameOperations').any?) ||
# 1 for any value means reboot pending
# "9306cdfc-c4a1-4a22-9996-848cb67eddc3"=1
(Registry.key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired') &&
Registry.get_values('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired').select{|v| v[2] == 1 }.any?) ||
# 1 or 2 for 'Flags' value means reboot pending
(Registry.key_exists?('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile') &&
[1,2].include?(Registry::get_value('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile','Flags')))
end
def timeout
node.run_state[:reboot_timeout] || @timeout
end
def reason
node.run_state[:reboot_reason] || @reason
end
end

View file

@ -0,0 +1,41 @@
class Chef
class Provider
class WindowsFeature
module Base
def action_install
unless installed?
install_feature(@new_resource.feature_name)
@new_resource.updated_by_last_action(true)
Chef::Log.info("#{@new_resource} installed feature")
else
Chef::Log.debug("#{@new_resource} is already installed - nothing to do")
end
end
def action_remove
if installed?
remove_feature(@new_resource.feature_name)
@new_resource.updated_by_last_action(true)
Chef::Log.info("#{@new_resource} removed")
else
Chef::Log.debug("#{@new_resource} feature does not exist - nothing to do")
end
end
def install_feature(name)
raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :install"
end
def remove_feature(name)
raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :remove"
end
def installed?
raise Chef::Exceptions::Override, "You must override installed? in #{self.to_s}"
end
end
end
end
end

View file

@ -0,0 +1,86 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Library:: helper
#
# Copyright:: 2011, Opscode, 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.
#
module Windows
module Helper
AUTO_RUN_KEY = 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
ENV_KEY = 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
# returns windows friendly version of the provided path,
# ensures backslashes are used everywhere
def win_friendly_path(path)
path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR) if path
end
# account for Window's wacky File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
# especially important for 32-bit processes (like Ruby) on a
# 64-bit instance of Windows.
def locate_sysnative_cmd(cmd)
if ::File.exists?("#{ENV['WINDIR']}\\sysnative\\#{cmd}")
"#{ENV['WINDIR']}\\sysnative\\#{cmd}"
elsif ::File.exists?("#{ENV['WINDIR']}\\system32\\#{cmd}")
"#{ENV['WINDIR']}\\system32\\#{cmd}"
else
cmd
end
end
# Create a feature provider dependent value object.
# mainly created becasue Windows Feature names are
# different based on whether dism.exe or servicemanagercmd.exe
# is used for installation
def value_for_feature_provider(provider_hash)
p = Chef::Platform.find_provider_for_node(node, :windows_feature)
key = p.to_s.downcase.split('::').last
provider_hash[key] || provider_hash[key.to_sym]
end
# singleton instance of the Windows Version checker
def win_version
@win_version ||= Windows::Version.new
end
# if a file is local it returns a windows friendly path version
# if a file is remote it caches it locally
def cached_file(source, checksum=nil, windows_path=true)
@installer_file_path ||= begin
if(source =~ /^(https?:\/\/)(.*\/)(.*)$/)
cache_file_path = "#{Chef::Config[:file_cache_path]}/#{::File.basename(source)}"
Chef::Log.debug("Caching a copy of file #{source} at #{cache_file_path}")
r = Chef::Resource::RemoteFile.new(cache_file_path, run_context)
r.source(source)
r.backup(false)
r.checksum(checksum) if checksum
r.run_action(:create)
else
cache_file_path = source
end
windows_path ? win_friendly_path(cache_file_path) : cache_file_path
end
end
end
end
Chef::Recipe.send(:include, Windows::Helper)

View file

@ -0,0 +1,357 @@
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: registry
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Opscode, Inc.
# Copyright:: 2011, Business Intelligence Associates, 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.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'win32/registry'
require 'ruby-wmi'
end
module Windows
module RegistryHelper
@@native_registry_constant = ENV['PROCESSOR_ARCHITEW6432'] == 'AMD64' ? 0x0100 : 0x0200
def get_hive_name(path)
Chef::Log.debug("Resolving registry shortcuts to full names")
reg_path = path.split("\\")
hive_name = reg_path.shift
hkey = {
"HKLM" => "HKEY_LOCAL_MACHINE",
"HKCU" => "HKEY_CURRENT_USER",
"HKU" => "HKEY_USERS"
}[hive_name] || hive_name
Chef::Log.debug("Hive resolved to #{hkey}")
return hkey
end
def get_hive(path)
Chef::Log.debug("Getting hive for #{path}")
reg_path = path.split("\\")
hive_name = reg_path.shift
hkey = get_hive_name(path)
hive = {
"HKEY_LOCAL_MACHINE" => ::Win32::Registry::HKEY_LOCAL_MACHINE,
"HKEY_USERS" => ::Win32::Registry::HKEY_USERS,
"HKEY_CURRENT_USER" => ::Win32::Registry::HKEY_CURRENT_USER
}[hkey]
unless hive
Chef::Application.fatal!("Unsupported registry hive '#{hive_name}'")
end
Chef::Log.debug("Registry hive resolved to #{hkey}")
return hive
end
def unload_hive(path)
hive = get_hive(path)
if hive == ::Win32::Registry::HKEY_USERS
reg_path = path.split("\\")
priv = Chef::WindowsPrivileged.new
begin
priv.reg_unload_key(reg_path[1])
rescue
end
end
end
def set_value(mode,path,values,type=nil)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key_name = reg_path.join("\\")
Chef::Log.debug("Creating #{path}")
if !key_exists?(path,true)
create_key(path)
end
hive.send(mode, key_name, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg|
changed_something = false
values.each do |k,val|
key = "#{k}" #wtf. avoid "can't modify frozen string" in win32/registry.rb
cur_val = nil
begin
cur_val = reg[key]
rescue
#subkey does not exist (ok)
end
if cur_val != val
Chef::Log.debug("setting #{key}=#{val}")
if type.nil?
type = :string
end
reg_type = {
:binary => ::Win32::Registry::REG_BINARY,
:string => ::Win32::Registry::REG_SZ,
:multi_string => ::Win32::Registry::REG_MULTI_SZ,
:expand_string => ::Win32::Registry::REG_EXPAND_SZ,
:dword => ::Win32::Registry::REG_DWORD,
:dword_big_endian => ::Win32::Registry::REG_DWORD_BIG_ENDIAN,
:qword => ::Win32::Registry::REG_QWORD
}[type]
reg.write(key, reg_type, val)
ensure_hive_unloaded(hive_loaded)
changed_something = true
end
end
return changed_something
end
return false
end
def get_value(path,value)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do | reg |
begin
return reg[value]
rescue
return nil
ensure
ensure_hive_unloaded(hive_loaded)
end
end
end
def get_values(path)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do | reg |
values = []
begin
reg.each_value do |name, type, data|
values << [name, type, data]
end
rescue
ensure
ensure_hive_unloaded(hive_loaded)
end
values
end
end
def delete_value(path,values)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
Chef::Log.debug("Deleting values in #{path}")
hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do | reg |
values.each_key { |key|
name = "#{key}"
# Ensure delete operation is idempotent.
if value_exists?(path, key)
Chef::Log.debug("Deleting value #{name} in #{path}")
reg.delete_value(name)
else
Chef::Log.debug("Value #{name} in #{path} does not exist, skipping.")
end
}
end
end
def create_key(path)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
Chef::Log.debug("Creating registry key #{path}")
hive.create(key)
end
def value_exists?(path,value)
if key_exists?(path,true)
hive, reg_path, hive_name, root_key , hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
Chef::Log.debug("Attempting to open #{key}");
Chef::Log.debug("Native Constant #{@@native_registry_constant}")
Chef::Log.debug("Hive #{hive}")
hive.open(key, ::Win32::Registry::KEY_READ | @@native_registry_constant) do | reg |
begin
rtn_value = reg[value]
return true
rescue
return false
ensure
ensure_hive_unloaded(hive_loaded)
end
end
end
return false
end
# TODO: Does not load user registry...
def key_exists?(path, load_hive = false)
if load_hive
hive, reg_path, hive_name, root_key , hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
else
hive = get_hive(path)
reg_path = path.split("\\")
hive_name = reg_path.shift
root_key = reg_path[0]
key = reg_path.join("\\")
hive_loaded = false
end
begin
hive.open(key, ::Win32::Registry::Constants::KEY_READ | @@native_registry_constant )
return true
rescue
return false
ensure
ensure_hive_unloaded(hive_loaded)
end
end
def get_user_hive_location(sid)
reg_key = "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\#{sid}"
Chef::Log.debug("Looking for profile at #{reg_key}")
if key_exists?(reg_key)
return get_value(reg_key,'ProfileImagePath')
else
return nil
end
end
def resolve_user_to_sid(username)
begin
sid = WMI::Win32_UserAccount.find(:first, :conditions => {:name => username}).sid
Chef::Log.debug("Resolved user SID to #{sid}")
return sid
rescue
return nil
end
end
def hive_loaded?(path)
hive = get_hive(path)
reg_path = path.split("\\")
hive_name = reg_path.shift
user_hive = path[0]
if is_user_hive?(hive)
return key_exists?("#{hive_name}\\#{user_hive}")
else
return true
end
end
def is_user_hive?(hive)
if hive == ::Win32::Registry::HKEY_USERS
return true
else
return true
end
end
def get_reg_path_info(path)
hive = get_hive(path)
reg_path = path.split("\\")
hive_name = reg_path.shift
root_key = reg_path[0]
hive_loaded = false
if is_user_hive?(hive) && !key_exists?("#{hive_name}\\#{root_key}")
reg_path, hive_loaded = load_user_hive(hive,reg_path,root_key)
root_key = reg_path[0]
Chef::Log.debug("Resolved user (#{path}) to (#{reg_path.join('/')})")
end
return hive, reg_path, hive_name, root_key, hive_loaded
end
def load_user_hive(hive,reg_path,user_hive)
Chef::Log.debug("Reg Path #{reg_path}")
# See if the hive is loaded. Logged in users will have a key that is named their SID
# if the user has specified the a path by SID and the user is logged in, this function
# should not be executed.
if is_user_hive?(hive) && !key_exists?("HKU\\#{user_hive}")
Chef::Log.debug("The user is not logged in and has not been specified by SID")
sid = resolve_user_to_sid(user_hive)
Chef::Log.debug("User SID resolved to (#{sid})")
# Now that the user has been resolved to a SID, check and see if the hive exists.
# If this exists by SID, the user is logged in and we should use that key.
# TODO: Replace the username with the sid and send it back because the username
# does not exist as the key location.
load_reg = false
if key_exists?("HKU\\#{sid}")
reg_path[0] = sid #use the active profile (user is logged on)
Chef::Log.debug("HKEY_USERS Mapped: #{user_hive} -> #{sid}")
else
Chef::Log.debug("User is not logged in")
load_reg = true
end
# The user is not logged in, so we should load the registry from disk
if load_reg
profile_path = get_user_hive_location(sid)
if profile_path != nil
ntuser_dat = "#{profile_path}\\NTUSER.DAT"
if ::File.exists?(ntuser_dat)
priv = Chef::WindowsPrivileged.new
if priv.reg_load_key(sid,ntuser_dat)
Chef::Log.debug("RegLoadKey(#{sid}, #{user_hive}, #{ntuser_dat})")
reg_path[0] = sid
else
Chef::Log.debug("Failed RegLoadKey(#{sid}, #{user_hive}, #{ntuser_dat})")
end
end
end
end
end
return reg_path, load_reg
end
private
def ensure_hive_unloaded(hive_loaded=false)
if(hive_loaded)
Chef::Log.debug("Hive was loaded, we really should unload it")
unload_hive(path)
end
end
end
end
module Registry
module_function
extend Windows::RegistryHelper
end

View file

@ -0,0 +1,204 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Library:: version
#
# Copyright:: 2011, Opscode, 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.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'ruby-wmi'
require 'Win32API'
end
module Windows
class Version
# http://msdn.microsoft.com/en-us/library/ms724833(v=vs.85).aspx
# Suite Masks
# Microsoft BackOffice components are installed.
VER_SUITE_BACKOFFICE = 0x00000004
# Windows Server 2003, Web Edition is installed.
VER_SUITE_BLADE = 0x00000400
# Windows Server 2003, Compute Cluster Edition is installed.
VER_SUITE_COMPUTE_SERVER = 0x00004000
# Windows Server 2008 Datacenter, Windows Server 2003, Datacenter Edition, or Windows 2000 Datacenter Server is installed.
VER_SUITE_DATACENTER = 0x00000080
# Windows Server 2008 Enterprise, Windows Server 2003, Enterprise Edition, or Windows 2000 Advanced Server is installed. Refer to the Remarks section for more information about this bit flag.
VER_SUITE_ENTERPRISE = 0x00000002
# Windows XP Embedded is installed.
VER_SUITE_EMBEDDEDNT = 0x00000040
# Windows Vista Home Premium, Windows Vista Home Basic, or Windows XP Home Edition is installed.
VER_SUITE_PERSONAL = 0x00000200
# Remote Desktop is supported, but only one interactive session is supported. This value is set unless the system is running in application server mode.
VER_SUITE_SINGLEUSERTS = 0x00000100
# Microsoft Small Business Server was once installed on the system, but may have been upgraded to another version of Windows. Refer to the Remarks section for more information about this bit flag.
VER_SUITE_SMALLBUSINESS = 0x00000001
# Microsoft Small Business Server is installed with the restrictive client license in force. Refer to the Remarks section for more information about this bit flag.
VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x00000020
# Windows Storage Server 2003 R2 or Windows Storage Server 2003is installed.
VER_SUITE_STORAGE_SERVER = 0x00002000
# Terminal Services is installed. This value is always set.
# If VER_SUITE_TERMINAL is set but VER_SUITE_SINGLEUSERTS is not set, the system is running in application server mode.
VER_SUITE_TERMINAL = 0x00000010
# Windows Home Server is installed.
VER_SUITE_WH_SERVER = 0x00008000
# Product Type
# The system is a domain controller and the operating system is Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, or Windows 2000 Server.
VER_NT_DOMAIN_CONTROLLER = 0x0000002
# The operating system is Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, or Windows 2000 Server.
# Note that a server that is also a domain controller is reported as VER_NT_DOMAIN_CONTROLLER, not VER_NT_SERVER.
VER_NT_SERVER = 0x0000003
# The operating system is Windows 7, Windows Vista, Windows XP Professional, Windows XP Home Edition, or Windows 2000 Professional.
VER_NT_WORKSTATION = 0x0000001
# GetSystemMetrics
# The build number if the system is Windows Server 2003 R2; otherwise, 0.
SM_SERVERR2 = 89
# http://msdn.microsoft.com/en-us/library/ms724358(v=vs.85).aspx
# this is what it sounds like...when kittens die
SKU = {
0x00000006 => {:ms_const => 'PRODUCT_BUSINESS', :name => 'Business'},
0x00000010 => {:ms_const => 'PRODUCT_BUSINESS_N', :name => 'Business N'},
0x00000012 => {:ms_const => 'PRODUCT_CLUSTER_SERVER', :name => 'HPC Edition'},
0x00000008 => {:ms_const => 'PRODUCT_DATACENTER_SERVER', :name => 'Server Datacenter (full installation)'},
0x0000000C => {:ms_const => 'PRODUCT_DATACENTER_SERVER_CORE', :name => 'Server Datacenter (core installation)'},
0x00000027 => {:ms_const => 'PRODUCT_DATACENTER_SERVER_CORE_V', :name => 'Server Datacenter without Hyper-V (core installation)'},
0x00000025 => {:ms_const => 'PRODUCT_DATACENTER_SERVER_V', :name => 'Server Datacenter without Hyper-V (full installation)'},
0x00000004 => {:ms_const => 'PRODUCT_ENTERPRISE', :name => 'Enterprise'},
0x00000046 => {:ms_const => 'PRODUCT_ENTERPRISE_E', :name => 'Not supported'},
0x0000001B => {:ms_const => 'PRODUCT_ENTERPRISE_N', :name => 'Enterprise N'},
0x0000000A => {:ms_const => 'PRODUCT_ENTERPRISE_SERVER', :name => 'Server Enterprise (full installation)'},
0x0000000E => {:ms_const => 'PRODUCT_ENTERPRISE_SERVER_CORE', :name => 'Server Enterprise (core installation)'},
0x00000029 => {:ms_const => 'PRODUCT_ENTERPRISE_SERVER_CORE_V', :name => 'Server Enterprise without Hyper-V (core installation)'},
0x0000000F => {:ms_const => 'PRODUCT_ENTERPRISE_SERVER_IA64', :name => 'Server Enterprise for Itanium-based Systems'},
0x00000026 => {:ms_const => 'PRODUCT_ENTERPRISE_SERVER_V', :name => 'Server Enterprise without Hyper-V (full installation)'},
0x00000002 => {:ms_const => 'PRODUCT_HOME_BASIC', :name => 'Home Basic'},
0x00000043 => {:ms_const => 'PRODUCT_HOME_BASIC_E', :name => 'Not supported'},
0x00000005 => {:ms_const => 'PRODUCT_HOME_BASIC_N', :name => 'Home Basic N'},
0x00000003 => {:ms_const => 'PRODUCT_HOME_PREMIUM', :name => 'Home Premium'},
0x00000044 => {:ms_const => 'PRODUCT_HOME_PREMIUM_E', :name => 'Not supported'},
0x0000001A => {:ms_const => 'PRODUCT_HOME_PREMIUM_N', :name => 'Home Premium N'},
0x0000002A => {:ms_const => 'PRODUCT_HYPERV', :name => 'Microsoft Hyper-V Server'},
0x0000001E => {:ms_const => 'PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT', :name => 'Windows Essential Business Server Management Server'},
0x00000020 => {:ms_const => 'PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING', :name => 'Windows Essential Business Server Messaging Server'},
0x0000001F => {:ms_const => 'PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY', :name => 'Windows Essential Business Server Security Server'},
0x00000030 => {:ms_const => 'PRODUCT_PROFESSIONAL', :name => 'Professional'},
0x00000045 => {:ms_const => 'PRODUCT_PROFESSIONAL_E', :name => 'Not supported'},
0x00000031 => {:ms_const => 'PRODUCT_PROFESSIONAL_N', :name => 'Professional N'},
0x00000018 => {:ms_const => 'PRODUCT_SERVER_FOR_SMALLBUSINESS', :name => 'Windows Server 2008 for Windows Essential Server Solutions'},
0x00000023 => {:ms_const => 'PRODUCT_SERVER_FOR_SMALLBUSINESS_V', :name => 'Windows Server 2008 without Hyper-V for Windows Essential Server Solutions'},
0x00000021 => {:ms_const => 'PRODUCT_SERVER_FOUNDATION', :name => 'Server Foundation'},
0x00000022 => {:ms_const => 'PRODUCT_HOME_PREMIUM_SERVER', :name => 'Windows Home Server 2011'},
0x00000032 => {:ms_const => 'PRODUCT_SB_SOLUTION_SERVER', :name => 'Windows Small Business Server 2011 Essentials'},
0x00000013 => {:ms_const => 'PRODUCT_HOME_SERVER', :name => 'Windows Storage Server 2008 R2 Essentials'},
0x00000009 => {:ms_const => 'PRODUCT_SMALLBUSINESS_SERVER', :name => 'Windows Small Business Server'},
0x00000038 => {:ms_const => 'PRODUCT_SOLUTION_EMBEDDEDSERVER', :name => 'Windows MultiPoint Server'},
0x00000007 => {:ms_const => 'PRODUCT_STANDARD_SERVER', :name => 'Server Standard (full installation)'},
0x0000000D => {:ms_const => 'PRODUCT_STANDARD_SERVER_CORE', :name => 'Server Standard (core installation)'},
0x00000028 => {:ms_const => 'PRODUCT_STANDARD_SERVER_CORE_V', :name => 'Server Standard without Hyper-V (core installation)'},
0x00000024 => {:ms_const => 'PRODUCT_STANDARD_SERVER_V', :name => 'Server Standard without Hyper-V (full installation)'},
0x0000000B => {:ms_const => 'PRODUCT_STARTER', :name => 'Starter'},
0x00000042 => {:ms_const => 'PRODUCT_STARTER_E', :name => 'Not supported'},
0x0000002F => {:ms_const => 'PRODUCT_STARTER_N', :name => 'Starter N'},
0x00000017 => {:ms_const => 'PRODUCT_STORAGE_ENTERPRISE_SERVER', :name => 'Storage Server Enterprise'},
0x00000014 => {:ms_const => 'PRODUCT_STORAGE_EXPRESS_SERVER', :name => 'Storage Server Express'},
0x00000015 => {:ms_const => 'PRODUCT_STORAGE_STANDARD_SERVER', :name => 'Storage Server Standard'},
0x00000016 => {:ms_const => 'PRODUCT_STORAGE_WORKGROUP_SERVER', :name => 'Storage Server Workgroup'},
0x00000000 => {:ms_const => 'PRODUCT_UNDEFINED', :name => 'An unknown product'},
0x00000001 => {:ms_const => 'PRODUCT_ULTIMATE', :name => 'Ultimate'},
0x00000047 => {:ms_const => 'PRODUCT_ULTIMATE_E', :name => 'Not supported'},
0x0000001C => {:ms_const => 'PRODUCT_ULTIMATE_N', :name => 'Ultimate N'},
0x00000011 => {:ms_const => 'PRODUCT_WEB_SERVER', :name => 'Web Server (full installation)'},
0x0000001D => {:ms_const => 'PRODUCT_WEB_SERVER_CORE', :name => 'Web Server (core installation)'}
}
attr_reader :major_version, :minor_version, :build_number, :service_pack_major_version, :service_pack_minor_version
attr_reader :version, :product_type, :product_suite, :sku
def initialize
unless RUBY_PLATFORM =~ /mswin|mingw32|windows/
raise NotImplementedError, 'only valid on Windows platform'
end
@version, @product_type, @product_suite, @sku, @service_pack_major_version, @service_pack_minor_version = get_os_info
@major_version, @minor_version, @build_number = version.split('.').map{|v| v.to_i }
end
WIN_VERSIONS = {
"Windows 7" => {:major => 6, :minor => 1, :callable => lambda{ @product_type == VER_NT_WORKSTATION }},
"Windows Server 2008 R2" => {:major => 6, :minor => 1, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
"Windows Server 2008" => {:major => 6, :minor => 0, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
"Windows Vista" => {:major => 6, :minor => 0, :callable => lambda{ @product_type == VER_NT_WORKSTATION }},
"Windows Server 2003 R2" => {:major => 5, :minor => 2, :callable => lambda{ Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) != 0 }},
"Windows Home Server" => {:major => 5, :minor => 2, :callable => lambda{ (@product_suite & VER_SUITE_WH_SERVER) == VER_SUITE_WH_SERVER }},
"Windows Server 2003" => {:major => 5, :minor => 2, :callable => lambda{ Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) == 0 }},
"Windows XP" => {:major => 5, :minor => 1},
"Windows 2000" => {:major => 5, :minor => 0}
}
marketing_names = Array.new
# General Windows checks
WIN_VERSIONS.each do |k,v|
method_name = "#{k.gsub(/\s/, '_').downcase}?"
define_method(method_name) do
(@major_version == v[:major]) &&
(@minor_version == v[:minor]) &&
(v[:callable] ? v[:callable].call : true)
end
marketing_names << [k, method_name]
end
define_method(:marketing_name) do
marketing_names.each do |mn|
break mn[0] if self.send(mn[1])
end
end
# Server Type checks
%w{ core full datacenter }.each do |m|
define_method("server_#{m}?") do
if @sku
!(SKU[@sku][:name] =~ /#{m}/i).nil?
else
false
end
end
end
private
# Win32API call to GetSystemMetrics(SM_SERVERR2)
# returns: The build number if the system is Windows Server 2003 R2; otherwise, 0.
def sm_serverr2
@sm_serverr2 ||= Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2)
end
# query WMI Win32_OperatingSystem for required OS info
def get_os_info
cols = %w{ Version ProductType OSProductSuite OperatingSystemSKU ServicePackMajorVersion ServicePackMinorVersion }
os_info = WMI::Win32_OperatingSystem.find(:first)
cols.map do |c|
begin
os_info.send(c)
rescue # OperatingSystemSKU doesn't exist in all versions of Windows
nil
end
end
end
end
end

View file

@ -0,0 +1,94 @@
#
# Author:: Doug MacEachern <dougm@vmware.com>
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Library:: windows_privileged
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Business Intelligence Associates, 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.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'windows/error'
require 'windows/registry'
require 'windows/process'
require 'windows/security'
end
#helpers for Windows API calls that require privilege adjustments
class Chef
class WindowsPrivileged
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
include Windows::Error
include Windows::Registry
include Windows::Process
include Windows::Security
end
#File -> Load Hive... in regedit.exe
def reg_load_key(name, file)
run(SE_BACKUP_NAME, SE_RESTORE_NAME) do
rc = RegLoadKey(HKEY_USERS, "#{name}", file)
if rc == ERROR_SUCCESS
return true
elsif rc == ERROR_SHARING_VIOLATION
return false
else
raise get_last_error(rc)
end
end
end
#File -> Unload Hive... in regedit.exe
def reg_unload_key(name)
run(SE_BACKUP_NAME, SE_RESTORE_NAME) do
rc = RegUnLoadKey(HKEY_USERS, "#{name}")
if rc != ERROR_SUCCESS
raise get_last_error(rc)
end
end
end
def run(*privileges)
token = [0].pack('L')
unless OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, token)
raise get_last_error
end
token = token.unpack('L')[0]
privileges.each do |name|
unless adjust_privilege(token, name, SE_PRIVILEGE_ENABLED)
raise get_last_error
end
end
begin
yield
ensure #disable privs
privileges.each do |name|
adjust_privilege(token, name, 0)
end
end
end
def adjust_privilege(token, priv, attr=0)
luid = [0,0].pack('Ll')
if LookupPrivilegeValue(nil, priv, luid)
new_state = [1, luid.unpack('Ll'), attr].flatten.pack('LLlL')
AdjustTokenPrivileges(token, 0, new_state, new_state.size, 0, 0)
end
end
end
end

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,9 @@
name "windows"
maintainer "Opscode, Inc."
maintainer_email "cookbooks@opscode.com"
license "Apache 2.0"
description "Provides a set of useful Windows-specific primitives."
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version "1.8.4"
supports "windows"
depends "chef_handler"

View file

@ -0,0 +1,32 @@
#
# Author:: Paul Morotn (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: auto_run
#
# Copyright:: 2011, Business Intelligence Associates, 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.
#
action :create do
windows_registry 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' do
values new_resource.name => "\"#{new_resource.program}\" #{new_resource.args}"
end
end
action :remove do
windows_registry 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' do
values new_resource.name => ''
action :remove
end
end

View file

@ -0,0 +1,62 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windws
# Provider:: batch
#
# Copyright:: 2011, Opscode, 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.
#
require 'tempfile'
require 'chef/resource/execute'
action :run do
begin
script_file.puts(@new_resource.code)
script_file.close
set_owner_and_group
# cwd hax...shell_out on windows needs to support proper 'cwd'
# follow CHEF-2357 for more
cwd = @new_resource.cwd ? "cd \"#{@new_resource.cwd}\" & " : ""
r = Chef::Resource::Execute.new(@new_resource.name, run_context)
r.user(@new_resource.user)
r.group(@new_resource.group)
r.command("#{cwd}call \"#{script_file.path}\" #{@new_resource.flags}")
r.creates(@new_resource.creates)
r.returns(@new_resource.returns)
r.run_action(:run)
@new_resource.updated_by_last_action(r.updated_by_last_action?)
ensure
unlink_script_file
end
end
private
def set_owner_and_group
# FileUtils itself implements a no-op if +user+ or +group+ are nil
# You can prove this by running FileUtils.chown(nil,nil,'/tmp/file')
# as an unprivileged user.
FileUtils.chown(@new_resource.user, @new_resource.group, script_file.path)
end
def script_file
@script_file ||= Tempfile.open(['chef-script', '.bat'])
end
def unlink_script_file
@script_file && @script_file.close!
end

View file

@ -0,0 +1,47 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Provider:: feature_dism
#
# Copyright:: 2011, Opscode, 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.
#
include Chef::Provider::WindowsFeature::Base
include Chef::Mixin::ShellOut
include Windows::Helper
def install_feature(name)
shell_out!("#{dism} /online /enable-feature /featurename:#{@new_resource.feature_name} /norestart", {:returns => [0,42,127]})
end
def remove_feature(name)
shell_out!("#{dism} /online /disable-feature /featurename:#{@new_resource.feature_name} /norestart", {:returns => [0,42,127]})
end
def installed?
@installed ||= begin
cmd = shell_out("#{dism} /online /Get-Features", {:returns => [0,42,127]})
cmd.stderr.empty? && (cmd.stdout =~ /^Feature Name : #{@new_resource.feature_name}.?$\n^State : Enabled.?$/i)
end
end
private
# account for File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
def dism
@dism ||= begin
locate_sysnative_cmd("dism.exe")
end
end

View file

@ -0,0 +1,47 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Provider:: feature_servermanagercmd
#
# Copyright:: 2011, Opscode, 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.
#
include Chef::Provider::WindowsFeature::Base
include Chef::Mixin::ShellOut
include Windows::Helper
def install_feature(name)
shell_out!("#{servermanagercmd} -install #{@new_resource.feature_name}", {:returns => [0,42,127]})
end
def remove_feature(name)
shell_out!("#{servermanagercmd} -remove #{@new_resource.feature_name}", {:returns => [0,42,127]})
end
def installed?
@installed ||= begin
cmd = shell_out("#{servermanagercmd} -query", {:returns => [0,42,127]})
cmd.stderr.empty? && (cmd.stdout =~ /^\s*?\[X\]\s.+?\s\[#{@new_resource.feature_name}\]$/i)
end
end
private
# account for File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
def servermanagercmd
@servermanagercmd ||= begin
locate_sysnative_cmd("servermanagercmd.exe")
end
end

View file

@ -0,0 +1,251 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Provider:: package
#
# Copyright:: 2011, Opscode, 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.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'win32/registry'
end
require 'chef/mixin/shell_out'
require 'chef/mixin/language'
include Chef::Mixin::ShellOut
include Windows::Helper
# the logic in all action methods mirror that of
# the Chef::Provider::Package which will make
# refactoring into core chef easy
action :install do
# If we specified a version, and it's not the current version, move to the specified version
if @new_resource.version != nil && @new_resource.version != @current_resource.version
install_version = @new_resource.version
# If it's not installed at all, install it
elsif @current_resource.version == nil
install_version = candidate_version
end
if install_version
Chef::Log.info("Installing #{@new_resource} version #{install_version}")
status = install_package(@new_resource.package_name, install_version)
if status
@new_resource.updated_by_last_action(true)
end
end
end
action :upgrade do
if @current_resource.version != candidate_version
orig_version = @current_resource.version || "uninstalled"
Chef::Log.info("Upgrading #{@new_resource} version from #{orig_version} to #{candidate_version}")
status = upgrade_package(@new_resource.package_name, candidate_version)
if status
@new_resource.updated_by_last_action(true)
end
end
end
action :remove do
if removing_package?
Chef::Log.info("Removing #{@new_resource}")
remove_package(@current_resource.package_name, @new_resource.version)
@new_resource.updated_by_last_action(true)
else
end
end
def removing_package?
if @current_resource.version.nil?
false # nothing to remove
elsif @new_resource.version.nil?
true # remove any version of a package
elsif @new_resource.version == @current_resource.version
true # remove the version we have
else
false # we don't have the version we want to remove
end
end
def expand_options(options)
options ? " #{options}" : ""
end
# these methods are the required overrides of
# a provider that extends from Chef::Provider::Package
# so refactoring into core Chef should be easy
def load_current_resource
@current_resource = Chef::Resource::WindowsPackage.new(@new_resource.name)
@current_resource.package_name(@new_resource.package_name)
@current_resource.version(nil)
unless current_installed_version.nil?
@current_resource.version(current_installed_version)
end
@current_resource
end
def current_installed_version
@current_installed_version ||= begin
if installed_packages.include?(@new_resource.package_name)
installed_packages[@new_resource.package_name][:version]
end
end
end
def candidate_version
@candidate_version ||= begin
@new_resource.version || 'latest'
end
end
def install_package(name,version)
Chef::Log.debug("Processing #{@new_resource} as a #{installer_type} installer.")
install_args = [cached_file(@new_resource.source, @new_resource.checksum), expand_options(unattended_installation_flags), expand_options(@new_resource.options)]
Chef::Log.info("Starting installation...this could take awhile.")
Chef::Log.debug "Install command: #{ sprintf(install_command_template, *install_args) }"
shell_out!(sprintf(install_command_template, *install_args), {:timeout => @new_resource.timeout, :returns => @new_resource.success_codes})
end
def remove_package(name, version)
uninstall_string = installed_packages[@new_resource.package_name][:uninstall_string]
Chef::Log.info("Registry provided uninstall string for #{@new_resource} is '#{uninstall_string}'")
uninstall_command = begin
if uninstall_string =~ /msiexec/i
"#{uninstall_string} /qn"
else
uninstall_string.gsub!('"','')
"start \"\" /wait /d\"#{::File.dirname(uninstall_string)}\" #{::File.basename(uninstall_string)}#{expand_options(@new_resource.options)} /S"
end
end
Chef::Log.info("Removing #{@new_resource} with uninstall command '#{uninstall_command}'")
shell_out!(uninstall_command, {:returns => @new_resource.success_codes})
end
private
def install_command_template
case installer_type
when :msi
"msiexec%2$s \"%1$s\"%3$s"
else
"start \"\" /wait %1$s%2$s%3$s"
end
end
def uninstall_command_template
case installer_type
when :msi
"msiexec %2$s %1$s"
else
"start \"\" /wait /d%1$s %2$s %3$s"
end
end
# http://unattended.sourceforge.net/installers.php
def unattended_installation_flags
case installer_type
when :msi
"/qb /i"
when :installshield
"/s /sms"
when :nsis
"/S /NCRC"
when :inno
#"/sp- /silent /norestart"
"/verysilent /norestart"
when :wise
"/s"
else
end
end
def installed_packages
@installed_packages || begin
installed_packages = {}
# Computer\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE)) #rescue nil
# 64-bit registry view
# Computer\HKEY_LOCAL_MACHINE\Software\Wow6464Node\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0100))) #rescue nil
# 32-bit registry view
# Computer\HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0200))) #rescue nil
# Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_CURRENT_USER)) #rescue nil
installed_packages
end
end
def extract_installed_packages_from_key(hkey = ::Win32::Registry::HKEY_LOCAL_MACHINE, desired = ::Win32::Registry::Constants::KEY_READ)
uninstall_subkey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall'
packages = {}
begin
::Win32::Registry.open(hkey, uninstall_subkey, desired) do |reg|
reg.each_key do |key, wtime|
begin
k = reg.open(key, desired)
display_name = k["DisplayName"] rescue nil
version = k["DisplayVersion"] rescue "NO VERSION"
uninstall_string = k["UninstallString"] rescue nil
if display_name
packages[display_name] = {:name => display_name,
:version => version,
:uninstall_string => uninstall_string}
end
rescue ::Win32::Registry::Error
end
end
end
rescue ::Win32::Registry::Error
end
packages
end
def installer_type
@installer_type || begin
if @new_resource.installer_type
@new_resource.installer_type
else
basename = ::File.basename(cached_file(@new_resource.source, @new_resource.checksum))
if basename.split(".").last == "msi" # Microsoft MSI
:msi
else
# search the binary file for installer type
contents = ::Kernel.open(::File.expand_path(cached_file(@new_resource.source)), "rb") {|io| io.read } # TODO limit data read in
case contents
when /inno/i # Inno Setup
:inno
when /wise/i # Wise InstallMaster
:wise
when /nsis/i # Nullsoft Scriptable Install System
:nsis
else
# if file is named 'setup.exe' assume installshield
if basename == "setup.exe"
:installshield
else
raise Chef::Exceptions::AttributeNotFound, "installer_type could not be determined, please set manually"
end
end
end
end
end
end

View file

@ -0,0 +1,153 @@
#
# Author:: Kevin Moser (<kevin.moser@nordstrom.com>)
# Cookbook Name:: windows
# Provider:: pagefile
#
# Copyright:: 2012, Nordstrom, 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.
#
include Chef::Mixin::ShellOut
include Windows::Helper
action :set do
pagefile = @new_resource.name
initial_size = @new_resource.initial_size
maximum_size = @new_resource.maximum_size
system_managed = @new_resource.system_managed
automatic_managed = @new_resource.automatic_managed
updated = false
if automatic_managed
unless automatic_managed?
set_automatic_managed
updated = true
end
else
if automatic_managed?
unset_automatic_managed
updated = true
end
# Check that the resource is not just trying to unset automatic managed, if it is do nothing more
if (initial_size && maximum_size) || system_managed
unless exists?(pagefile)
create(pagefile)
end
if system_managed
unless max_and_min_set?(pagefile, 0, 0)
set_system_managed(pagefile)
updated = true
end
else
unless max_and_min_set?(pagefile, initial_size, maximum_size)
set_custom_size(pagefile, initial_size, maximum_size)
updated = true
end
end
end
end
@new_resource.updated_by_last_action(updated)
end
action :delete do
pagefile = @new_resource.name
updated = false
if exists?(pagefile)
delete(pagefile)
updated = true
end
@new_resource.updated_by_last_action(updated)
end
private
def exists?(pagefile)
@exists ||= begin
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list", {:returns => [0]})
cmd.stderr.empty? && (cmd.stdout =~ /SettingID=#{get_setting_id(pagefile)}/i)
end
end
def max_and_min_set?(pagefile, min, max)
@max_and_min_set ||= begin
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list", {:returns => [0]})
cmd.stderr.empty? && (cmd.stdout =~ /InitialSize=#{min}/i) && (cmd.stdout =~ /MaximumSize=#{max}/i)
end
end
def create(pagefile)
Chef::Log.debug("Creating pagefile #{pagefile}")
cmd = shell_out("#{wmic} pagefileset create name=\"#{win_friendly_path(pagefile)}\"")
check_for_errors(cmd.stderr)
end
def delete(pagefile)
Chef::Log.debug("Removing pagefile #{pagefile}")
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" delete")
check_for_errors(cmd.stderr)
end
def automatic_managed?
@automatic_managed ||= begin
cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" get AutomaticManagedPagefile /format:list")
cmd.stderr.empty? && (cmd.stdout =~ /AutomaticManagedPagefile=TRUE/i)
end
end
def set_automatic_managed
Chef::Log.debug("Setting pagefile to Automatic Managed")
cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=True")
check_for_errors(cmd.stderr)
end
def unset_automatic_managed
Chef::Log.debug("Setting pagefile to User Managed")
cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=False")
check_for_errors(cmd.stderr)
end
def set_custom_size(pagefile, min, max)
Chef::Log.debug("Setting #{pagefile} to InitialSize=#{min} & MaximumSize=#{max}")
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=#{min},MaximumSize=#{max}", {:returns => [0]})
check_for_errors(cmd.stderr)
end
def set_system_managed(pagefile)
Chef::Log.debug("Setting #{pagefile} to System Managed")
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=0,MaximumSize=0", {:returns => [0]})
check_for_errors(cmd.stderr)
end
def get_setting_id(pagefile)
pagefile = win_friendly_path(pagefile)
pagefile = pagefile.split("\\")
"#{pagefile[1]} @ #{pagefile[0]}"
end
def check_for_errors(stderr)
unless stderr.empty?
Chef::Log.fatal(stderr)
end
end
def wmic
@wmic ||= begin
locate_sysnative_cmd("wmic.exe")
end
end

View file

@ -0,0 +1,35 @@
#
# Author:: Paul Morotn (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: path
#
# Copyright:: 2011, Business Intelligence Associates, 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.
#
action :add do
env "PATH" do
action :modify
delim ::File::PATH_SEPARATOR
value new_resource.path
end
end
action :remove do
env "PATH" do
action :delete
delim ::File::PATH_SEPARATOR
value new_resource.path
end
end

View file

@ -0,0 +1,100 @@
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Provider:: printer
#
# Copyright:: 2012, Nordstrom, 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.
#
# Support whyrun
def whyrun_supported?
true
end
action :create do
if @current_resource.exists
Chef::Log.info "#{ @new_resource } already exists - nothing to do."
else
converge_by("Create #{ @new_resource }") do
create_printer
end
end
end
action :delete do
if @current_resource.exists
converge_by("Delete #{ @new_resource }") do
delete_printer
end
else
Chef::Log.info "#{ @current_resource } doesn't exist - can't delete."
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsPrinter.new(@new_resource.name)
@current_resource.name(@new_resource.name)
if printer_exists?(@current_resource.name)
# TODO: Set @current_resource printer properties from registry
@current_resource.exists = true
end
end
private
PRINTERS_REG_KEY = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\\'
def printer_exists?(name)
printer_reg_key = PRINTERS_REG_KEY + name
Chef::Log.debug "Checking to see if this reg key exists: '#{ printer_reg_key }'"
Registry.key_exists?(printer_reg_key)
end
def create_printer
# Create the printer port first
windows_printer_port new_resource.ipv4_address do
end
port_name = "IP_#{ new_resource.ipv4_address }"
powershell "Creating printer: #{ new_resource.name }" do
code <<-EOH
Set-WmiInstance -class Win32_Printer `
-EnableAllPrivileges `
-Argument @{ DeviceID = "#{ new_resource.device_id }";
Comment = "#{ new_resource.comment }";
Default = "$#{ new_resource.default }";
DriverName = "#{ new_resource.driver_name }";
Location = "#{ new_resource.location }";
PortName = "#{ port_name }";
Shared = "$#{ new_resource.shared }";
ShareName = "#{ new_resource.share_name }";
}
EOH
end
end
def delete_printer
powershell "Deleting printer: #{ new_resource.name }" do
code <<-EOH
$printer = Get-WMIObject -class Win32_Printer -EnableAllPrivileges -Filter "name = '#{ new_resource.name }'"
$printer.Delete()
EOH
end
end

View file

@ -0,0 +1,102 @@
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Provider:: printer_port
#
# Copyright:: 2012, Nordstrom, 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.
#
# Support whyrun
def whyrun_supported?
true
end
action :create do
if @current_resource.exists
Chef::Log.info "#{ @new_resource } already exists - nothing to do."
else
converge_by("Create #{ @new_resource }") do
create_printer_port
end
end
end
action :delete do
if @current_resource.exists
converge_by("Delete #{ @new_resource }") do
delete_printer_port
end
else
Chef::Log.info "#{ @current_resource } doesn't exist - can't delete."
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsPrinterPort.new(@new_resource.name)
@current_resource.name(@new_resource.name)
@current_resource.ipv4_address(@new_resource.ipv4_address)
@current_resource.port_name(@new_resource.port_name || "IP_#{ @new_resource.ipv4_address }")
if port_exists?(@current_resource.port_name)
# TODO: Set @current_resource port properties from registry
@current_resource.exists = true
end
end
private
PORTS_REG_KEY = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\\'
def port_exists?(name)
port_reg_key = PORTS_REG_KEY + name
Chef::Log.debug "Checking to see if this reg key exists: '#{ port_reg_key }'"
Registry.key_exists?(port_reg_key)
end
def create_printer_port
port_name = new_resource.port_name || "IP_#{ new_resource.ipv4_address }"
# create the printer port using PowerShell
powershell "Creating printer port #{ new_resource.port_name }" do
code <<-EOH
Set-WmiInstance -class Win32_TCPIPPrinterPort `
-EnableAllPrivileges `
-Argument @{ HostAddress = "#{ new_resource.ipv4_address }";
Name = "#{ port_name }";
Description = "#{ new_resource.port_description }";
PortNumber = "#{ new_resource.port_number }";
Protocol = "#{ new_resource.port_protocol }";
SNMPEnabled = "$#{ new_resource.snmp_enabled }";
}
EOH
end
end
def delete_printer_port
port_name = new_resource.port_name || "IP_#{ new_resource.ipv4_address }"
powershell "Deleting printer port: #{ new_resource.port_name }" do
code <<-EOH
$port = Get-WMIObject -class Win32_TCPIPPrinterPort -EnableAllPrivileges -Filter "name = '#{ port_name }'"
$port.Delete()
EOH
end
end

View file

@ -0,0 +1,31 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Provider:: reboot
#
# Copyright:: 2011, Opscode, 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.
#
action :request do
node.run_state[:reboot_requested] = true
node.run_state[:reboot_timeout] = @new_resource.timeout
node.run_state[:reboot_reason] = @new_resource.reason
end
action :cancel do
node.run_state.delete(:reboot_requested)
node.run_state.delete(:reboot_timeout)
node.run_state.delete(:reboot_reason)
end

View file

@ -0,0 +1,72 @@
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: registry
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Opscode, Inc.
# Copyright:: 2011, Business Intelligence Associates, 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.
#
include Windows::RegistryHelper
action :create do
registry_update(:create)
end
action :modify do
registry_update(:open)
end
action :force_modify do
require 'timeout'
Timeout.timeout(120) do
@new_resource.values.each do |value_name, value_data|
i = 1
until i > 5 do
desired_value_data = value_data
current_value_data = get_value(@new_resource.key_name.dup, value_name.dup)
if current_value_data.to_s == desired_value_data.to_s
Chef::Log.debug("#{@new_resource} value [#{value_name}] desired [#{desired_value_data}] data already set. Check #{i}/5.")
i+=1
else
Chef::Log.debug("#{@new_resource} value [#{value_name}] current [#{current_value_data}] data not equal to desired [#{desired_value_data}] data. Setting value and restarting check loop.")
begin
registry_update(:open)
rescue Exception
registry_update(:create)
end
i=0 # start count loop over
end
end
end
break
end
end
action :remove do
delete_value(@new_resource.key_name,@new_resource.values)
end
private
def registry_update(mode)
Chef::Log.debug("Registry Mode (#{mode})")
updated = set_value(mode,@new_resource.key_name,@new_resource.values,@new_resource.type)
@new_resource.updated_by_last_action(updated)
end

View file

@ -0,0 +1,56 @@
#
# Author:: Doug MacEachern <dougm@vmware.com>
# Cookbook Name:: windows
# Provider:: shortcut
#
# Copyright:: 2010, VMware, 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.
#
def load_current_resource
require 'win32ole'
@link = WIN32OLE.new("WScript.Shell").CreateShortcut(@new_resource.name)
@current_resource = Chef::Resource::WindowsShortcut.new(@new_resource.name)
@current_resource.name(@new_resource.name)
@current_resource.target(@link.TargetPath)
@current_resource.arguments(@link.Arguments)
@current_resource.description(@link.Description)
@current_resource.cwd(@link.WorkingDirectory)
end
# Check to see if the shorcut needs any changes
#
# === Returns
# <true>:: If a change is required
# <false>:: If the shorcuts are identical
def compare_shortcut
[:target, :arguments, :description, :cwd].any? do |attr|
!@new_resource.send(attr).nil? && @current_resource.send(attr) != @new_resource.send(attr)
end
end
def action_create
if compare_shortcut
@link.TargetPath = @new_resource.target if @new_resource.target != nil
@link.Arguments = @new_resource.arguments if @new_resource.arguments != nil
@link.Description = @new_resource.description if @new_resource.description != nil
@link.WorkingDirectory = @new_resource.cwd if @new_resource.cwd != nil
#ignoring: WindowStyle, Hotkey, IconLocation
@link.Save
Chef::Log.info("Added #{@new_resource} shortcut")
@updated = true
end
end

View file

@ -0,0 +1,124 @@
#
# Author:: Paul Mooring (<paul@opscode.com>)
# Cookbook Name:: windows
# Provider:: task
#
# Copyright:: 2012, Opscode, 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.
#
require 'chef/mixin/shell_out'
include Chef::Mixin::ShellOut
action :create do
if @current_resource.exists
Chef::Log.info "#{@new_resource} task already exists - nothing to do"
else
cmd = "schtasks /Create /TN \"#{@new_resource.name}\" "
cmd += "/SC #{@new_resource.frequency} /MO #{@new_resource.frequency_modifier} "
cmd += "/TR \"#{@new_resource.command}\" "
if @new_resource.user && @new_resource.password
cmd += "/RU \"#{@new_resource.user}\" /RP \"#{@new_resource.password}\" "
elsif (@new_resource.user and !@new_resource.password) || (@new_resource.password and !@new_resource.user)
Chef::Log.fatal "#{@new_resource.name}: Can't specify user or password without both!"
end
cmd += "/RL HIGHEST " if @new_resource.run_level == :highest
shell_out!(cmd, {:returns => [0]})
@new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task created"
end
end
action :run do
if @current_resource.exists
if @current_resource.status == :running
Chef::Log.info "#{@new_resource} task is currently running, skipping run"
else
cmd = "schtasks /Run /TN \"#{@current_resource.name}\""
shell_out!(cmd, {:returns => [0]})
@new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task ran"
end
else
Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do"
end
end
action :change do
if @current_resource.exists
cmd = "schtasks /Change /TN \"#{@current_resource.name}\" "
cmd += "/TR \"#{@new_resource.command}\" " if @new_resource.command
if @new_resource.user && @new_resource.password
cmd += "/RU \"#{@new_resource.user}\" /RP \"#{@new_resource.password}\" "
elsif (@new_resource.user and !@new_resource.password) || (@new_resource.password and !@new_resource.user)
Chef::Log.fatal "#{@new_resource.name}: Can't specify user or password without both!"
end
shell_out!(cmd, {:returns => [0]})
@new_resource.updated_by_last_action true
Chef::Log.info "Change #{@new_resource} task ran"
else
Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do"
end
end
action :delete do
if @current_resource.exists
cmd = "schtasks /Delete /TN \"#{@current_resource.name}\""
shell_out!(cmd, {:returns => [0]})
@new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task deleted"
else
Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do"
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsTask.new(@new_resource.name)
@current_resource.name(@new_resource.name)
task_hash = load_task_hash(@current_resource.name)
if task_hash[:TaskName] == '\\' + @new_resource.name
@current_resource.exists = true
if task_hash[:Status] == "Running"
@current_resource.status = :running
end
@current_resource.cwd(task_hash[:Folder])
@current_resource.command(task_hash[:TaskToRun])
@current_resource.user(task_hash[:RunAsUser])
end if task_hash.respond_to? :[]
end
private
def load_task_hash(task_name)
Chef::Log.debug "looking for existing tasks"
output = `schtasks /Query /FO LIST /V /TN \"#{task_name}\" 2> NUL`
if output.empty?
task = false
else
task = Hash.new
output.split("\n").map! do |line|
line.split(":", 2).map! do |field|
field.strip
end
end.each do |field|
if field.kind_of? Array and field[0].respond_to? :to_sym
task[field[0].gsub(/\s+/,"").to_sym] = field[1]
end
end
end
task
end

View file

@ -0,0 +1,91 @@
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Provider:: unzip
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Opscode, 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.
#
include Windows::Helper
require 'find'
action :unzip do
ensure_rubyzip_gem_installed
Chef::Log.debug("unzip #{@new_resource.source} => #{@new_resource.path} (overwrite=#{@new_resource.overwrite})")
Zip::ZipFile.open(cached_file(@new_resource.source, @new_resource.checksum)) do |zip|
zip.each do |entry|
path = ::File.join(@new_resource.path, entry.name)
FileUtils.mkdir_p(::File.dirname(path))
if @new_resource.overwrite && ::File.exists?(path) && !::File.directory?(path)
FileUtils.rm(path)
end
zip.extract(entry, path)
end
end
@new_resource.updated_by_last_action(true)
end
action :zip do
ensure_rubyzip_gem_installed
# sanitize paths for windows.
@new_resource.source.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
@new_resource.path.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
Chef::Log.debug("zip #{@new_resource.source} => #{@new_resource.path} (overwrite=#{@new_resource.overwrite})")
if @new_resource.overwrite == false && ::File.exists?(@new_resource.path)
Chef::Log.info("file #{@new_resource.path} already exists and overwrite is set to false, exiting")
else
# delete the archive if it already exists, because we are recreating it.
if ::File.exists?(@new_resource.path)
::File.unlink(@new_resource.path)
end
# only supporting compression of a single directory (recursively).
if ::File.directory?(@new_resource.source)
z = Zip::ZipFile.new(@new_resource.path, true)
unless @new_resource.source =~ /::File::ALT_SEPARATOR$/
@new_resource.source << ::File::ALT_SEPARATOR
end
Find.find(@new_resource.source) do |f|
f.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
# don't add root directory to the zipfile.
next if f == @new_resource.source
# strip the root directory from the filename before adding it to the zipfile.
zip_fname = f.sub(@new_resource.source, '')
Chef::Log.debug("adding #{zip_fname} to archive, sourcefile is: #{f}")
z.add(zip_fname, f)
end
z.close
else
Chef::Log.info("Single directory must be specified for compression, and #{@new_resource.source} does not meet that criteria.")
end
end
end
private
def ensure_rubyzip_gem_installed
begin
require 'zip/zip'
rescue LoadError
Chef::Log.info("Missing gem 'rubyzip'...installing now.")
chef_gem "rubyzip" do
version node['windows']['rubyzipversion']
end
require 'zip/zip'
end
end

View file

@ -0,0 +1,34 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Recipe:: default
#
# Copyright:: 2011, Opscode, 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.
#
# gems with precompiled binaries
%w{ win32-api win32-service }.each do |win_gem|
chef_gem win_gem do
options '--platform=mswin32'
action :install
end
end
# the rest
%w{ windows-api windows-pr win32-dir win32-event win32-mutex }.each do |win_gem|
chef_gem win_gem do
action :install
end
end

View file

@ -0,0 +1,32 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Recipe:: restart_handler
#
# Copyright:: 2011, Opscode, 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.
#
remote_directory node['chef_handler']['handler_path'] do
source 'handlers'
recursive true
action :create
end
chef_handler 'WindowsRebootHandler' do
source "#{node['chef_handler']['handler_path']}/windows_reboot_handler.rb"
arguments node['windows']['allow_pending_reboots']
supports :report => true, :exception => false
action :enable
end

View file

@ -0,0 +1,30 @@
#
# Author:: Paul Morotn (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Resource:: auto_run
#
# Copyright:: 2011, Business Intelligence Associates, 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.
#
def initialize(name,run_context=nil)
super
@action = :create
end
actions :create, :remove
attribute :program, :kind_of => String
attribute :name, :kind_of => String, :name_attribute => true
attribute :args, :kind_of => String, :default => ''

View file

@ -0,0 +1,36 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Resource:: batch
#
# Copyright:: 2011, Opscode, 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.
#
actions :run
attribute :command, :kind_of => String, :name_attribute => true
attribute :cwd, :kind_of => String, :default => nil
attribute :code, :kind_of => String, :default => nil
attribute :user, :kind_of => [ String, Integer ], :default => nil
attribute :group, :kind_of => [ String, Integer ], :default => nil
attribute :creates, :kind_of => [ String ], :default => nil
attribute :flags, :kind_of => [ String ], :default => nil
attribute :returns, :kind_of => [Integer, Array], :default => 0
def initialize(name, run_context=nil)
super
@action = :run
@command = name
end

View file

@ -0,0 +1,40 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Resource:: feature
#
# Copyright:: 2011, Opscode, 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.
#
include Windows::Helper
actions :install, :remove
attribute :feature_name, :kind_of => String, :name_attribute => true
def initialize(name, run_context=nil)
super
@action = :install
@provider = lookup_provider_constant(locate_default_provider)
end
private
def locate_default_provider
if ::File.exists?(locate_sysnative_cmd('dism.exe'))
:windows_feature_dism
elsif ::File.exists?(locate_sysnative_cmd('servermanagercmd.exe'))
:windows_feature_servermanagercmd
end
end

View file

@ -0,0 +1,46 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Resource:: package
#
# Copyright:: 2011, Opscode, 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.
#
actions :install, :remove
default_action :install
attribute :package_name, :kind_of => String, :name_attribute => true
attribute :source, :kind_of => String, :required => true
attribute :version, :kind_of => String
attribute :options, :kind_of => String
attribute :installer_type, :kind_of => Symbol, :default => nil, :equal_to => [:msi, :inno, :nsis, :wise, :installshield, :custom]
attribute :checksum, :kind_of => String
attribute :timeout, :kind_of => Integer, :default => 600
attribute :success_codes, :kind_of => Array, :default => [0, 42, 127]
# TODO
# add preseeding support
#attribute :response_file
# allow target dirtory of installation to be set
#attribute :target_dir
# Covers 0.10.8 and earlier
def initialize(*args)
super
@action = :install
end

View file

@ -0,0 +1,29 @@
#
# Author:: Kevin Moser (<kevin.moser@nordstrom.com>)
# Cookbook Name:: windows
# Resource:: pagefile
#
# Copyright:: 2012, Nordstrom, 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.
#
actions :set, :delete
attribute :name, :kind_of => String, :name_attribute => true
attribute :system_managed, :kind_of => [TrueClass, FalseClass]
attribute :automatic_managed, :kind_of => [TrueClass, FalseClass], :default => false
attribute :initial_size, :kind_of => Integer
attribute :maximum_size, :kind_of => Integer
default_action :set

View file

@ -0,0 +1,28 @@
#
# Author:: Paul Morotn (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Resource:: path
#
# Copyright:: 2011, Business Intelligence Associates, 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.
#
def initialize(name,run_context=nil)
super
@action = :add
end
actions :add, :remove
attribute :path, :kind_of => String, :name_attribute => true

View file

@ -0,0 +1,41 @@
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Resource:: printer
#
# Copyright:: 2012, Nordstrom, 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.
#
# See here for more info:
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394492(v=vs.85).aspx
require 'resolv'
actions :create, :delete
default_action :create
attribute :device_id, :kind_of => String, :name_attribute => true,
:required => true
attribute :comment, :kind_of => String
attribute :default, :kind_of => [ TrueClass, FalseClass ], :default => false
attribute :driver_name, :kind_of => String, :required => true
attribute :location, :kind_of => String
attribute :shared, :kind_of => [ TrueClass, FalseClass ], :default => false
attribute :share_name, :kind_of => String
attribute :ipv4_address, :kind_of => String, :regex => Resolv::IPv4::Regex
attr_accessor :exists

View file

@ -0,0 +1,40 @@
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Resource:: printer_port
#
# Copyright:: 2012, Nordstrom, 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.
#
# See here for more info:
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394492(v=vs.85).aspx
require 'resolv'
actions :create, :delete
default_action :create
attribute :ipv4_address, :name_attribute => true, :kind_of => String,
:required => true, :regex => Resolv::IPv4::Regex
attribute :port_name , :kind_of => String
attribute :port_number , :kind_of => Fixnum, :default => 9100
attribute :port_description, :kind_of => String
attribute :snmp_enabled , :kind_of => [ TrueClass, FalseClass ],
:default => false
attribute :port_protocol, :kind_of => Fixnum, :default => 1, :equal_to => [1, 2]
attr_accessor :exists

View file

@ -0,0 +1,29 @@
#
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Resource:: reboot
#
# Copyright:: 2011, Opscode, 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.
#
actions :request, :cancel
attribute :timeout, :kind_of => Integer, :default => 60, :name_attribute => true
attribute :reason, :kind_of => String, :default => ''
def initialize(name,run_context=nil)
super
@action = :request
end

View file

@ -0,0 +1,33 @@
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Resource:: registry
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Opscode, 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.
#
actions :create, :modify, :force_modify, :remove
attribute :key_name, :kind_of => String, :name_attribute => true
attribute :values, :kind_of => Hash
attribute :type, :kind_of => Symbol, :default => nil, :equal_to => [:binary, :string, :multi_string, :expand_string, :dword, :dword_big_endian, :qword]
def initialize(name, run_context=nil)
super
@action = :modify
@key_name = name
end

View file

@ -0,0 +1,35 @@
#
# Author:: Doug MacEachern <dougm@vmware.com>
# Cookbook Name:: windows
# Resource:: shortcut
#
# Copyright:: 2010, VMware, 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.
#
actions :create
default_action :create
attribute :name, :kind_of => String
attribute :target, :kind_of => String
attribute :arguments, :kind_of => String
attribute :description, :kind_of => String
attribute :cwd, :kind_of => String
# Covers 0.10.8 and earlier
def initialize(*args)
super
@action = :create
end

View file

@ -0,0 +1,46 @@
#
# Author:: Paul Mooring (<paul@opscode.com>)
# Cookbook Name:: windows
# Resource:: task
#
# Copyright:: 2012, Opscode, 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.
#
# Passwords can't be loaded for existing tasks, making :modify both confusing
# and not very useful
actions :create, :delete, :run
attribute :name, :kind_of => String, :name_attribute => true
attribute :command, :kind_of => String
attribute :cwd, :kind_of => String
attribute :user, :kind_of => String, :default => nil
attribute :password, :kind_of => String, :default => nil
attribute :run_level, :equal_to => [:highest, :limited], :default => :limited
attribute :frequency_modifier, :kind_of => Integer, :default => 1
attribute :frequency, :equal_to => [:minute,
:hourly,
:daily,
:weekly,
:monthly,
:once,
:on_logon,
:on_idle], :default => :hourly
attr_accessor :exists, :status
def initialize(name, run_context=nil)
super
@action = :create
end

View file

@ -0,0 +1,33 @@
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@opscode.com>)
# Cookbook Name:: windows
# Resource:: unzip
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Opscode, 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.
#
actions :unzip, :zip
attribute :path, :kind_of => String, :name_attribute => true
attribute :source, :kind_of => String
attribute :overwrite, :kind_of => [ TrueClass, FalseClass ], :default => false
attribute :checksum, :kind_of => String
def initialize(name, run_context=nil)
super
@action = :unzip
end