diff --git a/yum/README.md b/yum/README.md new file mode 100644 index 000000000..e2d08f502 --- /dev/null +++ b/yum/README.md @@ -0,0 +1,119 @@ +Description +=========== + +Configures various YUM components on Red Hat-like systems. Includes LWRP for managing repositories and their GPG keys. + +Based on the work done by Eric Wolfe and Charles Duffy on the yumrepo cookbook. http://github.com/atomic-penguin/cookbooks/tree/yumrepo/yumrepo + +Requirements +============ +RHEL, CentOS or Scientific Linux 5.x or newer. It has not been tested on other platforms or earlier versions. RHEL 6 support is untested (testing and patches are welcome). + +Recipes +======= + +default +------- +The default recipe runs `yum update` during the Compile Phase of the Chef run to ensure that the system's package cache is updated with the latest. It is recommended that this recipe appear first in a node's run list (directly or through a role) to ensure that when installing packages, Chef will be able to download the latest version available on the remote YUM repository. + +yum +--- +Manages the configuration of the `/etc/yum.conf` via attributes. + +Resources/Providers +=================== + +key +--- +This LWRP handles importing GPG keys for YUM repositories. Keys can be imported by the `url` parameter or placed in `/etc/pki/rpm-gpg/` by a recipe and then installed with the LWRP without passing the URL. + +# Actions +- :add: installs the GPG key into `/etc/pki/rpm-gpg/` +- :remove: removes the GPG key from `/etc/pki/rpm-gpg/` + +# Attribute Parameters + +- key: name attribute. The name of the GPG key to install. +- url: if the key needs to be downloaded, the URL providing the download. + +# Example + +``` ruby +# add the Zenoss GPG key +yum_key "RPM-GPG-KEY-zenoss" do + url "http://dev.zenoss.com/yum/RPM-GPG-KEY-zenoss" + action :add +end + +# remove Zenoss GPG key +yum_key "RPM-GPG-KEY-zenoss" do + action :remove +end +``` + +repository +---------- +This LWRP provides an easy way to manage additional YUM repositories. GPG keys can be managed with the `key` LWRP. + +# 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 +- description. The description of the repository +- url: The URL providing the packages +- mirrorlist: Default is `false`, if `true` the `url` is considered a list of mirrors +- key: Optional, the name of the GPG key file installed by the `key` LWRP. +- enabled: Default is `1`, set to `0` if the repository is disabled. +- type: Optional, alternate type of repository +- failovermethod: Optional, failovermethod +- bootstrapurl: Optional, bootstrapurl + +# Example + +``` ruby +# add the Zenoss repository +yum_repository "zenoss" do + name "Zenoss Stable repo" + url "http://dev.zenoss.com/yum/stable/" + key "RPM-GPG-KEY-zenoss" + action :add +end + +# remove Zenoss repo +yum_repository "zenoss" do + action :remove +end +``` + +Usage +===== + +Put `recipe[yum]` first in the run list to ensure `yum update` is run before other recipes. You can manage GPG keys either with cookbook_file in a recipe if you want to package it with a cookbook or use the `url` parameter of the `key` LWRP. + +License and Author +================== + +Author:: Eric G. Wolfe + +Copyright:: 2010-2011 + +Author:: Matt Ray () + +Copyright:: 2011 Opscode, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + diff --git a/yum/attributes/default.rb b/yum/attributes/default.rb new file mode 100644 index 000000000..9bf2fc1b1 --- /dev/null +++ b/yum/attributes/default.rb @@ -0,0 +1,23 @@ +# +# Cookbook Name:: yum +# Attributes:: default +# +# Copyright 2011, Eric G. Wolfe +# Copyright 2011, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Example: override.yum.exclude = "kernel* compat-glibc*" +default[:yum][:exclude] +default[:yum][:installonlypkgs] diff --git a/yum/metadata.rb b/yum/metadata.rb new file mode 100644 index 000000000..c453c13ef --- /dev/null +++ b/yum/metadata.rb @@ -0,0 +1,21 @@ +maintainer "Opscode, Inc." +maintainer_email "cookbooks@opscode.com" +license "Apache 2.0" +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version "0.1" +recipe "yum", "Runs 'yum update' during compile phase" +recipe "yum::yum", "manages yum configuration" + +%w{ redhat centos scientific }.each do |os| + supports os, ">= 5.0" +end + +attribute "yum/exclude", + :display_name => "yum.conf exclude", + :description => "List of packages to exclude from updates or installs. This should be a space separated list. Shell globs using wildcards (eg. * and ?) are allowed.", + :required => "optional" + +attribute "yum/installonlypkgs", + :display_name => "yum.conf installonlypkgs", + :description => "List of packages that should only ever be installed, never updated. Kernels in particular fall into this category. Defaults to kernel, kernel-smp, kernel-bigmem, kernel-enterprise, kernel-debug, kernel-unsupported.", + :required => "optional" diff --git a/yum/providers/key.rb b/yum/providers/key.rb new file mode 100644 index 000000000..1e8bcfbab --- /dev/null +++ b/yum/providers/key.rb @@ -0,0 +1,74 @@ +# +# Cookbook Name:: yum +# Provider:: key +# +# Copyright 2010, Tippr Inc. +# Copyright 2011, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +action :add do + unless ::File.exists?("/etc/pki/rpm-gpg/#{new_resource.key}") + Chef::Log.info "Adding #{new_resource.key} GPG key to /etc/pki/rpm-gpg/" + + if node[:platform_version].to_i <= 5 + package "gnupg" + elsif node[:platform_version].to_i >= 6 + package "gnupg2" + end + + execute "rpm --import /etc/pki/rpm-gpg/#{new_resource.key}" do + action :nothing + not_if <<-EOH + function packagenames_for_keyfile() { + local filename="$1" + gpg \ + --with-fingerprint \ + --with-colons \ + --fixed-list-mode \ + "$filename" \ + | gawk -F: '/^pub/ { print tolower(sprintf("gpg-pubkey-%s-%x\\n", substr($5, length($5)-8+1), $6)) }' + } + + for pkgname in $(packagenames_for_keyfile "/etc/pki/rpm-gpg/#{new_resource.key}"); do + if [[ $pkgname ]] && ! rpm -q $pkgname ; then + exit 1; + fi; + done + + exit 0 + EOH + end + + #download the file if necessary + if new_resource.url + remote_file "/etc/pki/rpm-gpg/#{new_resource.key}" do + source new_resource.url + mode "0644" + notifies :run, resources(:execute => "rpm --import /etc/pki/rpm-gpg/#{new_resource.key}"), :immediately + end + end + + end +end + +action :remove do + if ::File.exists?("/etc/pki/rpm-gpg/#{new_resource.key}") + Chef::Log.info "Removing #{new_resource.key} key from /etc/pki/rpm-gpg/" + file "/etc/pki/rpm-gpg/#{new_resource.key}" do + action :delete + end + new_resource.updated_by_last_action(true) + end +end diff --git a/yum/providers/repository.rb b/yum/providers/repository.rb new file mode 100644 index 000000000..f80e34696 --- /dev/null +++ b/yum/providers/repository.rb @@ -0,0 +1,65 @@ +# +# Cookbook Name:: yum +# Provider:: repository +# +# Copyright 2010, Tippr Inc. +# Copyright 2011, Opscode, Inc.. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# note that deletion does not remove GPG keys, either from the repo or +# /etc/pki/rpm-gpg; this is a design decision. + +action :add do + unless ::File.exists?("/etc/yum.repos.d/#{new_resource.repo_name}.repo") + Chef::Log.info "Adding #{new_resource.repo_name} repository to /etc/yum.repos.d/#{new_resource.repo_name}.repo" + #import the gpg key. If it needs to be downloaded or imported from a cookbook + #that can be done in the calling recipe + if new_resource.key then + yum_key new_resource.key + end + #get the metadata + execute "yum -q makecache" do + action :nothing + end + #write out the file + template "/etc/yum.repos.d/#{new_resource.repo_name}.repo" do + cookbook "yum" + source "repo.erb" + mode "0644" + variables({ + :repo_name => new_resource.repo_name, + :description => new_resource.description, + :url => new_resource.url, + :mirrorlist => new_resource.mirrorlist, + :key => new_resource.key, + :enabled => new_resource.enabled, + :type => new_resource.type, + :failovermethod => new_resource.failovermethod, + :bootstrapurl => new_resource.bootstrapurl + }) + notifies :run, resources(:execute => "yum -q makecache"), :immediately + end + end +end + +action :remove do + if ::File.exists?("/etc/yum.repos.d/#{new_resource.repo_name}.repo") + Chef::Log.info "Removing #{new_resource.repo_name} repository from /etc/yum.repos.d/" + file "/etc/yum.repos.d/#{new_resource.repo_name}.repo" do + action :delete + end + new_resource.updated_by_last_action(true) + end +end diff --git a/yum/recipes/default.rb b/yum/recipes/default.rb new file mode 100644 index 000000000..6cf273cdd --- /dev/null +++ b/yum/recipes/default.rb @@ -0,0 +1,20 @@ +# +# Cookbook Name:: yum +# Recipe:: default +# +# Copyright 2011, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +execute "yum update" diff --git a/yum/recipes/yum.rb b/yum/recipes/yum.rb new file mode 100644 index 000000000..584a2ba93 --- /dev/null +++ b/yum/recipes/yum.rb @@ -0,0 +1,23 @@ +# +# Cookbook Name:: yum +# Recipe:: yum +# +# Copyright 2011, Eric G. Wolfe +# Copyright 2011, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +template "/etc/yum.conf" do + source "yum-rhel#{node[:platform_version].to_i}.conf.erb" +end diff --git a/yum/resources/key.rb b/yum/resources/key.rb new file mode 100644 index 000000000..2556a4413 --- /dev/null +++ b/yum/resources/key.rb @@ -0,0 +1,23 @@ +# +# Cookbook Name:: yum +# Resource:: key +# +# Copyright 2011, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +actions :add, :remove + +attribute :key, :kind_of => String, :name_attribute => true +attribute :url, :kind_of => String, :default => nil diff --git a/yum/resources/repository.rb b/yum/resources/repository.rb new file mode 100644 index 000000000..3cf8abf08 --- /dev/null +++ b/yum/resources/repository.rb @@ -0,0 +1,31 @@ +# +# Cookbook Name:: yum +# Resource:: repository +# +# Copyright 2011, Opscode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +actions :add, :remove + +#name of the repo, used for .repo filename +attribute :repo_name, :kind_of => String, :name_attribute => true +attribute :description, :kind_of => String #long description +attribute :url, :kind_of => String +attribute :mirrorlist, :default => false +attribute :key, :kind_of => String, :default => nil +attribute :enabled, :default => 1 +attribute :type, :kind_of => String, :default => nil +attribute :failovermethod, :kind_of => String, :default => nil +attribute :bootstrapurl, :kind_of => String, :default => nil diff --git a/yum/templates/default/repo.erb b/yum/templates/default/repo.erb new file mode 100644 index 000000000..520b511f2 --- /dev/null +++ b/yum/templates/default/repo.erb @@ -0,0 +1,25 @@ +# Generated by Chef for <%= node[:fqdn] %> +# Local modifications will be overwritten. +[<%= @repo_name %>] +name=<%= @description %> +<% if @type %> +type=<%= @type %> +<% end %> +<% if @mirrorlist %> +mirrorlist=<%= @url %> +<% else %> +baseurl=<%= @url %> +<% end %> +<% if @key %> +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/<%= @key %> +<% else %> +gpgcheck=0 +<% end %> +enabled=<%= @enabled %> +<% if @failovermethod %> +failovermethod=<%= @failovermethod %> +<% end %> +<% if @bootstrapurl %> +bootstrapurl=<%= @bootstrapurl %> +<% end %> diff --git a/yum/templates/default/yum-rhel5.conf.erb b/yum/templates/default/yum-rhel5.conf.erb new file mode 100644 index 000000000..467d378db --- /dev/null +++ b/yum/templates/default/yum-rhel5.conf.erb @@ -0,0 +1,28 @@ +# Generated by Chef for <%= node[:fqdn] %> +# Local modifications will be overwritten. +[main] +cachedir=/var/cache/yum +keepcache=0 +debuglevel=2 +logfile=/var/log/yum.log +distroverpkg=redhat-release +tolerant=1 +exactarch=1 +obsoletes=1 +gpgcheck=1 +plugins=1 +<%- if node[:yum][:exclude] %> +exclude=<%= node[:yum][:exclude].join(" ") %> +<%- end %> +<%- if node[:yum][:installonlypkgs] %> +installonlypkgs=<%= node[:yum][:installonlypkgs].join(" ") %> +<%- end %> + +# Note: yum-RHN-plugin doesn't honor this. +metadata_expire=1h + +# Default. +# installonly_limit = 3 + +# PUT YOUR REPOS HERE OR IN separate files named file.repo +# in /etc/yum.repos.d diff --git a/yum/templates/default/yum-rhel6.conf.erb b/yum/templates/default/yum-rhel6.conf.erb new file mode 100644 index 000000000..a5afb56aa --- /dev/null +++ b/yum/templates/default/yum-rhel6.conf.erb @@ -0,0 +1,31 @@ +# Generated by Chef for <%= node[:fqdn] %> +# Local modifications will be overwritten. +[main] +cachedir=/var/cache/yum/$basearch/$releasever +keepcache=0 +debuglevel=2 +logfile=/var/log/yum.log +exactarch=1 +obsoletes=1 +gpgcheck=1 +plugins=1 +installonly_limit=3 +<%- if node[:yum][:exclude] %> +exclude=<%= node[:yum][:exclude].join(" ") %> +<%- end %> +<%- if node[:yum][:installonlypkgs] %> +installonlypkgs=<%= node[:yum][:installonlypkgs].join(" ") %> +<%- end %> + +# This is the default, if you make this bigger yum won't see if the metadata +# is newer on the remote and so you'll "gain" the bandwidth of not having to +# download the new metadata and "pay" for it by yum not having correct +# information. +# It is esp. important, to have correct metadata, for distributions like +# Fedora which don't keep old packages around. If you don't like this checking +# interupting your command line usage, it's much better to have something +# manually check the metadata once an hour (yum-updatesd will do this). +# metadata_expire=90m + +# PUT YOUR REPOS HERE OR IN separate files named file.repo +# in /etc/yum.repos.d