summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CBGB.md2
-rw-r--r--acceptance/Gemfile6
-rw-r--r--acceptance/README.md13
-rw-r--r--acceptance/cookbook-git/.acceptance/acceptance-cookbook/.gitignore2
-rw-r--r--acceptance/cookbook-git/.acceptance/acceptance-cookbook/libraries/init.rb19
-rw-r--r--acceptance/cookbook-git/.acceptance/acceptance-cookbook/metadata.rb1
-rw-r--r--acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/destroy.rb5
-rw-r--r--acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/provision.rb15
-rw-r--r--acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/verify.rb5
-rw-r--r--acceptance/cookbook-git/.gitignore1
-rw-r--r--acceptance/cookbook-git/.kitchen.digitalocean.yml21
-rw-r--r--acceptance/cookbook-git/.kitchen.ec2.yml288
-rw-r--r--acceptance/cookbook-git/.kitchen.vagrant.yml72
-rw-r--r--acceptance/trivial/.kitchen.yml2
-rw-r--r--chef.gemspec2
-rw-r--r--lib/chef/property.rb3
-rw-r--r--lib/chef/provider/package/zypper.rb95
-rw-r--r--spec/functional/resource/user/useradd_spec.rb8
-rw-r--r--spec/integration/recipes/resource_action_spec.rb70
-rw-r--r--spec/unit/provider/package/zypper_spec.rb78
-rw-r--r--tasks/cbgb.rb2
21 files changed, 599 insertions, 111 deletions
diff --git a/CBGB.md b/CBGB.md
index b8ab2e80e7..2ce26fc3ab 100644
--- a/CBGB.md
+++ b/CBGB.md
@@ -9,7 +9,7 @@
More information can be found in the [Chef Board of Governance RFC](Chef Board of Governance).
-# Board of Governers
+# Board of Governors
## Project Lead
diff --git a/acceptance/Gemfile b/acceptance/Gemfile
index 70d99492dd..f9a0b5497e 100644
--- a/acceptance/Gemfile
+++ b/acceptance/Gemfile
@@ -1,10 +1,12 @@
source "https://rubygems.org"
gem "mixlib-install", github: "chef/mixlib-install"
+gem "chef", path: ".."
gem "chef-acceptance", github: "chef/chef-acceptance"
-gem "test-kitchen", github: "sersut/test-kitchen",
- branch: "sersut/mixlib-install-update"
+gem "test-kitchen", github: "sersut/test-kitchen", branch: "sersut/mixlib-install-update"
+gem "kitchen-ec2"
gem "kitchen-inspec"
gem "kitchen-vagrant"
gem "windows_chef_zero"
gem "winrm-transport"
+gem "berkshelf"
diff --git a/acceptance/README.md b/acceptance/README.md
index 5f6bfc45ba..8f957debb2 100644
--- a/acceptance/README.md
+++ b/acceptance/README.md
@@ -16,15 +16,22 @@ export APPBUNDLER_ALLOW_RVM=true
### Setting up and running a test suite
To get started, do a bundle install from the acceptance directory:
```shell
-chef/acceptance$ bundle install
+chef/acceptance$ bundle install --binstubs
```
To get some basic info and ensure chef-acceptance can be run, do:
```shell
-chef/acceptance$ bundle exec chef-acceptance info
+chef/acceptance$ bin/chef-acceptance info
```
To run a particular test suite, do the following:
```shell
-chef/acceptance$ bundle exec chef-acceptance test TEST_SUITE
+chef/acceptance$ bin/chef-acceptance test TEST_SUITE
+```
+
+To restrict which OS's will run, use the KITCHEN_INSTANCES environment variable:
+
+```shell
+chef/acceptance$ export KITCHEN_INSTANCES=*-ubuntu-1404
+chef/acceptance$ bin/chef-acceptance test cookbook-git
```
diff --git a/acceptance/cookbook-git/.acceptance/acceptance-cookbook/.gitignore b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/.gitignore
new file mode 100644
index 0000000000..041413b040
--- /dev/null
+++ b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/.gitignore
@@ -0,0 +1,2 @@
+nodes/
+tmp/
diff --git a/acceptance/cookbook-git/.acceptance/acceptance-cookbook/libraries/init.rb b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/libraries/init.rb
new file mode 100644
index 0000000000..d40d6672e7
--- /dev/null
+++ b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/libraries/init.rb
@@ -0,0 +1,19 @@
+module CookbookGit
+ def self.test_cookbook_name
+ "git"
+ end
+
+ def self.test_run_path
+ File.join(Chef.node["chef-acceptance"]["suite-dir"], "test_run")
+ end
+
+ def self.acceptance_path
+ File.expand_path("..", Chef.node["chef-acceptance"]["suite-dir"])
+ end
+
+ def self.acceptance_gemfile
+ File.join(acceptance_path, "Gemfile")
+ end
+end
+
+ENV["KITCHEN_LOCAL_YAML"] ||= File.join(Chef.node["chef-acceptance"]["suite-dir"], ".kitchen.#{ENV["KITCHEN_DRIVER"] || "vagrant"}.yml")
diff --git a/acceptance/cookbook-git/.acceptance/acceptance-cookbook/metadata.rb b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/metadata.rb
new file mode 100644
index 0000000000..4c7c42d9bd
--- /dev/null
+++ b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/metadata.rb
@@ -0,0 +1 @@
+name 'acceptance-cookbook'
diff --git a/acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/destroy.rb b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/destroy.rb
new file mode 100644
index 0000000000..faf9a87a86
--- /dev/null
+++ b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/destroy.rb
@@ -0,0 +1,5 @@
+# Run the test on the current platform
+execute "bundle exec kitchen destroy #{ENV['KITCHEN_INSTANCES']}" do
+ cwd "#{CookbookGit.test_run_path}/#{CookbookGit.test_cookbook_name}"
+ env "BUNDLE_GEMFILE" => CookbookGit.acceptance_gemfile
+end
diff --git a/acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/provision.rb b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/provision.rb
new file mode 100644
index 0000000000..878de27f54
--- /dev/null
+++ b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/provision.rb
@@ -0,0 +1,15 @@
+# Grab the cookbook
+directory CookbookGit.test_run_path
+
+# TODO Grab the source URL from supermarket
+# TODO get git to include its kitchen tests in the cookbook.
+git "#{CookbookGit.test_run_path}/#{CookbookGit.test_cookbook_name}" do
+ repository "https://github.com/jkeiser/#{CookbookGit.test_cookbook_name}.git"
+ branch "jk/windows-fix"
+end
+
+# Run the test on the current platform
+execute "bundle exec kitchen converge #{ENV['KITCHEN_INSTANCES']} -c" do
+ cwd "#{CookbookGit.test_run_path}/#{CookbookGit.test_cookbook_name}"
+ env "BUNDLE_GEMFILE" => CookbookGit.acceptance_gemfile
+end
diff --git a/acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/verify.rb b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/verify.rb
new file mode 100644
index 0000000000..55b362d131
--- /dev/null
+++ b/acceptance/cookbook-git/.acceptance/acceptance-cookbook/recipes/verify.rb
@@ -0,0 +1,5 @@
+# Run tests on the current platform
+execute "bundle exec kitchen verify #{ENV['KITCHEN_INSTANCES']} -c" do
+ cwd "#{CookbookGit.test_run_path}/#{CookbookGit.test_cookbook_name}"
+ env "BUNDLE_GEMFILE" => CookbookGit.acceptance_gemfile
+end
diff --git a/acceptance/cookbook-git/.gitignore b/acceptance/cookbook-git/.gitignore
new file mode 100644
index 0000000000..306f0cce57
--- /dev/null
+++ b/acceptance/cookbook-git/.gitignore
@@ -0,0 +1 @@
+test_run/
diff --git a/acceptance/cookbook-git/.kitchen.digitalocean.yml b/acceptance/cookbook-git/.kitchen.digitalocean.yml
new file mode 100644
index 0000000000..29733210c7
--- /dev/null
+++ b/acceptance/cookbook-git/.kitchen.digitalocean.yml
@@ -0,0 +1,21 @@
+# Not quite ready yet
+
+driver:
+ name: digitalocean
+ digitalocean_access_token: <%= ENV['DIGITALOCEAN_API_TOKEN'] %>
+ region: <%= ENV['DIGITALOCEAN_REGION'] %>
+ size: 2gb
+ ssh_key_ids: <%= ENV['DIGITALOCEAN_SSH_KEYS'] %>
+ transport:
+ ssh_key: <%= ENV['DIGITALOCEAN_SSH_KEY_PATH'] %>
+
+platforms:
+<% %w(centos-6.5 centos-7.0
+ fedora-21
+ debian-8.1
+ ubuntu-12.04 ubuntu-14.04 ubuntu-15.10
+).each do |platform| %>
+ - name: #{platform}
+ driver_config:
+ image: <%= "#{platform.gsub('.', '-')}-x64" %>
+<% end %>
diff --git a/acceptance/cookbook-git/.kitchen.ec2.yml b/acceptance/cookbook-git/.kitchen.ec2.yml
new file mode 100644
index 0000000000..61413ea5ff
--- /dev/null
+++ b/acceptance/cookbook-git/.kitchen.ec2.yml
@@ -0,0 +1,288 @@
+# Not quite ready yet
+
+<%
+def file_if_exists(path)
+ path = File.expand_path(path)
+ File.exist?(path) ? path : nil
+end
+%>
+
+driver:
+ name: ec2
+ tags:
+ X-Project: Kitchen Tests
+ aws_ssh_key_id: <%= ENV['AWS_SSH_KEY_ID'] || ENV['USER'] %>
+ transport:
+ ssh_key: <%= file_if_exists("~/.ssh/#{ENV['AWS_SSH_KEY_ID'] || ENV['USERNAME']}.pem") ||
+ file_if_exists("~/.ssh/#{ENV['AWS_SSH_KEY_ID'] || ENV['USERNAME']}")
+ file_if_exists("~/.ssh/id_rsa") %>
+ # test-specific stuff
+ region: us-west-2
+ availability_zone: a
+ subnet_id: subnet-19ac017c
+ security_group_ids: ["sg-e401eb83", "sg-96274af3"]
+ instance_type: m3.large
+ associate_public_ip: true
+
+platforms:
+ #
+ # AIX
+ #
+ # - name: aix-6.1
+ # - name: aix-7.1
+ #
+ # Debian
+ #
+ - name: debian-8
+ driver:
+ image_search:
+ name: debian-jessie-*
+ owner-id: 379101102735
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: admin
+ - name: debian-7
+ driver:
+ image_search:
+ name: debian-wheezy-*
+ owner-id: 379101102735
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: standard
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: admin
+ #
+ # Ubuntu
+ #
+ - name: ubuntu-15.10
+ driver:
+ image_search:
+ name: ubuntu/images/*/ubuntu-*-15.10-amd64-server-*
+ owner-id: 099720109477
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: ubuntu
+ - name: ubuntu-14.04
+ driver:
+ image_search:
+ name: ubuntu/images/*/ubuntu-*-14.04-*-server-*
+ owner-id: 099720109477
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: ubuntu
+ # - name: ubuntu-12.04
+ # driver:
+ # image_search:
+ # name: ubuntu/images/*/ubuntu-*-12.04-*-server-*
+ # owner-id: 099720109477
+ # architecture: x86_64
+ # virtualization-type: hvm
+ # block-device-mapping.volume-type: gp2
+ # image-type: machine
+ # instance_type: t2.micro
+ # transport:
+ # username: ubuntu
+ #
+ # Red Hat Enterprise Linux
+ #
+ - name: el-7
+ driver:
+ image_search:
+ name: RHEL-7.*
+ owner-id: 309956199498
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: ec2-user
+ - name: el-6
+ driver:
+ image_search:
+ name: RHEL-6.*
+ owner-id: 309956199498
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: ec2-user
+ - name: el-5
+ driver:
+ image_search:
+ name: RHEL-5.*
+ owner-id: 309956199498
+ architecture: x86_64
+ virtualization-type: paravirtual
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t1.micro
+ transport:
+ username: ec2-user
+ #
+ # FreeBSD
+ #
+ - name: freebsd-10
+ driver:
+ image_search:
+ name: FreeBSD/EC2 10.*-RELEASE*
+ owner-id: 118940168514
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: ec2-user
+ - name: freebsd-9
+ driver:
+ image_search:
+ name: FreeBSD/EC2 9.*-RELEASE*
+ owner-id: 118940168514
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: ec2-user
+ # - name: freebsd-8
+ # driver:
+ # image_search:
+ # name: FreeBSD/EC2 8.*-RELEASE*
+ # owner-id: 118940168514
+ # architecture: x86_64
+ # virtualization-type: hvm
+ # block-device-mapping.volume-type: standard
+ # image-type: machine
+ # instance_type: t2.micro
+ # transport:
+ # username: ec2-user
+ #
+ # OS/X
+ #
+ # - name: mac_os_x-10.11
+ # - name: mac_os_x-10.10
+ # - name: mac_os_x-10.9
+ # - name: mac_os_x-10.8
+ #
+ # Nexus???
+ #
+ # - name: nexus-7
+ #
+ # Solaris
+ #
+ # - name: solaris-11
+ # - name: solaris-10
+ #
+ # Windows
+ #
+ - name: windows-2012r2
+ driver:
+ image_search:
+ name: Windows_Server-2012-R2*-English-*-Base-*
+ owner-alias: amazon
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: administrator
+ # user_data: |
+ # <powershell>
+ # $logfile="C:\\Program Files\\Amazon\\Ec2ConfigService\\Logs\\kitchen-ec2.log"
+ # #PS Remoting and & winrm.cmd basic config
+ # Enable-PSRemoting -Force -SkipNetworkProfileCheck
+ # & winrm.cmd set winrm/config '@{MaxTimeoutms="1800000"}' >> $logfile
+ # & winrm.cmd set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}' >> $logfile
+ # & winrm.cmd set winrm/config/winrs '@{MaxShellsPerUser="50"}' >> $logfile
+ # #Server settings - support username/password login
+ # & winrm.cmd set winrm/config/service/auth '@{Basic="true"}' >> $logfile
+ # & winrm.cmd set winrm/config/service '@{AllowUnencrypted="true"}' >> $logfile
+ # & winrm.cmd set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}' >> $logfile
+ # #Firewall Config
+ # & netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" profile=public protocol=tcp localport=5985 remoteip=localsubnet new remoteip=any >> $logfile
+ # #Set script execution to unrestricted
+ # & Set-ExecutionPolicy Unrestricted -Force
+ # </powershell>
+ - name: windows-2012
+ driver:
+ image_search:
+ name: Windows_Server-2012-RTM*-English-*-Base-*
+ owner-alias: amazon
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: administrator
+ - name: windows-2008r2
+ driver:
+ image_search:
+ name: Windows_Server-2008-R2*-English-*-Base-*
+ owner-alias: amazon
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
+ transport:
+ username: administrator
+ #
+ # Centos
+ #
+ # - name: centos-7
+ # driver:
+ # image_search:
+ # name: CentOS Linux 7 *
+ # owner-alias: aws-marketplace
+ # architecture: x86_64
+ # virtualization-type: hvm
+ # block-device-mapping.volume-type: standard
+ # image-type: machine
+ # instance_type: t2.micro
+ # transport:
+ # username: root
+ # - name: centos-6
+ # driver:
+ # image_search:
+ # name: CentOS-6.5-GA-*
+ # owner-alias: aws-marketplace
+ # architecture: x86_64
+ # virtualization-type: paravirtual
+ # block-device-mapping.volume-type: standard
+ # image-type: machine
+ # instance_type: t1.micro
+ # transport:
+ # username: root
+ #
+ # Fedora
+ #
+ - name: fedora-21
+ driver:
+ image_search:
+ name: Fedora-Cloud-Base-21-*
+ owner-id: 125523088429
+ architecture: x86_64
+ virtualization-type: hvm
+ block-device-mapping.volume-type: gp2
+ image-type: machine
+ instance_type: t2.micro
diff --git a/acceptance/cookbook-git/.kitchen.vagrant.yml b/acceptance/cookbook-git/.kitchen.vagrant.yml
new file mode 100644
index 0000000000..0dc8b11dc1
--- /dev/null
+++ b/acceptance/cookbook-git/.kitchen.vagrant.yml
@@ -0,0 +1,72 @@
+driver:
+ name: vagrant
+ forward_agent: yes
+ customize:
+ cpus: 2
+ memory: 1024
+
+platforms:
+<% %w(
+debian-8
+debian-7
+debian-6
+ubuntu-15.10
+ubuntu-14.04
+el-7
+el-6
+el-5
+freebsd-10
+freebsd-9
+fedora-21
+).each do |platform| %>
+ - name: <%= platform %>
+ driver:
+ box: opscode-<%= platform %>
+ box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_<%= platform %>_chef-provisionerless.box
+<% end %>
+# freebsd-8
+# ubuntu-12.04
+# centos-7
+# centos-6
+
+<% %w(
+2012r2
+2012
+2008r2
+).each do |version| %>
+ - name: windows-<%= version %>
+ driver:
+ box: chef/windows-server-<%= version %>-standard
+# URL is atlas
+<% end %>
+
+suites:
+ - name: default
+ run_list:
+ - recipe[git]
+ attributes: {}
+ includes: ["ubuntu-14.04"]
+ excludes: ["windows-2012r2", "windows-2012", "windows-2008r2"]
+ - name: source
+ includes: ["nonexistent"]
+ excludes: ["ubuntu-12.04", "ubuntu-10.04", "windows-2012r2", "windows-2012", "windows-2008r2"]
+ run_list:
+ - recipe[git::source]
+ attributes: {}
+ - name: default-windows
+ includes: [
+ # 'windows-8.1-professional',
+ # 'windows-2008r2-standard',
+ "windows-2012r2",
+ # "windows-2012",
+ # "windows-2008r2"
+ ]
+ run_list:
+ - recipe[git]
+ attributes: {}
+
+provisioner:
+ name: chef_zero
+ product_name: chef
+ product_version: latest
+ channel: current
diff --git a/acceptance/trivial/.kitchen.yml b/acceptance/trivial/.kitchen.yml
index a7d0a25f93..c0f1d782d2 100644
--- a/acceptance/trivial/.kitchen.yml
+++ b/acceptance/trivial/.kitchen.yml
@@ -23,5 +23,5 @@ suites:
provisioner:
product_name: chef
product_version: latest
- channel: current
+ channel: unstable
run_list:
diff --git a/chef.gemspec b/chef.gemspec
index ed2ce1a621..e50ef6c744 100644
--- a/chef.gemspec
+++ b/chef.gemspec
@@ -54,6 +54,6 @@ Gem::Specification.new do |s|
s.bindir = "bin"
s.executables = %w{ chef-client chef-solo knife chef-shell chef-apply }
- s.require_path = %w{ lib lib-backcompat }
+ s.require_paths = %w{ lib lib-backcompat }
s.files = %w{Gemfile Rakefile LICENSE README.md CONTRIBUTING.md} + Dir.glob("{distro,lib,lib-backcompat,tasks,spec}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) } + Dir.glob("*.gemspec")
end
diff --git a/lib/chef/property.rb b/lib/chef/property.rb
index 8ff4ecc7fc..8b5c6560a9 100644
--- a/lib/chef/property.rb
+++ b/lib/chef/property.rb
@@ -320,7 +320,8 @@ class Chef
resource.resource_initializing &&
resource.respond_to?(:enclosing_provider) &&
resource.enclosing_provider &&
- resource.enclosing_provider.respond_to?(name)
+ resource.enclosing_provider.new_resource &&
+ resource.enclosing_provider.new_resource.respond_to?(name)
Chef::Log.warn("#{Chef::Log.caller_location}: property #{name} is declared in both #{resource} and #{resource.enclosing_provider}. Use new_resource.#{name} instead. At #{Chef::Log.caller_location}")
end
diff --git a/lib/chef/provider/package/zypper.rb b/lib/chef/provider/package/zypper.rb
index 9b0aaf322a..fe8358c654 100644
--- a/lib/chef/provider/package/zypper.rb
+++ b/lib/chef/provider/package/zypper.rb
@@ -2,7 +2,7 @@
#
# Authors:: Adam Jacob (<adam@opscode.com>)
# Ionuț Arțăriși (<iartarisi@suse.cz>)
-# Copyright:: Copyright (c) 2008 Opscode, Inc.
+# Copyright:: Copyright (c) 2008-2015 Chef Software, Inc.
# Copyright (c) 2013 SUSE Linux GmbH
# License:: Apache License, Version 2.0
#
@@ -20,70 +20,74 @@
#
require "chef/provider/package"
-require "chef/mixin/command"
-require "chef/resource/package"
-require "singleton"
+require "chef/resource/zypper_package"
class Chef
class Provider
class Package
class Zypper < Chef::Provider::Package
+ use_multipackage_api
provides :package, platform_family: "suse"
provides :zypper_package, os: "linux"
- def load_current_resource
- @current_resource = Chef::Resource::ZypperPackage.new(new_resource.name)
- current_resource.package_name(new_resource.package_name)
-
- is_installed=false
- is_out_of_date=false
- version=""
- oud_version=""
+ def get_versions(package_name)
+ candidate_version = current_version = nil
+ is_installed = false
Chef::Log.debug("#{new_resource} checking zypper")
- status = shell_out_with_timeout("zypper --non-interactive info #{new_resource.package_name}")
+ status = shell_out_with_timeout!("zypper --non-interactive info #{package_name}")
status.stdout.each_line do |line|
case line
when /^Version: (.+)$/
- version = $1
+ candidate_version = $1
Chef::Log.debug("#{new_resource} version #{$1}")
when /^Installed: Yes$/
is_installed=true
Chef::Log.debug("#{new_resource} is installed")
-
- when /^Installed: No$/
- is_installed=false
- Chef::Log.debug("#{new_resource} is not installed")
when /^Status: out-of-date \(version (.+) installed\)$/
- is_out_of_date=true
- oud_version=$1
+ current_version=$1
Chef::Log.debug("#{new_resource} out of date version #{$1}")
end
end
+ current_version = candidate_version if is_installed
+ { current_version: current_version, candidate_version: candidate_version }
+ end
- if is_installed==false
- @candidate_version=version
- end
-
- if is_installed==true
- if is_out_of_date==true
- current_resource.version(oud_version)
- @candidate_version=version
- else
- current_resource.version(version)
- @candidate_version=version
+ def versions
+ @versions =
+ begin
+ raw_versions = package_name_array.map do |package_name|
+ get_versions(package_name)
+ end
+ Hash[*package_name_array.zip(raw_versions).flatten]
end
+ end
+
+ def get_candidate_versions
+ package_name_array.map do |package_name|
+ versions[package_name][:candidate_version]
end
+ end
- unless status.exitstatus == 0
- raise Chef::Exceptions::Package, "zypper failed - #{status.inspect}!"
+ def get_current_versions
+ package_name_array.map do |package_name|
+ versions[package_name][:current_version]
end
+ end
+
+ def load_current_resource
+ @current_resource = Chef::Resource::ZypperPackage.new(new_resource.name)
+ current_resource.package_name(new_resource.package_name)
+
+ @candidate_version = get_candidate_versions
+ current_resource.version(get_current_versions)
current_resource
end
- def zypper_version()
- `zypper -V 2>&1`.scan(/\d+/).join(".").to_f
+ def zypper_version
+ @zypper_version ||=
+ `zypper -V 2>&1`.scan(/\d+/).join(".").to_f
end
def install_package(name, version)
@@ -91,6 +95,7 @@ class Chef
end
def upgrade_package(name, version)
+ # `zypper install` upgrades packages, we rely on the idempotency checks to get action :install behavior
install_package(name, version)
end
@@ -103,13 +108,19 @@ class Chef
end
private
- def zypper_package(command, pkgname, version)
- version = "=#{version}" unless version.nil? || version.empty?
+
+ def zip(names, versions)
+ names.zip(versions).map do |n, v|
+ (v.nil? || v.empty?) ? n : "#{n}=#{v}"
+ end
+ end
+
+ def zypper_package(command, names, versions)
+ zipped_names = zip(names, versions)
if zypper_version < 1.0
- shell_out_with_timeout!("zypper#{gpg_checks} #{command} -y #{pkgname}")
+ shell_out_with_timeout!(a_to_s("zypper", gpg_checks, command, "-y", names))
else
- shell_out_with_timeout!("zypper --non-interactive#{gpg_checks} "+
- "#{command} #{pkgname}#{version}")
+ shell_out_with_timeout!(a_to_s("zypper --non-interactive", gpg_checks, command, zipped_names))
end
end
@@ -118,12 +129,12 @@ class Chef
when true
""
when false
- " --no-gpg-checks"
+ "--no-gpg-checks"
when nil
Chef::Log.warn("Chef::Config[:zypper_check_gpg] was not set. " +
"All packages will be installed without gpg signature checks. " +
"This is a security hazard.")
- " --no-gpg-checks"
+ "--no-gpg-checks"
end
end
end
diff --git a/spec/functional/resource/user/useradd_spec.rb b/spec/functional/resource/user/useradd_spec.rb
index 38682baea6..d0ae40a35f 100644
--- a/spec/functional/resource/user/useradd_spec.rb
+++ b/spec/functional/resource/user/useradd_spec.rb
@@ -245,7 +245,7 @@ describe Chef::Provider::User::Useradd, metadata do
expect(pw_entry.home).to eq(home)
end
- if %w{rhel fedora}.include?(OHAI_SYSTEM["platform_family"])
+ if %w{rhel fedora wrlinux}.include?(OHAI_SYSTEM["platform_family"])
# Inconsistent behavior. See: CHEF-2205
it "creates the home dir when not explicitly asked to on RHEL (XXX)" do
expect(File).to exist(home)
@@ -287,9 +287,9 @@ describe Chef::Provider::User::Useradd, metadata do
let(:uid_min) do
case ohai[:platform]
when "aix"
- # UIDs and GIDs below 100 are typically reserved for system accounts and services
- # http://www.ibm.com/developerworks/aix/library/au-satuidgid/
- 100
+ # UIDs and GIDs below 200 are typically reserved for system accounts and services
+ # https://abcofaix.wordpress.com/tag/usermod/
+ 200
else
# from `man useradd`, login user means uid will be between
# UID_SYS_MIN and UID_SYS_MAX defined in /etc/login.defs. On my
diff --git a/spec/integration/recipes/resource_action_spec.rb b/spec/integration/recipes/resource_action_spec.rb
index b8c533b31d..5778c467c5 100644
--- a/spec/integration/recipes/resource_action_spec.rb
+++ b/spec/integration/recipes/resource_action_spec.rb
@@ -9,8 +9,8 @@ describe "Resource.action" do
shared_context "ActionJackson" do
it "the default action is the first declared action" do
converge <<-EOM, __FILE__, __LINE__+1
- #{resource_dsl} 'hi' do
- foo 'foo!'
+ #{resource_dsl} "hi" do
+ foo "foo!"
end
EOM
expect(ActionJackson.ran_action).to eq :access_recipe_dsl
@@ -19,8 +19,8 @@ describe "Resource.action" do
it "the action can access recipe DSL" do
converge <<-EOM, __FILE__, __LINE__+1
- #{resource_dsl} 'hi' do
- foo 'foo!'
+ #{resource_dsl} "hi" do
+ foo "foo!"
action :access_recipe_dsl
end
EOM
@@ -30,8 +30,8 @@ describe "Resource.action" do
it "the action can access attributes" do
converge <<-EOM, __FILE__, __LINE__+1
- #{resource_dsl} 'hi' do
- foo 'foo!'
+ #{resource_dsl} "hi" do
+ foo "foo!"
action :access_attribute
end
EOM
@@ -41,8 +41,8 @@ describe "Resource.action" do
it "the action can access public methods" do
converge <<-EOM, __FILE__, __LINE__+1
- #{resource_dsl} 'hi' do
- foo 'foo!'
+ #{resource_dsl} "hi" do
+ foo "foo!"
action :access_method
end
EOM
@@ -52,8 +52,8 @@ describe "Resource.action" do
it "the action can access protected methods" do
converge <<-EOM, __FILE__, __LINE__+1
- #{resource_dsl} 'hi' do
- foo 'foo!'
+ #{resource_dsl} "hi" do
+ foo "foo!"
action :access_protected_method
end
EOM
@@ -64,8 +64,8 @@ describe "Resource.action" do
it "the action cannot access private methods" do
expect {
converge(<<-EOM, __FILE__, __LINE__+1)
- #{resource_dsl} 'hi' do
- foo 'foo!'
+ #{resource_dsl} "hi" do
+ foo "foo!"
action :access_private_method
end
EOM
@@ -75,8 +75,8 @@ describe "Resource.action" do
it "the action cannot access resource instance variables" do
converge <<-EOM, __FILE__, __LINE__+1
- #{resource_dsl} 'hi' do
- foo 'foo!'
+ #{resource_dsl} "hi" do
+ foo "foo!"
action :access_instance_variable
end
EOM
@@ -86,14 +86,14 @@ describe "Resource.action" do
it "the action does not compile until the prior resource has converged" do
converge <<-EOM, __FILE__, __LINE__+1
- ruby_block 'wow' do
+ ruby_block "wow" do
block do
- ResourceActionSpec::ActionJackson.ruby_block_converged = 'ruby_block_converged!'
+ ResourceActionSpec::ActionJackson.ruby_block_converged = "ruby_block_converged!"
end
end
- #{resource_dsl} 'hi' do
- foo 'foo!'
+ #{resource_dsl} "hi" do
+ foo "foo!"
action :access_class_method
end
EOM
@@ -103,12 +103,12 @@ describe "Resource.action" do
it "the action's resources converge before the next resource converges" do
converge <<-EOM, __FILE__, __LINE__+1
- #{resource_dsl} 'hi' do
- foo 'foo!'
+ #{resource_dsl} "hi" do
+ foo "foo!"
action :access_attribute
end
- ruby_block 'wow' do
+ ruby_block "wow" do
block do
ResourceActionSpec::ActionJackson.ruby_block_converged = ResourceActionSpec::ActionJackson.succeeded
end
@@ -436,6 +436,34 @@ describe "Resource.action" do
end
+ context "With a resource with a set_or_return property named group (same name as a resource)" do
+ class ResourceActionSpecWithGroupAction < Chef::Resource
+ resource_name :resource_action_spec_set_group_to_nil
+ action :set_group_to_nil do
+ # Access x during converge to ensure that we emit no warnings there
+ resource_action_spec_with_group "hi" do
+ group nil
+ action :nothing
+ end
+ end
+ end
+
+ class ResourceActionSpecWithGroup < Chef::Resource
+ resource_name :resource_action_spec_with_group
+ def group(value=nil)
+ set_or_return(:group, value, {})
+ end
+ end
+
+ it "Setting group to nil in an action does not emit a warning about it being defined in two places" do
+ expect_recipe {
+ resource_action_spec_set_group_to_nil "hi" do
+ action :set_group_to_nil
+ end
+ }.to emit_no_warnings_or_errors
+ end
+ end
+
context "When a resource has a property with the same name as another resource" do
class HasPropertyNamedTemplate < Chef::Resource
use_automatic_resource_name
diff --git a/spec/unit/provider/package/zypper_spec.rb b/spec/unit/provider/package/zypper_spec.rb
index 0f39fde5cf..34cd5fe0ca 100644
--- a/spec/unit/provider/package/zypper_spec.rb
+++ b/spec/unit/provider/package/zypper_spec.rb
@@ -34,7 +34,7 @@ describe Chef::Provider::Package::Zypper do
before(:each) do
allow(Chef::Resource::Package).to receive(:new).and_return(current_resource)
- allow(provider).to receive(:shell_out).and_return(status)
+ allow(provider).to receive(:shell_out!).and_return(status)
allow(provider).to receive(:`).and_return("2.0")
end
@@ -60,7 +60,7 @@ describe Chef::Provider::Package::Zypper do
end
it "should run zypper info with the package name" do
- shell_out_expectation(
+ shell_out_expectation!(
"zypper --non-interactive info #{new_resource.package_name}"
).and_return(status)
provider.load_current_resource
@@ -68,33 +68,24 @@ describe Chef::Provider::Package::Zypper do
it "should set the installed version to nil on the current resource if zypper info installed version is (none)" do
allow(provider).to receive(:shell_out).and_return(status)
+ expect(current_resource).to receive(:version).with([nil]).and_return(true)
provider.load_current_resource
end
it "should set the installed version if zypper info has one" do
status = double(:stdout => "Version: 1.0\nInstalled: Yes\n", :exitstatus => 0)
- allow(provider).to receive(:shell_out).and_return(status)
- expect(current_resource).to receive(:version).with("1.0").and_return(true)
+ allow(provider).to receive(:shell_out!).and_return(status)
+ expect(current_resource).to receive(:version).with(["1.0"]).and_return(true)
provider.load_current_resource
end
it "should set the candidate version if zypper info has one" do
status = double(:stdout => "Version: 1.0\nInstalled: No\nStatus: out-of-date (version 0.9 installed)", :exitstatus => 0)
- allow(provider).to receive(:shell_out).and_return(status)
+ allow(provider).to receive(:shell_out!).and_return(status)
provider.load_current_resource
- expect(provider.candidate_version).to eql("1.0")
- end
-
- it "should raise an exception if zypper info fails" do
- expect(status).to receive(:exitstatus).and_return(1)
- expect { provider.load_current_resource }.to raise_error(Chef::Exceptions::Package)
- end
-
- it "should not raise an exception if zypper info succeeds" do
- expect(status).to receive(:exitstatus).and_return(0)
- expect { provider.load_current_resource }.not_to raise_error
+ expect(provider.candidate_version).to eql(["1.0"])
end
it "should return the current resouce" do
@@ -108,7 +99,7 @@ describe Chef::Provider::Package::Zypper do
shell_out_expectation!(
"zypper --non-interactive install --auto-agree-with-licenses emacs=1.0"
)
- provider.install_package("emacs", "1.0")
+ provider.install_package(["emacs"], ["1.0"])
end
it "should run zypper install without gpg checks" do
allow(Chef::Config).to receive(:[]).with(:zypper_check_gpg).and_return(false)
@@ -116,7 +107,7 @@ describe Chef::Provider::Package::Zypper do
"zypper --non-interactive --no-gpg-checks install "+
"--auto-agree-with-licenses emacs=1.0"
)
- provider.install_package("emacs", "1.0")
+ provider.install_package(["emacs"], ["1.0"])
end
it "should warn about gpg checks on zypper install" do
expect(Chef::Log).to receive(:warn).with(
@@ -126,7 +117,7 @@ describe Chef::Provider::Package::Zypper do
"zypper --non-interactive --no-gpg-checks install "+
"--auto-agree-with-licenses emacs=1.0"
)
- provider.install_package("emacs", "1.0")
+ provider.install_package(["emacs"], ["1.0"])
end
end
@@ -136,7 +127,7 @@ describe Chef::Provider::Package::Zypper do
shell_out_expectation!(
"zypper --non-interactive install --auto-agree-with-licenses emacs=1.0"
)
- provider.upgrade_package("emacs", "1.0")
+ provider.upgrade_package(["emacs"], ["1.0"])
end
it "should run zypper update without gpg checks" do
allow(Chef::Config).to receive(:[]).with(:zypper_check_gpg).and_return(false)
@@ -144,7 +135,7 @@ describe Chef::Provider::Package::Zypper do
"zypper --non-interactive --no-gpg-checks install "+
"--auto-agree-with-licenses emacs=1.0"
)
- provider.upgrade_package("emacs", "1.0")
+ provider.upgrade_package(["emacs"], ["1.0"])
end
it "should warn about gpg checks on zypper upgrade" do
expect(Chef::Log).to receive(:warn).with(
@@ -154,14 +145,14 @@ describe Chef::Provider::Package::Zypper do
"zypper --non-interactive --no-gpg-checks install "+
"--auto-agree-with-licenses emacs=1.0"
)
- provider.upgrade_package("emacs", "1.0")
+ provider.upgrade_package(["emacs"], ["1.0"])
end
it "should run zypper upgrade without gpg checks" do
shell_out_expectation!(
"zypper --non-interactive --no-gpg-checks install "+
"--auto-agree-with-licenses emacs=1.0"
)
- provider.upgrade_package("emacs", "1.0")
+ provider.upgrade_package(["emacs"], ["1.0"])
end
end
@@ -173,7 +164,7 @@ describe Chef::Provider::Package::Zypper do
shell_out_expectation!(
"zypper --non-interactive remove emacs"
)
- provider.remove_package("emacs", nil)
+ provider.remove_package(["emacs"], [nil])
end
end
@@ -183,14 +174,14 @@ describe Chef::Provider::Package::Zypper do
shell_out_expectation!(
"zypper --non-interactive remove emacs=1.0"
)
- provider.remove_package("emacs", "1.0")
+ provider.remove_package(["emacs"], ["1.0"])
end
it "should run zypper remove without gpg checks" do
allow(Chef::Config).to receive(:[]).with(:zypper_check_gpg).and_return(false)
shell_out_expectation!(
"zypper --non-interactive --no-gpg-checks remove emacs=1.0"
)
- provider.remove_package("emacs", "1.0")
+ provider.remove_package(["emacs"], ["1.0"])
end
it "should warn about gpg checks on zypper remove" do
expect(Chef::Log).to receive(:warn).with(
@@ -199,24 +190,24 @@ describe Chef::Provider::Package::Zypper do
shell_out_expectation!(
"zypper --non-interactive --no-gpg-checks remove emacs=1.0"
)
- provider.remove_package("emacs", "1.0")
+ provider.remove_package(["emacs"], ["1.0"])
end
end
end
describe "purge_package" do
- it "should run remove_package with the name and version" do
+ it "should run remove with the name and version and --clean-deps" do
shell_out_expectation!(
"zypper --non-interactive --no-gpg-checks remove --clean-deps emacs=1.0"
)
- provider.purge_package("emacs", "1.0")
+ provider.purge_package(["emacs"], ["1.0"])
end
it "should run zypper purge without gpg checks" do
allow(Chef::Config).to receive(:[]).with(:zypper_check_gpg).and_return(false)
shell_out_expectation!(
"zypper --non-interactive --no-gpg-checks remove --clean-deps emacs=1.0"
)
- provider.purge_package("emacs", "1.0")
+ provider.purge_package(["emacs"], ["1.0"])
end
it "should warn about gpg checks on zypper purge" do
expect(Chef::Log).to receive(:warn).with(
@@ -225,7 +216,7 @@ describe Chef::Provider::Package::Zypper do
shell_out_expectation!(
"zypper --non-interactive --no-gpg-checks remove --clean-deps emacs=1.0"
)
- provider.purge_package("emacs", "1.0")
+ provider.purge_package(["emacs"], ["1.0"])
end
end
@@ -239,7 +230,7 @@ describe Chef::Provider::Package::Zypper do
shell_out_expectation!(
"zypper --no-gpg-checks install --auto-agree-with-licenses -y emacs"
)
- provider.install_package("emacs", "1.0")
+ provider.install_package(["emacs"], ["1.0"])
end
end
@@ -248,7 +239,7 @@ describe Chef::Provider::Package::Zypper do
shell_out_expectation!(
"zypper --no-gpg-checks install --auto-agree-with-licenses -y emacs"
)
- provider.upgrade_package("emacs", "1.0")
+ provider.upgrade_package(["emacs"], ["1.0"])
end
end
@@ -257,8 +248,27 @@ describe Chef::Provider::Package::Zypper do
shell_out_expectation!(
"zypper --no-gpg-checks remove -y emacs"
)
- provider.remove_package("emacs", "1.0")
+ provider.remove_package(["emacs"], ["1.0"])
end
end
end
+
+ describe "when installing multiple packages" do # https://github.com/chef/chef/issues/3570
+ it "should install an array of package names and versions" do
+ allow(Chef::Config).to receive(:[]).with(:zypper_check_gpg).and_return(false)
+ shell_out_expectation!(
+ "zypper --non-interactive --no-gpg-checks install "+
+ "--auto-agree-with-licenses emacs=1.0 vim=2.0"
+ )
+ provider.install_package(["emacs", "vim"], ["1.0", "2.0"])
+ end
+
+ it "should remove an array of package names and versions" do
+ allow(Chef::Config).to receive(:[]).with(:zypper_check_gpg).and_return(false)
+ shell_out_expectation!(
+ "zypper --non-interactive --no-gpg-checks remove emacs=1.0 vim=2.0"
+ )
+ provider.remove_package(["emacs", "vim"], ["1.0", "2.0"])
+ end
+ end
end
diff --git a/tasks/cbgb.rb b/tasks/cbgb.rb
index 17c69e0446..97d374e297 100644
--- a/tasks/cbgb.rb
+++ b/tasks/cbgb.rb
@@ -33,7 +33,7 @@ namespace :cbgb do
out << "<!-- Modify CBGB.toml file and run `rake cbgb:generate` to regenerate -->\n\n"
out << "# " + cbgb["Preamble"]["title"] + "\n\n"
out << cbgb["Preamble"]["text"] + "\n"
- out << "# Board of Governers\n\n"
+ out << "# Board of Governors\n\n"
out << "## " + cbgb["Org"]["Lead"]["title"] + "\n\n"
out << person(cbgb["people"], cbgb["Org"]["Lead"]["person"]) + "\n\n"
out << "### " + cbgb["Org"]["Contributors"]["title"] + "\n\n"