text:
#
# Cookbook Name:: build-essential
# Attributes:: default
#
# 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.
#

case platform
when "mac_os_x"
  case
  when Chef::VersionConstraint.new("~> 10.7.0").include?(platform_version)
    default['build_essential']['osx']['gcc_installer_url'] = "https://github.com/downloads/kennethreitz/osx-gcc-installer/GCC-10.7-v2.pkg"
    default['build_essential']['osx']['gcc_installer_checksum'] = "df36aa87606feb99d0db9ac9a492819e"
  when Chef::VersionConstraint.new("~> 10.6.0").include?(platform_version)
    default['build_essential']['osx']['gcc_installer_url'] = "https://github.com/downloads/kennethreitz/osx-gcc-installer/GCC-10.6.pkg"
    default['build_essential']['osx']['gcc_installer_checksum'] = "d1db5bab6a3f6b9f3b5577a130baeefa"
  end
end


text:
## v1.2.6:

* [COOK-1113] - Use an attribute to determine if upstart is used
* [COOK-1121] - Add support for Windows
* [COOK-1140] - Fix conf.d on Debian
* [COOK-1151] - Fix server_ec2 handling /var/lib/mysql bind mount
* [COOK-1321] - Document setting password attributes for solo

## v1.2.4

* [COOK-992] - fix FATAL nameerror
* [COOK-827] - `mysql:server_ec2` recipe can't mount `data_dir`
* [COOK-945] - FreeBSD support

## v1.2.2

* [COOK-826] mysql::server recipe doesn't quote password string
* [COOK-834] Add 'scientific' and 'amazon' platforms to mysql cookbook

## v1.2.1

* [COOK-644] Mysql client cookbook 'package missing' error message is confusing
* [COOK-645] RHEL6/CentOS6 - mysql cookbook contains 'skip-federated' directive which is unsupported on MySQL 5.1

## v1.2.0

* [COOK-684] remove mysql_database LWRP

## v1.0.8:

* [COOK-633] ensure "cloud" attribute is available

## v1.0.7:

* [COOK-614] expose all mysql tunable settings in config
* [COOK-617] bind to private IP if available

## v1.0.6:

* [COOK-605] install mysql-client package on ubuntu/debian

## v1.0.5:

* [COOK-465] allow optional remote root connections to mysql
* [COOK-455] improve platform version handling
* externalize conf_dir attribute for easier cross platform support
* change datadir attribute to data_dir for consistency

## v1.0.4:

* fix regressions on debian platform
* [COOK-578] wrap root password in quotes
* [COOK-562] expose all tunables in my.cnf

repo_name: michael-romer/zf-boilerplate

repo_language: PHP

mime_type: text/html


text:
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.


text:
maintainer        "Opscode, Inc."
maintainer_email  "cookbooks@opscode.com"
license           "Apache 2.0"
description       "Installs and configures mysql for client or server"
long_description  IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version           "1.2.7"
recipe            "mysql", "Includes the client recipe to configure a client"
recipe            "mysql::client", "Installs packages required for mysql clients using run_action magic"
recipe            "mysql::server", "Installs packages required for mysql servers w/o manual intervention"
recipe            "mysql::server_ec2", "Performs EC2-specific mountpoint manipulation"

%w{ debian ubuntu centos suse fedora redhat scientific amazon freebsd windows }.each do |os|
  supports os
end

depends "openssl"
depends "windows"

attribute "mysql/server_root_password",
  :display_name => "MySQL Server Root Password",
  :description => "Randomly generated password for the mysqld root user",
  :default => "randomly generated"

attribute "mysql/bind_address",
  :display_name => "MySQL Bind Address",
  :description => "Address that mysqld should listen on",
  :default => "ipaddress"

attribute "mysql/data_dir",
  :display_name => "MySQL Data Directory",
  :description => "Location of mysql databases",
  :default => "/var/lib/mysql"

attribute "mysql/conf_dir",
  :display_name => "MySQL Conf Directory",
  :description => "Location of mysql conf files",
  :default => "/etc/mysql"

attribute "mysql/ec2_path",
  :display_name => "MySQL EC2 Path",
  :description => "Location of mysql directory on EC2 instance EBS volumes",
  :default => "/mnt/mysql"

attribute "mysql/tunable",
  :display_name => "MySQL Tunables",
  :description => "Hash of MySQL tunable attributes",
  :type => "hash"

attribute "mysql/tunable/key_buffer",
  :display_name => "MySQL Tuntable Key Buffer",
  :default => "250M"

attribute "mysql/tunable/max_connections",
  :display_name => "MySQL Tunable Max Connections",
  :default => "800"

attribute "mysql/tunable/wait_timeout",
  :display_name => "MySQL Tunable Wait Timeout",
  :default => "180"

attribute "mysql/tunable/net_read_timeout",
  :display_name => "MySQL Tunable Net Read Timeout",
  :default => "30"

attribute "mysql/tunable/net_write_timeout",
  :display_name => "MySQL Tunable Net Write Timeout",
  :default => "30"

attribute "mysql/tunable/back_log",
  :display_name => "MySQL Tunable Back Log",
  :default => "128"

attribute "mysql/tunable/table_cache",
  :display_name => "MySQL Tunable Table Cache for MySQL < 5.1.3",
  :default => "128"

attribute "mysql/tunable/table_open_cache",
  :display_name => "MySQL Tunable Table Cache for MySQL >= 5.1.3",
  :default => "128"

attribute "mysql/tunable/max_heap_table_size",
  :display_name => "MySQL Tunable Max Heap Table Size",
  :default => "32M"

attribute "mysql/tunable/expire_logs_days",
  :display_name => "MySQL Exipre Log Days",
  :default => "10"

attribute "mysql/tunable/max_binlog_size",
  :display_name => "MySQL Max Binlog Size",
  :default => "100M"

attribute "mysql/client",
  :display_name => "MySQL Connector/C Client",
  :description => "Hash of MySQL client attributes",
  :type => "hash"

attribute "mysql/client/version",
  :display_name => "MySQL Connector/C Version",
  :default => "6.0.2"

attribute "mysql/client/arch",
  :display_name => "MySQL Connector/C Architecture",
  :default => "win32"

attribute "mysql/client/package_file",
  :display_name => "MySQL Connector/C Package File Name",
  :default => "mysql-connector-c-6.0.2-win32.msi"

attribute "mysql/client/url",
  :display_name => "MySQL Connector/C Download URL",
  :default => "http://www.mysql.com/get/Downloads/Connector-C/mysql-connector-c-6.0.2-win32.msi/from/http://mysql.mirrors.pair.com/"

attribute "mysql/client/package_name",
  :display_name => "MySQL Connector/C Registry DisplayName",
  :default => "MySQL Connector C 6.0.2"

attribute "mysql/client/basedir",
  :display_name => "MySQL Connector/C Base Install Directory",
  :default => "C:\\Program Files (x86)\\MySQL\\Connector C 6.0.2"

attribute "mysql/client/lib_dir",
  :display_name => "MySQL Connector/C Library Directory (containing libmysql.dll)",
  :default => "C:\\Program Files (x86)\\MySQL\\Connector C 6.0.2\\lib\\opt"

attribute "mysql/client/bin_dir",
  :display_name => "MySQL Connector/C Executable Directory",
  :default => "C:\\Program Files (x86)\\MySQL\\Connector C 6.0.2\\bin"

attribute "mysql/client/ruby_dir",
  :display_name => "Ruby Executable Directory which should gain MySQL support",
  :default => "system ruby"


text:
Description
===========

Installs and configures MySQL client or server.

Requirements
============

Platform
--------

* Debian, Ubuntu
* CentOS, Red Hat, Fedora

Tested on:

* Debian 5.0
* Ubuntu 10.04
* CentOS 5.5

Cookbooks
---------

Requires Opscode's openssl cookbook for secure password generation. See _Attributes_ and _Usage_ for more information.

Requires a C compiler and Ruby development package in order to build mysql gem with native extensions. On Debian and Ubuntu systems this is satisfied by installing the "build-essential" and "ruby-dev" packages before running Chef. See USAGE below for information on how to handle this during a Chef run.

Resources and Providers
=======================

The LWRP that used to ship as part of this cookbook has been refactored into the [database](https://github.com/opscode/cookbooks/tree/master/database) cookbook.  Please see the README for details on updated usage.

Attributes
==========

* `mysql['server_root_password']` - Set the server's root password with this, default is a randomly generated password with `OpenSSL::Random.random_bytes`.
* `mysql['server_repl_password']` - Set the replication user 'repl' password with this, default is a randomly generated password with `OpenSSL::Random.random_bytes`.
* `mysql['server_debian_password']` - Set the debian-sys-maint user password with this, default is a randomly generated password with `OpenSSL::Random.random_bytes`.
* `mysql['bind_address']` - Listen address for MySQLd, default is node's ipaddress.
* `mysql['data_dir']` - Location for mysql data directory, default is "/var/lib/mysql"
* `mysql['conf_dir']` - Location for mysql conf directory, default is "/etc/mysql"
* `mysql['ec2_path']` - location of mysql data_dir on EC2 nodes, default "/mnt/mysql"

Performance tuning attributes, each corresponds to the same-named parameter in my.cnf; default values listed

* `mysql['tunable']['key_buffer']`          = "250M"
* `mysql['tunable']['max_connections']`     = "800"
* `mysql['tunable']['wait_timeout']`        = "180"
* `mysql['tunable']['net_write_timeout']`   = "30"
* `mysql['tunable']['net_write_timeout']`   = "30"
* `mysql['tunable']['back_log']`            = "128"
* `mysql['tunable']['table_cache']`         = "128"
* `mysql['tunable']['max_heap_table_size']` = "32M"
* `mysql['tunable']['expire_logs_days']`    = "10"
* `mysql['tunable']['max_binlog_size']`     = "100M"

Usage
=====

On client nodes, use the client (or default) recipe:

    include_recipe "mysql::client"

This will install the MySQL client libraries and development headers on the system. It will also install the Ruby Gem `mysql`, so that the cookbook's LWRP (above) can be used. This is done during the compile-phase of the Chef run. On platforms that are known to have a native package (currently Debian, Ubuntu, Red hat, Centos, Fedora and SUSE), the package will be installed. Other platforms will use the RubyGem.

This creates a resource object for the package and does the installation before other recipes are parsed. You'll need to have the C compiler and such (ie, build-essential on Ubuntu) before running the recipes, but we already do that when installing Chef :-).

On server nodes, use the server recipe:

    include_recipe "mysql::server"

On Debian and Ubuntu, this will preseed the mysql-server package with the randomly generated root password in the recipe file. On other platforms, it simply installs the required packages. It will also create an SQL file, /etc/mysql/grants.sql, that will be used to set up grants for the root, repl and debian-sys-maint users.

The recipe will perform a `node.save` unless it is run under `chef-solo` after the password attributes are used to ensure that in the event of a failed run, the saved attributes would be used.

**Chef Solo Note**: These node attributes are stored on the Chef server when using `chef-client`. Because `chef-solo` does not connect to a server or save the node object at all, to have the same passwords persist across `chef-solo` runs, you must specify them in the `json_attribs` file used. For example:

    {
      "mysql": {
        "server_root_password": "iloverandompasswordsbutthiswilldo",
        "server_repl_password": "iloverandompasswordsbutthiswilldo",
        "server_debian_password": "iloverandompasswordsbutthiswilldo"
      },
      "run_list":["recipe[mysql::server]"]
    }

On EC2 nodes, use the `server_ec2` recipe and the mysql data dir will be set up in the ephmeral storage.

    include_recipe "mysql::server_ec2"

When the `ec2_path` doesn't exist we look for a mounted filesystem (eg, EBS) and move the data_dir there.

The client recipe is already included by server and 'default' recipes.

For more infromation on the compile vs execution phase of a Chef run:

* http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run

License and Author
==================

Author:: Joshua Timberman (<joshua@opscode.com>)
Author:: AJ Christensen (<aj@opscode.com>)
Author:: Seth Chisamore (<schisamo@opscode.com>)
Author:: Brian Bianco (<brian.bianco@gmail.com>)

Copyright:: 2009-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.


text:
begin
  require 'mysql'
rescue LoadError
  Chef::Log.info("Missing gem 'mysql'")
end

module Opscode
  module Mysql
    module Database
      def db
        @db ||= ::Mysql.new new_resource.host, new_resource.username, new_resource.password
      end
      def close
        @db.close rescue nil
        @db = nil
      end
    end
  end
end


text:
#
# 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.
#

module Opscode
  module Mysql
    module Helpers

      def debian_before_squeeze?
        platform?("debian") && (node.platform_version.to_f < 6.0)
      end

      def ubuntu_before_lucid?
        platform?("ubuntu") && (node.platform_version.to_f < 10.0)
      end

    end
  end
end


text:
#
# Cookbook Name:: mysql
# Recipe:: default
#
# Copyright 2008-2009, 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.attribute?('ec2') && ! FileTest.directory?(node['mysql']['ec2_path']))

  service "mysql" do
    action :stop
  end

  execute "install-mysql" do
    command "mv #{node['mysql']['data_dir']} #{node['mysql']['ec2_path']}"
    not_if do FileTest.directory?(node['mysql']['ec2_path']) end
  end

  [node['mysql']['ec2_path'], node['mysql']['data_dir']].each do |dir|
    directory dir do
      owner "mysql"
      group "mysql"
    end
  end

  mount node['mysql']['data_dir'] do
    device node['mysql']['ec2_path']
    fstype "none"
    options "bind,rw"
    action [:mount, :enable]
  end

  service "mysql" do
    action :start
  end

end


text:
#
# Cookbook Name:: mysql
# Recipe:: client
#
# 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.
#

# Include Opscode helper in Recipe class to get access
# to debian_before_squeeze? and ubuntu_before_lucid?
::Chef::Recipe.send(:include, Opscode::Mysql::Helpers)

mysql_packages = case node['platform']
when "centos", "redhat", "suse", "fedora", "scientific", "amazon"
  %w{mysql mysql-devel}
when "ubuntu","debian"
  if debian_before_squeeze? || ubuntu_before_lucid?
    %w{mysql-client libmysqlclient15-dev}
  else
    %w{mysql-client libmysqlclient-dev}
  end
when "freebsd"
  %w{mysql55-client}
when "windows"
  package_file = node['mysql']['client']['package_file']
  remote_file "#{Chef::Config[:file_cache_path]}/#{package_file}" do
    source node['mysql']['client']['url']
    not_if { File.exists? "#{Chef::Config[:file_cache_path]}/#{package_file}" }
  end

  windows_package node['mysql']['client']['package_name'] do
    source "#{Chef::Config[:file_cache_path]}/#{package_file}"
  end
  windows_path node['mysql']['client']['bin_dir'] do
    action :add
  end
  def package(*args, &blk)
    windows_package(*args, &blk)
  end
  [node['mysql']['client']['package_name']]
else
  %w{mysql-client libmysqlclient-dev}
end

mysql_packages.each do |mysql_pack|
  package mysql_pack do
    action :install
  end
end

if platform?(%w{ redhat centos fedora suse scientific amazon })
  package 'ruby-mysql'
elsif platform?(%w{ debian ubuntu })
  package "libmysql-ruby"
else
  gem_package "mysql" do
    action :install
  end
end

if platform? 'windows'
  ruby_block "copy libmysql.dll into ruby path" do
    block do
      require 'fileutils'
      FileUtils.cp "#{node['mysql']['client']['lib_dir']}\\libmysql.dll", node['mysql']['client']['ruby_dir']
    end
    not_if { File.exist?("#{node['mysql']['client']['ruby_dir']}\\libmysql.dll") }
  end
end


text:
#
# Cookbook Name:: mysql
# 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.
#

::Chef::Recipe.send(:include, Opscode::OpenSSL::Password)

include_recipe "mysql::client"

# generate all passwords
node.set_unless['mysql']['server_debian_password'] = secure_password
node.set_unless['mysql']['server_root_password']   = secure_password
node.set_unless['mysql']['server_repl_password']   = secure_password

if platform?(%w{debian ubuntu})

  directory "/var/cache/local/preseeding" do
    owner "root"
    group node['mysql']['root_group']
    mode 0755
    recursive true
  end

  execute "preseed mysql-server" do
    command "debconf-set-selections /var/cache/local/preseeding/mysql-server.seed"
    action :nothing
  end

  template "/var/cache/local/preseeding/mysql-server.seed" do
    source "mysql-server.seed.erb"
    owner "root"
    group node['mysql']['root_group']
    mode "0600"
    notifies :run, resources(:execute => "preseed mysql-server"), :immediately
  end

  template "#{node['mysql']['conf_dir']}/debian.cnf" do
    source "debian.cnf.erb"
    owner "root"
    group node['mysql']['root_group']
    mode "0600"
  end

end

if platform? 'windows'
  package_file = node['mysql']['package_file']

  remote_file "#{Chef::Config[:file_cache_path]}/#{package_file}" do
    source node['mysql']['url']
    not_if { File.exists? "#{Chef::Config[:file_cache_path]}/#{package_file}" }
  end

  windows_package node['mysql']['package_name'] do
    source "#{Chef::Config[:file_cache_path]}/#{package_file}"
  end

  def package(*args, &blk)
    windows_package(*args, &blk)
  end
end

package node['mysql']['package_name'] do
  action :install
end

directory node['mysql']['confd_dir'] do
  owner "mysql" unless platform? 'windows'
  group "mysql" unless platform? 'windows'
  action :create
  recursive true
end

if platform? 'windows'
  require 'win32/service'

  windows_path node['mysql']['bin_dir'] do
    action :add
  end

  windows_batch "install mysql service" do
    command "\"#{node['mysql']['bin_dir']}\\mysqld.exe\" --install #{node['mysql']['service_name']}"
    not_if { Win32::Service.exists?(node['mysql']['service_name']) }
  end
end

service "mysql" do
  service_name node['mysql']['service_name']
  if node['mysql']['use_upstart']
    restart_command "restart mysql"
    stop_command "stop mysql"
    start_command "start mysql"
  end
  supports :status => true, :restart => true, :reload => true
  action :nothing
end

skip_federated = case node['platform']
                 when 'fedora', 'ubuntu', 'amazon'
                   true
                 when 'centos', 'redhat', 'scientific'
                   node['platform_version'].to_f < 6.0
                 else
                   false
                 end

template "#{node['mysql']['conf_dir']}/my.cnf" do
  source "my.cnf.erb"
  owner "root" unless platform? 'windows'
  group node['mysql']['root_group'] unless platform? 'windows'
  mode "0644"
  notifies :restart, resources(:service => "mysql"), :immediately
  variables :skip_federated => skip_federated
end

unless Chef::Config[:solo]
  ruby_block "save node data" do
    block do
      node.save
    end
    action :create
  end
end

# set the root password on platforms
# that don't support pre-seeding
unless platform?(%w{debian ubuntu})

  execute "assign-root-password" do
    command "\"#{node['mysql']['mysqladmin_bin']}\" -u root password \"#{node['mysql']['server_root_password']}\""
    action :run
    only_if "\"#{node['mysql']['mysql_bin']}\" -u root -e 'show databases;'"
  end

end

grants_path = node['mysql']['grants_path']

begin
  t = resources("template[#{grants_path}]")
rescue
  Chef::Log.info("Could not find previously defined grants.sql resource")
  t = template grants_path do
    source "grants.sql.erb"
    owner "root" unless platform? 'windows'
    group node['mysql']['root_group'] unless platform? 'windows'
    mode "0600"
    action :create
  end
end

if platform? 'windows'
  windows_batch "mysql-install-privileges" do
    command "\"#{node['mysql']['mysql_bin']}\" -u root #{node['mysql']['server_root_password'].empty? ? '' : '-p' }\"#{node['mysql']['server_root_password']}\" < \"#{grants_path}\""
    action :nothing
    subscribes :run, resources("template[#{grants_path}]"), :immediately
  end
else
  execute "mysql-install-privileges" do
    command "\"#{node['mysql']['mysql_bin']}\" -u root #{node['mysql']['server_root_password'].empty? ? '' : '-p' }\"#{node['mysql']['server_root_password']}\" < \"#{grants_path}\""
    action :nothing
    subscribes :run, resources("template[#{grants_path}]"), :immediately
  end
end


text:
#
# Cookbook Name:: mysql
# Recipe:: default
#
# Copyright 2008-2009, 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_recipe "mysql::client"


text:
#
# Cookbook Name:: mysql
# Attributes:: server
#
# Copyright 2008-2009, 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.
#

case node["platform"]
when "windows"
  default['mysql']['client']['version']      = "6.0.2"
  default['mysql']['client']['arch']         = "win32" # force 32 bit to work with mysql gem
  default['mysql']['client']['package_file'] = "mysql-connector-c-#{mysql['client']['version']}-#{mysql['client']['arch']}.msi"
  default['mysql']['client']['url']          = "http://www.mysql.com/get/Downloads/Connector-C/#{mysql['client']['package_file']}/from/http://mysql.mirrors.pair.com/"
  default['mysql']['client']['package_name'] = "MySQL Connector C #{mysql['client']['version']}"

  default['mysql']['client']['basedir']      = "#{ENV['SYSTEMDRIVE']}\\Program Files (x86)\\MySQL\\#{mysql['client']['package_name']}"
  default['mysql']['client']['lib_dir']      = "#{mysql['client']['basedir']}\\lib/opt"
  default['mysql']['client']['bin_dir']      = "#{mysql['client']['basedir']}\\bin"
  default['mysql']['client']['ruby_dir']     = RbConfig::CONFIG['bindir']
end


text:
#
# Cookbook Name:: mysql
# Attributes:: server
#
# Copyright 2008-2009, 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['mysql']['bind_address']               = attribute?('cloud') ? cloud['local_ipv4'] : ipaddress

case node["platform"]
when "centos", "redhat", "fedora", "suse", "scientific", "amazon"
  default['mysql']['package_name']            = "mysql-server"
  default['mysql']['service_name']            = "mysqld"
  default['mysql']['basedir']                 = "/usr"
  default['mysql']['data_dir']                = "/var/lib/mysql"
  default['mysql']['root_group']              = "root"
  default['mysql']['mysqladmin_bin']          = "/usr/bin/mysqladmin"
  default['mysql']['mysql_bin']               = "/usr/bin/mysql"

  set['mysql']['conf_dir']                    = '/etc'
  set['mysql']['confd_dir']                   = '/etc/mysql/conf.d'
  set['mysql']['socket']                      = "/var/lib/mysql/mysql.sock"
  set['mysql']['pid_file']                    = "/var/run/mysqld/mysqld.pid"
  set['mysql']['old_passwords']               = 1
  set['mysql']['grants_path']                 = "/etc/mysql_grants.sql"
when "freebsd"
  default['mysql']['package_name']            = "mysql55-server"
  default['mysql']['service_name']            = "mysql-server"
  default['mysql']['basedir']                 = "/usr/local"
  default['mysql']['data_dir']                = "/var/db/mysql"
  default['mysql']['root_group']              = "wheel"
  default['mysql']['mysqladmin_bin']          = "/usr/local/bin/mysqladmin"
  default['mysql']['mysql_bin']               = "/usr/local/bin/mysql"

  set['mysql']['conf_dir']                    = '/usr/local/etc'
  set['mysql']['confd_dir']                   = '/usr/local/etc/mysql/conf.d'
  set['mysql']['socket']                      = "/tmp/mysqld.sock"
  set['mysql']['pid_file']                    = "/var/run/mysqld/mysqld.pid"
  set['mysql']['old_passwords']               = 0
  set['mysql']['grants_path']                 = "/var/db/mysql/grants.sql"
when "windows"
  default['mysql']['package_name']            = "MySQL Server 5.5"
  default['mysql']['version']                 = '5.5.21'
  default['mysql']['arch']                    = 'win32'
  default['mysql']['package_file']            = "mysql-#{mysql['version']}-#{mysql['arch']}.msi"
  default['mysql']['url']                     = "http://www.mysql.com/get/Downloads/MySQL-5.5/#{mysql['package_file']}/from/http://mysql.mirrors.pair.com/"

  default['mysql']['service_name']            = "mysql"
  default['mysql']['basedir']                 = "#{ENV['SYSTEMDRIVE']}\\Program Files (x86)\\MySQL\\#{mysql['package_name']}"
  default['mysql']['data_dir']                = "#{mysql['basedir']}\\Data"
  default['mysql']['bin_dir']                 = "#{mysql['basedir']}\\bin"
  default['mysql']['mysqladmin_bin']          = "#{mysql['bin_dir']}\\mysqladmin"
  default['mysql']['mysql_bin']               = "#{mysql['bin_dir']}\\mysql"

  default['mysql']['conf_dir']                = "#{mysql['basedir']}"
  default['mysql']['old_passwords']           = 0
  default['mysql']['grants_path']             = "#{mysql['conf_dir']}\\grants.sql"
else
  default['mysql']['package_name']            = "mysql-server"
  default['mysql']['service_name']            = "mysql"
  default['mysql']['basedir']                 = "/usr"
  default['mysql']['data_dir']                = "/var/lib/mysql"
  default['mysql']['root_group']              = "root"
  default['mysql']['mysqladmin_bin']          = "/usr/bin/mysqladmin"
  default['mysql']['mysql_bin']               = "/usr/bin/mysql"

  set['mysql']['conf_dir']                    = '/etc/mysql'
  set['mysql']['confd_dir']                   = '/etc/mysql/conf.d'
  set['mysql']['socket']                      = "/var/run/mysqld/mysqld.sock"
  set['mysql']['pid_file']                    = "/var/run/mysqld/mysqld.pid"
  set['mysql']['old_passwords']               = 0
  set['mysql']['grants_path']                 = "/etc/mysql/grants.sql"
end

if attribute?('ec2')
  default['mysql']['ec2_path']    = "/mnt/mysql"
  default['mysql']['ebs_vol_dev'] = "/dev/sdi"
  default['mysql']['ebs_vol_size'] = 50
end

default['mysql']['use_upstart'] = platform?("ubuntu") && node.platform_version.to_f >= 10.04

default['mysql']['allow_remote_root']               = false
default['mysql']['tunable']['back_log']             = "128"
default['mysql']['tunable']['key_buffer']           = "256M"
default['mysql']['tunable']['max_allowed_packet']   = "16M"
default['mysql']['tunable']['max_connections']      = "800"
default['mysql']['tunable']['max_heap_table_size']  = "32M"
default['mysql']['tunable']['myisam_recover']       = "BACKUP"
default['mysql']['tunable']['net_read_timeout']     = "30"
default['mysql']['tunable']['net_write_timeout']    = "30"
default['mysql']['tunable']['table_cache']          = "128"
default['mysql']['tunable']['table_open_cache']     = "128"
default['mysql']['tunable']['thread_cache']         = "128"
default['mysql']['tunable']['thread_cache_size']    = 8
default['mysql']['tunable']['thread_concurrency']   = 10
default['mysql']['tunable']['thread_stack']         = "256K"
default['mysql']['tunable']['wait_timeout']         = "180"

default['mysql']['tunable']['query_cache_limit']    = "1M"
default['mysql']['tunable']['query_cache_size']     = "16M"

default['mysql']['tunable']['log_slow_queries']     = "/var/log/mysql/slow.log"
default['mysql']['tunable']['long_query_time']      = 2

default['mysql']['tunable']['expire_logs_days']     = 10
default['mysql']['tunable']['max_binlog_size']      = "100M"

default['mysql']['tunable']['innodb_buffer_pool_size']  = "256M"


text:
# Generated by Chef for <%= node['hostname'] %>.
# Local modifications will be overwritten.

<% case node['platform'] -%>
<% when "debian","ubuntu" -%>
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'debian-sys-maint'@'localhost' IDENTIFIED BY '<%= node[:mysql][:server_debian_password] %>' WITH GRANT OPTION;
<% end -%>
# Grant replication for a slave user.
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' identified by '<%= node['mysql']['server_repl_password'] %>';

# Set the server root password. This should be preseeded by the package installation.
<% if node['mysql']['allow_remote_root'] -%>
GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY '<%= node['mysql']['server_root_password'] %>' WITH GRANT OPTION;
<% end -%>
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('<%= node['mysql']['server_root_password'] %>');


text:
[client]
host     = localhost
user     = debian-sys-maint
password = <%= node['mysql']['server_debian_password'] %>
socket   = <%= node['mysql']['socket'] %>

[mysql_upgrade]
host     = localhost
user     = debian-sys-maint
password = <%= node['mysql']['server_debian_password'] %>
socket   = <%= node['mysql']['socket'] %>
basedir  = /usr


text:
# MySQL
-A FWR -p tcp -m tcp --dport 3306 -j ACCEPT
-A FWR -p udp -m udp --dport 3306 -j ACCEPT


text:
#
# Generated by Chef for <%= node['hostname'] %>
#
# Local modifications will be overwritten.
#
# The MySQL database server configuration file.
#
# You can copy this to one of:
# - "/etc/mysql/my.cnf" to set global options,
# - "~/.my.cnf" to set user-specific options.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

# This will be passed to all mysql clients
# It has been reported that passwords should be enclosed with ticks/quotes
# escpecially if they contain "#" chars...
# Remember to edit /etc/mysql/debian.cnf when changing the socket location.
[client]
port            = 3306
socket          = <%= node['mysql']['socket'] %>

# Here is entries for some specific programs
# The following values assume you have at least 32M ram

# This was formally known as [safe_mysqld]. Both versions are currently parsed.
[mysqld_safe]
socket          = <%= node['mysql']['socket'] %>
nice            = 0

[mysqld]
#
# * Basic Settings
#

#
# * IMPORTANT
#   If you make changes to these settings and your system uses apparmor, you may
#   also need to also adjust /etc/apparmor.d/usr.sbin.mysqld.
#

user            = mysql
pid-file        = <%= node['mysql']['pid_file'] %>
socket          = <%= node['mysql']['socket'] %>
port            = 3306
basedir         = <%= node['mysql']['basedir'] %>
datadir         = <%= node['mysql']['data_dir'] %>
tmpdir          = /tmp
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address            = <%= node['mysql']['bind_address'] %>
#
# * Fine Tuning
#
key_buffer              = <%= node['mysql']['tunable']['key_buffer'] %>
max_allowed_packet      = <%= node['mysql']['tunable']['max_allowed_packet'] %>
thread_stack            = <%= node['mysql']['tunable']['thread_stack'] %>
thread_cache_size       = <%= node['mysql']['tunable']['thread_cache_size'] %>
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover          = BACKUP
#max_connections        = 100
#table_cache            = 64
#thread_concurrency     = 10
max_connections         = <%= node['mysql']['tunable']['max_connections'] %>
wait_timeout            = <%= node['mysql']['tunable']['wait_timeout'] %>
net_read_timeout        = <%= node['mysql']['tunable']['net_read_timeout'] %>
net_write_timeout       = <%= node['mysql']['tunable']['net_write_timeout'] %>
back_log                = <%= node['mysql']['tunable']['back_log'] %>
table_cache             = <%= node['mysql']['tunable']['table_cache'] %>
max_heap_table_size     = <%= node['mysql']['tunable']['max_heap_table_size'] %>

#
# * Query Cache Configuration
#
query_cache_limit       = <%= node['mysql']['tunable']['query_cache_limit'] %>
query_cache_size        = <%= node['mysql']['tunable']['query_cache_size'] %>
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
#log            = /var/log/mysql/mysql.log
#
# Error logging goes to syslog. This is a Debian improvement :)
#
# Here you can see queries with especially long duration
log_slow_queries        = <%= node['mysql']['tunable']['log_slow_queries'] %>
long_query_time         = <%= node['mysql']['tunable']['long_query_time'] %>
log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
#       other settings you may need to change.
#server-id              = 1
#log_bin                        = /var/log/mysql/mysql-bin.log
expire_logs_days        = <%= node['mysql']['tunable']['expire_logs_days'] %>
max_binlog_size         = <%= node['mysql']['tunable']['max_binlog_size'] %>
#binlog_do_db           = include_database_name
#binlog_ignore_db       = include_database_name
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
# You might want to disable InnoDB to shrink the mysqld process by circa 100MB.
#skip-innodb
innodb_buffer_pool_size = <%= node['mysql']['tunable']['innodb_buffer_pool_size'] %>

<% if @skip_federated %>
#
# * Federated
#
# The FEDERATED storage engine is disabled since 5.0.67 by default in the .cnf files
# shipped with MySQL distributions (my-huge.cnf, my-medium.cnf, and so forth).
#
skip-federated
<% end %>
#
# * Security Features
#
# Read the manual, too, if you want chroot!
# chroot = /var/lib/mysql/
#
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
#
# ssl-ca=/etc/mysql/cacert.pem
# ssl-cert=/etc/mysql/server-cert.pem
# ssl-key=/etc/mysql/server-key.pem

[mysqldump]
quick
quote-names
max_allowed_packet      = <%= node['mysql']['tunable']['max_allowed_packet'] %>

[mysql]
#no-auto-rehash # faster start of mysql but no tab completition

[isamchk]
key_buffer              = <%= node['mysql']['tunable']['max_allowed_packet'] %>

#
# * NDB Cluster
#
# See /usr/share/doc/mysql-server-*/README.Debian for more information.
#
# The following configuration is read by the NDB Data Nodes (ndbd processes)
# not from the NDB Management Nodes (ndb_mgmd processes).
#
# [MYSQL_CLUSTER]
# ndb-connectstring=127.0.0.1

<% case node['platform'] -%>
<% when "centos", "redhat", "fedora", "suse", "scientific", "amazon"-%>
#
# * BerkeleyDB
#
# Using BerkeleyDB is now discouraged as its support will cease in 5.1.12.
skip-bdb
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords           = <%= node['mysql']['old_passwords'] %>

<% else -%>
#
# * IMPORTANT: Additional settings that can override those from this file!
#   The files must end with '.cnf', otherwise they'll be ignored.
#
!includedir <%= node['mysql']['confd_dir'] %>/
<% end -%>


text:
mysql-server-5.0        mysql-server/root_password_again        select <%= node['mysql']['server_root_password'] %>
mysql-server-5.0        mysql-server/root_password      select <%= node['mysql']['server_root_password'] %>
mysql-server-5.0        mysql-server-5.0/really_downgrade       boolean false
mysql-server-5.0        mysql-server-5.0/need_sarge_compat      boolean false
mysql-server-5.0        mysql-server-5.0/start_on_boot  boolean true
mysql-server-5.0        mysql-server/error_setting_password     boolean false
mysql-server-5.0        mysql-server-5.0/nis_warning    note
mysql-server-5.0        mysql-server-5.0/postrm_remove_databases        boolean false
mysql-server-5.0        mysql-server/password_mismatch  boolean false
mysql-server-5.0        mysql-server-5.0/need_sarge_compat_done boolean true


text:
#
# Generated by Chef for <%= node['hostname'] %>
#
# Local modifications will be overwritten.
#
# The MySQL database server configuration file.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

# This will be passed to all mysql clients
# It has been reported that passwords should be enclosed with ticks/quotes
# escpecially if they contain "#" chars...
[client]
port = 3306

[mysql]
default-character-set = latin1

[mysqld]
#
# * Basic Settings
#
port                      = 3306
basedir                   = <%= node['mysql']['basedir'] %>
datadir                   = <%= node['mysql']['data_dir'] %>
character-set-server      = latin1
default-storage-engine    = INNODB
sql-mode                  = "STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

#
# * Fine Tuning
#
thread_cache_size         = <%= node['mysql']['tunable']['thread_cache_size'] %>
max_connections           = <%= node['mysql']['tunable']['max_connections'] %>
table_cache               = <%= node['mysql']['tunable']['table_cache'] %>
query_cache_size          = <%= node['mysql']['tunable']['query_cache_size'] %>
tmp_table_size            = 5M
myisam_max_sort_file_size = 100G
myisam_sort_buffer_size   = 8M
key_buffer_size           = 8M
read_buffer_size          = 64K
read_rnd_buffer_size      = 256K
sort_buffer_size          = 212K

#
# * InnoDB
#
# Read the manual for more InnoDB related options. There are many!
# You might want to disable InnoDB to shrink the mysqld process by circa 100MB.
#
innodb_additional_mem_pool_size = 2M
innodb_flush_log_at_trx_commit  = 1
innodb_log_buffer_size          = 1M
innodb_buffer_pool_size         = <%= node['mysql']['tunable']['innodb_buffer_pool_size'] %>
innodb_log_file_size            = 10M
innodb_thread_concurrency       = 8


text:
## v1.4.2:

* [COOK-1155] - LWRP for apt pinning

## v1.4.0:

* [COOK-889] - overwrite existing repo source files
* [COOK-921] - optionally use cookbook\_file or remote\_file for key
* [COOK-1032] - fixes problem with apt repository key installation


text:
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.


text:
maintainer        "Opscode, Inc."
maintainer_email  "cookbooks@opscode.com"
license           "Apache 2.0"
description       "Configures apt and apt services and LWRPs for managing apt repositories and preferences"
long_description  IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version           "1.4.2"
recipe            "apt", "Runs apt-get update during compile phase and sets up preseed directories"
recipe            "apt::cacher-ng", "Set up an apt-cacher-ng caching proxy"
recipe            "apt::cacher-client", "Client for the apt::cacher-ng caching proxy"

%w{ ubuntu debian }.each do |os|
  supports os
end


text:
Description
===========

This cookbook includes recipes to execute apt-get update to ensure the
local APT package cache is up to date. There are recipes for managing
the apt-cacher-ng caching proxy and proxy clients. It also includes a
LWRP for managing APT repositories in /etc/apt/sources.list.d as well as
an LWRP for pinning packages via /etc/apt/preferences.d.

Recipes
=======

default
-------

This recipe installs the `update-notifier-common` package to provide
the timestamp file used to only run `apt-get update` if the cache is
more than one day old.

This recipe should appear first in the run list of Debian or Ubuntu
nodes to ensure that the package cache is up to date before managing
any `package` resources with Chef.

This recipe also sets up a local cache directory for preseeding packages.

cacher-ng
---------

Installs the `apt-cacher-ng` package and service so the system can
provide APT caching. You can check the usage report at
http://{hostname}:3142/acng-report.html. The `cacher-ng` recipe
includes the `cacher-client` recipe, so it helps seed itself.

cacher-client
-------------
Configures the node to use the `apt-cacher-ng` server as a client.

Resources/Providers
===================

Managing repositories
---------------------

This LWRP provides an easy way to manage additional APT repositories.
Adding a new repository will notify running the
`execute[apt-get-update]` resource.

# Actions

- :add: creates a repository file and builds the repository listing
- :remove: removes the repository file

# Attribute Parameters

- repo_name: name attribute. The name of the channel to discover
- uri: the base of the Debian distribution
- distribution: this is usually your release's codename...ie something
  like `karmic`, `lucid` or `maverick`
- components: package groupings..when it doubt use `main`
- deb_src: whether or not to add the repository as a source repo as
  well - value can be `true` or `false`, default `false`.
- key_server: the GPG keyserver where the key for the repo should be retrieved
- key: if a `key_server` is provided, this is assumed to be the
  fingerprint, otherwise it can be either the URI to the GPG key for
  the repo, or a cookbook_file.
- cookbook: if key should be a cookbook_file, specify a cookbook where
  the key is located for files/default. Defaults to nil, so it will
  use the cookbook where the resource is used.

# Examples

    # add the Zenoss repo
    apt_repository "zenoss" do
      uri "http://dev.zenoss.org/deb"
      components ["main","stable"]
    end

    # add the Nginx PPA; grab key from keyserver
    apt_repository "nginx-php" do
      uri "http://ppa.launchpad.net/nginx/php5/ubuntu"
      distribution node['lsb']['codename']
      components ["main"]
      keyserver "keyserver.ubuntu.com"
      key "C300EE8C"
    end

    # add the Nginx PPA; grab key from keyserver, also add source repo
    apt_repository "nginx-php" do
      uri "http://ppa.launchpad.net/nginx/php5/ubuntu"
      distribution node['lsb']['codename']
      components ["main"]
      keyserver "keyserver.ubuntu.com"
      key "C300EE8C"
      deb_src true
    end

    # add the Cloudkick Repo
    apt_repository "cloudkick" do
      uri "http://packages.cloudkick.com/ubuntu"
      distribution node['lsb']['codename']
      components ["main"]
      key "http://packages.cloudkick.com/cloudkick.packages.key"
    end

    # add the Cloudkick Repo with the key downloaded in the cookbook
    apt_repository "cloudkick" do
      uri "http://packages.cloudkick.com/ubuntu"
      distribution node['lsb']['codename']
      components ["main"]
      key "cloudkick.packages.key"
    end

    # remove Zenoss repo
    apt_repository "zenoss" do
      action :remove
    end

Pinning packages
----------------

This LWRP provides an easy way to pin packages in /etc/apt/preferences.d.
Although apt-pinning is quite helpful from time to time please note that Debian
does not encourage its use without thorough consideration.

Further information regarding apt-pinning is available via
http://wiki.debian.org/AptPreferences.

# Actions

- :add: creates a preferences file under /etc/apt/preferences.d
- :remove: Removes the file, therefore unpin the package

# Attribute Parameters

- package_name: name attribute. The name of the package
- pin: The package version/repository to pin
- pin_priority: The pinning priority aka "the highest package version wins"

# Examples

    # Pin libmysqlclient16 to version 5.1.49-3
    apt_preference "libmysqlclient16" do
      pin "version 5.1.49-3"
      pin_priority "700"
    end

    # Unpin libmysqlclient16
    apt_preference "libmysqlclient16" do
      action :remove
    end

Usage
=====

Put `recipe[apt]` first in the run list. If you have other recipes
that you want to use to configure how apt behaves, like new sources,
notify the execute resource to run, e.g.:

    template "/etc/apt/sources.list.d/my_apt_sources.list" do
      notifies :run, resources(:execute => "apt-get update"), :immediately
    end

The above will run during execution phase since it is a normal
template resource, and should appear before other package resources
that need the sources in the template.

Put `recipe[apt::cacher-ng]` in the run_list for a server to provide
APT caching and add `recipe[apt::cacher-client]` on the rest of the
Debian-based nodes to take advantage of the caching server.

License and Author
==================

Author:: Joshua Timberman (<joshua@opscode.com>)
Author:: Matt Ray (<matt@opscode.com>)
Author:: Seth Chisamore (<schisamo@opscode.com>)

Copyright 2009-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.


text:
#
# Cookbook Name:: apt
# Resource:: preference
#
# 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.
#

actions :add, :remove

def initialize(*args)
  super
  @action = :add
end

attribute :package_name, :kind_of => String, :name_attribute => true
attribute :pin, :kind_of => String
attribute :pin_priority, :kind_of => String


text:
#
# Cookbook Name:: apt
# Resource:: repository
#
# 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.
#

actions :add, :remove

def initialize(*args)
  super
  @action = :add
end

#name of the repo, used for source.list filename
attribute :repo_name, :kind_of => String, :name_attribute => true
attribute :uri, :kind_of => String
attribute :distribution, :kind_of => String
attribute :components, :kind_of => Array, :default => []
#whether or not to add the repository as a source repo as well
attribute :deb_src, :default => false
attribute :keyserver, :kind_of => String, :default => nil
attribute :key, :kind_of => String, :default => nil
attribute :cookbook, :kind_of => String, :default => nil


text:
#
# Cookbook Name:: apt
# Provider:: preference
#
# 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.
#

# Build preferences.d file contents
def build_pref(package_name, pin, pin_priority)
  preference_content = "Package: #{package_name}\nPin: #{pin}\nPin-Priority: #{pin_priority}\n"
end

action :add do
  new_resource.updated_by_last_action(false)

  preference = build_pref(new_resource.package_name,
                          new_resource.pin,
                          new_resource.pin_priority)

  preference_file = file "/etc/apt/preferences.d/#{new_resource.package_name}" do
    owner "root"
    group "root"
    mode 0644
    content preference
    action :nothing
  end

  # write out the preference file, replace it if it already exists
  preference_file.run_action(:create)
end

action :remove do
  if ::File.exists?("/etc/apt/preferences.d/#{new_resource.package_name}")
    Chef::Log.info "Un-pinning #{new_resource.package_name} from /etc/apt/preferences.d/"
    file "/etc/apt/preferences.d/#{new_resource.package_name}" do
      action :delete
    end
    new_resource.updated_by_last_action(true)
  end
end


text:
#
# Cookbook Name:: apt
# Provider:: repository
#
# 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.
#

# install apt key from keyserver
def install_key_from_keyserver(key, keyserver)
  unless system("apt-key list | grep #{key}")
    execute "install-key #{key}" do
      command "apt-key adv --keyserver #{keyserver} --recv #{key}"
      action :nothing
    end.run_action(:run)
    new_resource.updated_by_last_action(true)
  end
end

# install apt key from URI
def install_key_from_uri(uri)
  key_name = uri.split(/\//).last
  cached_keyfile = "#{Chef::Config[:file_cache_path]}/#{key_name}"
  if (new_resource.key =~ /http/)
    r = remote_file cached_keyfile do
      source new_resource.key
      mode "0644"
      action :nothing
    end
  else
    r = cookbook_file cached_keyfile do
      source new_resource.key
      cookbook new_resource.cookbook
      mode "0644"
      action :nothing
    end
  end

  r.run_action(:create)

  execute "install-key #{key_name}" do
    command "apt-key add #{cached_keyfile}"
    action :nothing
  end.run_action(:run)
  new_resource.updated_by_last_action(true)
end

# build repo file contents
def build_repo(uri, distribution, components, add_deb_src)
  components = components.join(' ') if components.respond_to?(:join)
  repo_info = "#{uri} #{distribution} #{components}\n"
  repo =  "deb     #{repo_info}"
  repo << "deb-src #{repo_info}" if add_deb_src
  repo
end

action :add do
    new_resource.updated_by_last_action(false)

    # add key
    if new_resource.keyserver && new_resource.key
      install_key_from_keyserver(new_resource.key, new_resource.keyserver)
    elsif new_resource.key
      install_key_from_uri(new_resource.key)
    end

    # build repo file
    repository = build_repo(new_resource.uri,
                            new_resource.distribution,
                            new_resource.components,
                            new_resource.deb_src)

    repo_file = file "/etc/apt/sources.list.d/#{new_resource.repo_name}-source.list" do
      owner "root"
      group "root"
      mode 0644
      content repository
      action :nothing
    end

    # write out the repo file, replace it if it already exists
    repo_file.run_action(:create)

    apt_get_update = execute "apt-get update" do
      ignore_failure true
      action :nothing
    end

    if repo_file.updated_by_last_action?
      new_resource.updated_by_last_action(true)
      apt_get_update.run_action(:run)
    end
end

action :remove do
  if ::File.exists?("/etc/apt/sources.list.d/#{new_resource.repo_name}-source.list")
    Chef::Log.info "Removing #{new_resource.repo_name} repository from /etc/apt/sources.list.d/"
    file "/etc/apt/sources.list.d/#{new_resource.repo_name}-source.list" do
      action :delete
    end
    new_resource.updated_by_last_action(true)
  end
end


text:
#
# Cookbook Name:: apt
# Recipe:: cacher-ng
#
# 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.
#

package "apt-cacher-ng" do
  action :install
end

service "apt-cacher-ng" do
  supports :restart => true, :status => false
  action [ :enable, :start ]
end

#this will help seed the proxy
include_recipe "apt::cacher-client"


text:
#
# Cookbook Name:: apt
# Recipe:: default
#
# Copyright 2008-2011, Opscode, Inc.
# Copyright 2009, Bryan McLellan <btm@loftninjas.org>
#
# 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.
#

# Run apt-get update to create the stamp file
execute "apt-get-update" do
  command "apt-get update"
  ignore_failure true
  not_if do ::File.exists?('/var/lib/apt/periodic/update-success-stamp') end
end

# For other recipes to call to force an update
execute "apt-get update" do
  command "apt-get update"
  ignore_failure true
  action :nothing
end

# provides /var/lib/apt/periodic/update-success-stamp on apt-get update
package "update-notifier-common" do
  notifies :run, resources(:execute => "apt-get-update"), :immediately
end

execute "apt-get-update-periodic" do
  command "apt-get update"
  ignore_failure true
  only_if do
    File.exists?('/var/lib/apt/periodic/update-success-stamp') &&
    File.mtime('/var/lib/apt/periodic/update-success-stamp') < Time.now - 86400
  end
end

%w{/var/cache/local /var/cache/local/preseeding}.each do |dirname|
  directory dirname do
    owner "root"
    group "root"
    mode  0644
    action :create
  end
end


text:
#
# Cookbook Name:: apt
# Recipe:: cacher-client
#
# Copyright 2011, 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.
#

#remove Acquire::http::Proxy lines from /etc/apt/apt.conf since we use 01proxy
#these are leftover from preseed installs
execute "Remove proxy from /etc/apt/apt.conf" do
  command "sed --in-place '/^Acquire::http::Proxy/d' /etc/apt/apt.conf"
  only_if "grep Acquire::http::Proxy /etc/apt/apt.conf"
end

servers = []
if node['apt'] && node['apt']['cacher_ipaddress']
  cacher = Chef::Node.new
  cacher.name(node['apt']['cacher_ipaddress'])
  cacher.ipaddress(node['apt']['cacher_ipaddress'])
  servers << cacher
end

servers += search(:node, 'recipes:apt\:\:cacher-ng') unless Chef::Config[:solo]

if servers.length > 0
  Chef::Log.info("apt-cacher-ng server found on #{servers[0]}.")
  proxy = "Acquire::http::Proxy \"http://#{servers[0].ipaddress}:3142\";\n"
  file "/etc/apt/apt.conf.d/01proxy" do
    owner "root"
    group "root"
    mode "0644"
    content proxy
    action :create
  end
else
  Chef::Log.info("No apt-cacher-ng server found.")
  file "/etc/apt/apt.conf.d/01proxy" do
    action :delete
    only_if {File.exists?("/etc/apt/apt.conf.d/01proxy")}
  end
end


text:
[DEFAULT]
;; All times are in seconds, but you can add a suffix
;; for minutes(m), hours(h) or days(d)

;; commented out address so apt-proxy will listen on all IPs
;; address = 127.0.0.1
port = 9999
cache_dir = /var/cache/apt-proxy

;; Control files (Packages/Sources/Contents) refresh rate
min_refresh_delay = 1s
complete_clientless_downloads = 1

;; Debugging settings.
debug = all:4 db:0

time = 30
passive_ftp = on

;;--------------------------------------------------------------
;; Cache housekeeping

cleanup_freq = 1d
max_age = 120d
max_versions = 3

;;---------------------------------------------------------------
;; Backend servers
;;
;; Place each server in its own [section]

[ubuntu]
; Ubuntu archive
backends =
        http://us.archive.ubuntu.com/ubuntu

[ubuntu-security]
; Ubuntu security updates
backends = http://security.ubuntu.com/ubuntu

[debian]
;; Backend servers, in order of preference
backends =
        http://debian.osuosl.org/debian/

[security]
;; Debian security archive
backends =
        http://security.debian.org/debian-security
        http://ftp2.de.debian.org/debian-security


capistrano

maintainer: Opscode, Inc.

license: Apache 2.0

capistrano: Installs Capistrano gem

description: Installs Capistrano gem and provides a define to set up deployment for an application


text:
maintainer        "Opscode, Inc."
maintainer_email  "cookbooks@opscode.com"
license           "Apache 2.0"
description       "Installs Capistrano gem and provides a define to set up deployment for an application"
version           "0.7.1"
recipe            "capistrano", "Installs Capistrano gem"
%w{ ubuntu debian redhat centos fedora freebsd openbsd }.each do |os|
  supports os
end


text:
DESCRIPTION
===========

Installs capistrano RubyGem and provides a definition to set up directory structure to perform capistrano deployment.

This cookbook is not necessary when using the Opscode application cookbook.

RECIPES
=======

The default recipe merely installs the capistrano RubyGem.

DEFINITIONS
===========

cap_setup
---------

The `cap_setup` definition will create the deployment directory structure for deploying applications with capistrano. For example to use the definition:

    cap_setup "my_app" do
      path "/srv/my_app"
      owner "nobody"
      group "nogroup"
      appowner "nobody"
    end

This will create the following directory structure:

    /srv/my_app
    /srv/my_app/releases
    /srv/my_app/shared
    /srv/my_app/shared/log
    /srv/my_app/shared/system

LICENSE AND AUTHOR
==================

Author:: Joshua Timberman (<joshua@opscode.com>)

Copyright 2009, 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.


text:
#
# Cookbook Name:: capistrano
# Definition:: cap_setup
#
# Copyright 2009, 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.
#

define :cap_setup, :path => nil, :owner => "root", :group => "root", :appowner => "nobody" do
  include_recipe "capistrano"

  directory params[:path] do
    owner params[:owner]
    group params[:group]
    mode 0755
  end

  # after chef-174 fixed, change mode to 2775
  %w{ releases shared }.each do |dir|
    directory "#{params[:path]}/#{dir}" do
      owner params[:owner]
      group params[:group]
      mode 0775
    end
  end

  %w{ log system }.each do |dir|
    directory "#{params[:path]}/shared/#{dir}" do
      owner params[:appowner]
      group params[:group]
      mode 0775
    end
  end

end


text:
#
# Cookbook Name:: capistrano
# Recipe:: default
#
# Copyright 2009, 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.
#

gem_package "capistrano"


text:
## 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


text:
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.5.1"

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 freebsd }.each do |os|
  supports os
end


text:
Description
===========

Installs a Java. Uses OpenJDK by default but supports installation of Oracle's JDK.

This cookbook also provides the `java_ark` LWRP which other java
cookbooks can use to install java-related applications from binary
packages.

The `java_ark` LWPR may move to its own cookbook at some point in the
future as its functionality is useful for other purposes.

**IMPORTANT NOTE** As of 26 March 2012 you can no longer directly download
the JDK from Oracle's website without using a full-fledged browser.
For that reason, the java::oracle recipe forces you to set up a
private repository accessible by HTTP. It is best to override the
dummy URL using a role.

Example

roles/base.rb

    normal_attributes(
      :java => {
        :jdk => {
          "6" => {
            :x86_64 => {
              :url => "http://hqlprrepo01.hq.un.fao.org/corporate/jdk-6u30-linux-x64.bin"
            }
          }
        }
      }
    )

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

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`

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.

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.

Resources/Providers
===================

This LWRP provides an easy way to manage java applications. It uses
the LWRP arkive (deliberately misspelled). It is an arkive and not an
"archive" because the `java_ark` lwrp is not the same as a java
archive or "jar". Essentially, you provide the `java_ark` with the URL
to a tarball and the commands within the extracted result that you
want symlinked to /usr/bin/

The `java_ark` LWPR may move to its own cookbook at some point in the
future as its functionality is useful for other purposes.

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

    # installs maven2
    java_ark "maven2" do
        url "http://www.apache.org/dist/maven/binaries/apache-maven-2.2.1-bin.tar.gz"
        checksum  "b9a36559486a862abfc7fb2064fd1429f20333caae95ac51215d06d72c02d376"
        app_home "/usr/local/maven/default"
        bin_cmds ["mvn"]
        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]"
    )

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.


text:
#
# 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 => /^http:\/\/.*(tar.gz|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

# 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


text:
#
# 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 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(/(.tar.gz|.zip)/)[0]
    app_dir_name = app_dir_name.split("-bin")[0]
  end
  [app_dir_name, file_name]
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 = app_dir
  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)
      FileUtils.mkdir app_root, :mode => new_resource.app_home_mode
      FileUtils.chown new_resource.owner, new_resource.owner, app_root
    end

    r = remote_file "#{Chef::Config[:file_cache_path]}/#{tarball_name}" do
      source new_resource.url
      checksum new_resource.checksum
      mode 0755
      action :nothing
    end
    r.run_action(:create_if_missing)

    require 'tmpdir'

    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/
      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
    new_resource.updated_by_last_action(true)
  end

  #update-alternatives
  if new_resource.default
    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
      Chef::Log.debug "symlinking #{app_dir} to #{app_home}"
      FileUtils.rm_f app_home
      FileUtils.ln_sf app_dir, app_home
    end
    if new_resource.bin_cmds
      new_resource.bin_cmds.each do |cmd|
        if ::File.exists? "/usr/bin/#{cmd}"
          current_bin_link = ::File.readlink("/usr/bin/#{cmd}")
        else
          current_bin_link = false
        end
        should_be_link = "#{app_home}/bin/#{cmd}"
        if current_bin_link != should_be_link
          cmd = Chef::ShellOut.new(
                                   %Q[ update-alternatives --install /usr/bin/#{cmd} #{cmd} #{app_home}/bin/#{cmd} 1;
                                       update-alternatives --set #{cmd} #{app_home}/bin/#{cmd}  ]
                                   ).run_command
          unless cmd.exitstatus == 0
            Chef::Application.fatal!(%Q[ update alternatives  failed ])
          end
        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
      cmd.run_action(:run)
    end
    Chef::Log.info "Removing #{new_resource.name} at #{app_dir}"
    FileUtils.rm_rf app_dir
    new_resource.updated_by_last_action(true)
  end
end


text:
# 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.

version = node['java']['jdk_version']
java_home = node['java']['java_home']
java_home_parent = ::File.dirname java_home
jdk_home = ""

pkgs = value_for_platform(
  ["centos","redhat","fedora","scientific","amazon"] => {
    "default" => ["java-1.#{version}.0-openjdk","java-1.#{version}.0-openjdk-devel"]
  },
  ["arch","freebsd"] => {
    "default" => ["openjdk#{version}"]
  },
  "default" => ["openjdk-#{version}-jdk"]
  )

# done by special request for rberger
ruby_block  "set-env-java-home" do
  block do
    ENV["JAVA_HOME"] = java_home
  end
end

if platform?("ubuntu","debian","redhat","centos","fedora","scientific","amazon")
  ruby_block "update-java-alternatives" do
    block do
      if platform?("ubuntu", "debian") and version == 6
        run_context = Chef::RunContext.new(node, {})
        r = Chef::Resource::Execute.new("update-java-alternatives", run_context)
        r.command "update-java-alternatives -s java-6-openjdk"
        r.returns [0,2]
        r.run_action(:create)
      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"
        arch = node['kernel']['machine'] =~ /x86_64/ ? "x86_64" : "i386"
        arch = 'amd64' if arch == 'x86_64' && node["platform_version"].to_f >= 12.04
        Chef::Log.debug("glob is #{java_home_parent}/java*#{version}*openjdk*")
        jdk_home = Dir.glob("#{java_home_parent}/java*#{version}*openjdk{,[-\.]#{arch}}")[0]
        Chef::Log.debug("jdk_home is #{jdk_home}")
        # delete the symlink if it already exists
        if ::File.exists? java_home
          FileUtils.rm_f java_home
        end
        FileUtils.ln_sf jdk_home, java_home

        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]"  if platform?("ubuntu","debian","redhat","centos","fedora","scientific","amazon")
  end
end


text:
#
# 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']
when "7"
  tarball_url = node['java']['jdk']['7'][arch]['url']
  tarball_checksum = node['java']['jdk']['7'][arch]['checksum']
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
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 ["java"]
  action :install
end


text:
#
# 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']
when "7"
  tarball_url = node['java']['jdk']['7']['i586']['url']
  tarball_checksum = node['java']['jdk']['7']['i586']['checksum']
end

ruby_block  "set-env-java-home" do
  block do
    ENV["JAVA_HOME"] = java_home
  end
end

yum_package "glibc" do
  arch "i686"
#  provider Chef::Provider::Package::Yum
end

java_ark "jdk-alt" do
  url tarball_url
  checksum tarball_checksum
  app_home java_home
  default false
  action :install
end


text:
#
# 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.
#

include_recipe "java::#{node['java']['install_flavor']}"

# 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


text:
#
# 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"
  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"
else
  default['java']['java_home'] = "/usr/lib/jvm/default-java"
end

# jdk6 attributes
# x86_64
default['java']['jdk']['6']['x86_64']['url'] = 'http://download.example.com/otn-pub/java/jdk/6u30-b12/jdk-6u30-linux-x64.bin'
default['java']['jdk']['6']['x86_64']['checksum'] = '928220f4e46c5dabef0440791c48023945629d8a23998e072157e04960d8a759'

# i586
default['java']['jdk']['6']['i586']['url'] = 'http://download.example.com/otn-pub/java/jdk/6u30-b12/jdk-6u30-linux-i586.bin'
default['java']['jdk']['6']['i586']['checksum'] = 'b551be83a690bc9fec0107d9aa4f828cd47e150fa54cbedbfa8f80c99e2f18b5'

# jdk7 attributes
# x86_64
default['java']['jdk']['7']['x86_64']['url'] = 'http://download.example.com/otn-pub/java/jdk/7u2-b13/jdk-7u2-linux-x64.tar.gz'
default['java']['jdk']['7']['x86_64']['checksum'] = '411a204122c5e45876d6edae1a031b718c01e6175833740b406e8aafc37bc82d'

# i586
default['java']['jdk']['7']['i586']['url'] = 'http://download.example.com/otn-pub/java/jdk/7u2-b13/jdk-7u2-linux-i586.tar.gz'
default['java']['jdk']['7']['i586']['checksum'] = '74faad48fef2c368276dbd1fd6c02520b0e9ebdcb1621916c1af345fc3ba65d1'


text:
= DESCRIPTION:

= REQUIREMENTS:

= ATTRIBUTES:

= USAGE:


maintainer: fredz

description: Install Basic Netwoking Tools ans Utilities on Debian5 and Ubuntu10

long_description:
= DESCRIPTION:

= REQUIREMENTS:

= ATTRIBUTES:

= USAGE:


text:
maintainer       "fredz"
maintainer_email "fred@frederico-araujo.com"
license          "Apache 2.0"
description      "Install Basic Netwoking Tools ans Utilities on Debian5 and Ubuntu10"
long_description IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
version          "0.0.2"

%w{ ubuntu debian }.each do |os|
  supports os
end


text:
#
# Cookbook Name:: debian_basic
# Recipe:: default
#
# Copyright 2010, fredz
#
# All rights reserved - Do Not Redistribute
#

packages = [
  'lsof',
  'iptables',
  'jwhois',
  'whois',
  'curl',
  'wget',
  'rsync',
  'jnettop',
  'nmap',
  'traceroute',
  'ethtool',
  'iproute',
  'iputils-ping',
  'netcat-openbsd',
  'tcpdump',
  'elinks',
  'lynx'
]

case node[:platform]
  when "debian", "ubuntu"
    packages.each do |pkg|
      package pkg do
        action :install
    end
  end
end


ant

description: Installs/Configures ant

long_description:
Description
===========

Installs and configures Apache Ant & Ivy

Requirements
============

Platform:

* Debian, Ubuntu, CentOS, Red Hat, Fedora

The following Opscode cookbooks are dependencies:

* java
* jpackage

Attributes
==========

Usage
=====

Simply include the recipe where you want Apache Ant & Ivy installed.

TODO
====

* plugin support
* global config template - /etc/ant/ant.conf

License and Author
==================

Author:: Seth Chisamore (<schisamo@opscode.com>)

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.

ant::default: Installs and configures Ant


text:
maintainer       "Opscode, Inc."
maintainer_email "cookbooks@opscode.com"
license          "Apache 2.0"
description      "Installs/Configures ant"
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version          "0.10.1"
%w{ java jpackage }.each do |cb|
  depends cb
end
%w{ debian ubuntu centos redhat fedora }.each do |os|
  supports os
end

recipe "ant::default", "Installs and configures Ant"


text:
Description
===========

Installs and configures Apache Ant & Ivy

Requirements
============

Platform:

* Debian, Ubuntu, CentOS, Red Hat, Fedora

The following Opscode cookbooks are dependencies:

* java
* jpackage

Attributes
==========

Usage
=====

Simply include the recipe where you want Apache Ant & Ivy installed.

TODO
====

* plugin support
* global config template - /etc/ant/ant.conf

License and Author
==================

Author:: Seth Chisamore (<schisamo@opscode.com>)

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.


text:
#
# Cookbook Name:: ant
# Recipe:: 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.
#

include_recipe "java"

case node.platform
when "centos","redhat","fedora"
  include_recipe "jpackage"
end

ant_pkgs = value_for_platform(
  ["debian","ubuntu",] => {
    "default" => ["ant","ant-contrib","ivy"]
  },
  ["centos","redhat","fedora" ] => {
    "default" => ["ant","ant-contrib","ivy"]
  },
  "default" => ["ant","ant-contrib","ivy"]
)

ant_pkgs.each do |pkg|
  package pkg do
    action :install
  end
end


text:
## v1.0.2:

* [COOK-993] Add mhash-devel to centos php source libs
* [COOK-989] - bump version of php to 5.3.10
* Also download the .tar.gz instead of .tar.bz2 as bzip2 may not be in
  the base OS (e.g., CentOS 6 minimal)


text:
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.


text:
maintainer        "Opscode, Inc."
maintainer_email  "cookbooks@opscode.com"
license           "Apache 2.0"
description       "Installs and maintains php and php modules"
version           "1.0.2"

depends "build-essential"
depends "xml"
depends "mysql"

%w{ debian ubuntu centos redhat fedora }.each do |os|
  supports os
end

recipe "php", "Installs php"
recipe "php::package", "Installs php using packages."
recipe "php::source", "Installs php from source."
recipe "php::module_apc", "Install the php5-apc package"
recipe "php::module_curl", "Install the php5-curl package"
recipe "php::module_fileinfo", "Install the php5-fileinfo package"
recipe "php::module_fpdf", "Install the php-fpdf package"
recipe "php::module_gd", "Install the php5-gd package"
recipe "php::module_ldap", "Install the php5-ldap package"
recipe "php::module_memcache", "Install the php5-memcache package"
recipe "php::module_mysql", "Install the php5-mysql package"
recipe "php::module_pgsql", "Install the php5-pgsql packag"
recipe "php::module_sqlite3", "Install the php5-sqlite3 package"