Skip to content

Commit

Permalink
TOOLS-98 Chef needs pkgin specific plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
trevoro authored and aglarond committed Apr 11, 2012
1 parent 23946a7 commit aeaa465
Show file tree
Hide file tree
Showing 7 changed files with 405 additions and 0 deletions.
8 changes: 8 additions & 0 deletions chef/lib/chef/platform.rb
Expand Up @@ -232,6 +232,14 @@ def platforms
:group => Chef::Provider::Group::Usermod
}
},
:smartos => {
:default => {
:service => Chef::Provider::Service::SmartOS,
:package => Chef::Provider::Package::SmartOS,
:cron => Chef::Provider::Cron::Solaris,
:group => Chef::Provider::Group::Usermod
}
},
:netbsd => {
:default => {
:group => Chef::Provider::Group::Usermod
Expand Down
195 changes: 195 additions & 0 deletions chef/lib/chef/provider/cron/smartos.rb
@@ -0,0 +1,195 @@
#
# Author:: Bryan McLellan (btm@loftninjas.org)
# Author:: Toomas Pelberg (toomasp@gmx.net)
# Copyright:: Copyright (c) 2009 Bryan McLellan
# Copyright:: Copyright (c) 2010 Toomas Pelberg
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require 'chef/log'
require 'chef/mixin/command'
require 'chef/provider'

class Chef
class Provider
class Cron
class SmartOS < Chef::Provider::Cron
include Chef::Mixin::Command

CRON_PATTERN = /([-0-9*,\/]+)\s([-0-9*,\/]+)\s([-0-9*,\/]+)\s([-0-9*,\/]+)\s([-0-9*,\/]+)\s(.*)/

def initialize(new_resource, run_context)
super(new_resource, run_context)
@cron_exists = false
@cron_empty = false
end
attr_accessor :cron_exists, :cron_empty

def load_current_resource
crontab_lines = []
@current_resource = Chef::Resource::Cron.new(@new_resource.name)
@current_resource.user(@new_resource.user)
status = popen4("crontab -l #{@new_resource.user}") do |pid, stdin, stdout, stderr|
stdout.each_line { |line| crontab_lines << line }
end
if status.exitstatus > 1
raise Chef::Exceptions::Cron, "Error determining state of #{@new_resource.name}, exit: #{status.exitstatus}"
elsif status.exitstatus == 0
cron_found = false
crontab_lines.each do |line|
case line.chomp
when "# Chef Name: #{@new_resource.name}"
Chef::Log.debug("#{@new_resource} found cron '#{@new_resource.name}'")
cron_found = true
@cron_exists = true
next
when /^MAILTO=(\S*)/
@current_resource.mailto($1) if cron_found
next
when /^PATH=(\S*)/
@current_resource.path($1) if cron_found
next
when /^SHELL=(\S*)/
@current_resource.shell($1) if cron_found
next
when /^HOME=(\S*)/
@current_resource.home($1) if cron_found
next
when CRON_PATTERN
if cron_found
@current_resource.minute($1)
@current_resource.hour($2)
@current_resource.day($3)
@current_resource.month($4)
@current_resource.weekday($5)
@current_resource.command($6)
cron_found=false
end
next
else
next
end
end
Chef::Log.debug("#{@new_resource} cron '#{@new_resource.name}' not found") unless @cron_exists
elsif status.exitstatus == 1
Chef::Log.debug("#{@new_resource} cron empty for '#{@new_resource.user}'")
@cron_empty = true
end

@current_resource
end

def compare_cron
[ :minute, :hour, :day, :month, :weekday, :command, :mailto, :path, :shell, :home ].any? do |cron_var|
!@new_resource.send(cron_var).nil? && @new_resource.send(cron_var) != @current_resource.send(cron_var)
end
end

def write_crontab(crontab)
tempcron = Tempfile.new("chef-cron")
tempcron << crontab
tempcron.flush
tempcron.chmod(0644)
status = run_command(:command => "/usr/bin/crontab #{tempcron.path}",:user => @new_resource.user)
if(status == 0)
@new_resource.updated_by_last_action(true)
else
@new_resource.updated_by_last_action(false)
end
tempcron.close!
return status
end

def action_create
crontab = String.new
newcron = String.new
cron_found = false

newcron << "# Chef Name: #{new_resource.name}\n"
[ :mailto, :path, :shell, :home ].each do |v|
newcron << "#{v.to_s.upcase}=#{@new_resource.send(v)}\n" if @new_resource.send(v)
end
newcron << "#{@new_resource.minute} #{@new_resource.hour} #{@new_resource.day} #{@new_resource.month} #{@new_resource.weekday} #{@new_resource.command}\n"

if @cron_exists
unless compare_cron
Chef::Log.debug("#{@new_resource} skipping existing cron entry '#{@new_resource.name}'")
return
end
status = popen4("crontab -l #{@new_resource.user}") do |pid, stdin, stdout, stderr|
stdout.each_line do |line|
case line.chomp
when "# Chef Name: #{@new_resource.name}"
cron_found = true
next
when CRON_PATTERN
if cron_found
cron_found = false
crontab << newcron
next
end
else
next if cron_found
end
crontab << line
end
end

status = write_crontab(crontab)
Chef::Log.info("#{@new_resource} updated crontab entry")
else
unless @cron_empty
status = popen4("crontab -l #{@new_resource.user}") do |pid, stdin, stdout, stderr|
stdout.each { |line| crontab << line }
end
end

crontab << newcron
status = write_crontab(crontab)
Chef::Log.info("#{@new_resource} added crontab entry")
end
end

def action_delete
if @cron_exists
crontab = String.new
cron_found = false
status = popen4("crontab -l #{@new_resource.user}") do |pid, stdin, stdout, stderr|
stdout.each_line do |line|
case line.chomp
when "# Chef Name: #{@new_resource.name}"
cron_found = true
next
when CRON_PATTERN
if cron_found
cron_found = false
next
end
else
next if cron_found
end
crontab << line
end
end

status = write_crontab(crontab)
Chef::Log.info("#{@new_resource} deleted crontab entry")
end
end

end
end
end
end
78 changes: 78 additions & 0 deletions chef/lib/chef/provider/package/smartos.rb
@@ -0,0 +1,78 @@
#
# Authors:: Trevor O (trevoro@joyent.com)
# Bryan McLellan (btm@loftninjas.org)
# Matthew Landauer (matthew@openaustralia.org)
# Copyright:: Copyright (c) 2009 Bryan McLellan, Matthew Landauer
# 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.
#
# Notes
#
# * Supports installing using a local package name
# * Otherwise reverts to installing from the pkgsrc repositories URL

require 'chef/provider/package'
require 'chef/mixin/shell_out'
require 'chef/resource/package'
require 'chef/mixin/get_source_from_package'

class Chef
class Provider
class Package
class SmartOS < Chef::Provider::Package
include Chef::Mixin::ShellOut
attr_accessor :is_virtual_package


def load_current_resource
Chef::Log.debug("#{@new_resource} loading current resource")
@current_resource = Chef::Resource::Package.new(@new_resource.name)
@current_resource.package_name(@new_resource.package_name)
check_package_state(@new_resource.package_name)
@current_resource # modified by check_package_state
end

def check_package_state(name)
Chef::Log.debug("#{@new_resource} checking package #{name}")
# XXX
info = shell_out!("pkg_info -E \"#{name}*\"", :env => nil, :returns => [0,1])
version = info.stdout[/^#{@new_resource.package_name}-(.+)/, 1]
if !version
@current_resource.version(nil)
else
@current_resource.version(version)
end
end

def install_package(name, version)
Chef::Log.debug("#{@new_resource} installing package #{name}-#{version}")
package = "#{name}-#{version}"
run_command_with_systems_locale(:command => "pkgin -y install #{package}")
end

def upgrade_package(name, version)
Chef::Log.debug("#{@new_resource} upgrading package #{name}-#{version}")
install_package(name, version)
end

def remove_package(name, version)
Chef::Log.debug("#{@new_resource} removing package #{name}-#{version}")
package = "#{name}-#{version}"
run_command_with_systems_locale(:command => "pkgin -y remove #{package}")
end

end
end
end
end
85 changes: 85 additions & 0 deletions chef/lib/chef/provider/service/smartos.rb
@@ -0,0 +1,85 @@
#
# Author:: Toomas Pelberg (<toomasp@gmx.net>)
# Copyright:: Copyright (c) 2010 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.
#

require 'chef/provider/service'
require 'chef/mixin/command'

class Chef
class Provider
class Service
class SmartOS < Chef::Provider::Service

def initialize(new_resource, run_context=nil)
super
@init_command = "/usr/sbin/svcadm"
@status_command = "/bin/svcs -l"
end

def load_current_resource
@current_resource = Chef::Resource::Service.new(@new_resource.name)
@current_resource.service_name(@new_resource.service_name)
unless ::File.exists? "/bin/svcs"
raise Chef::Exceptions::Service, "/bin/svcs does not exist!"
end
@status = service_status.enabled
@current_resource
end

def enable_service
run_command(:command => "#{@init_command} enable #{@new_resource.service_name}")
return service_status.enabled
end

def disable_service
run_command(:command => "#{@init_command} disable #{@new_resource.service_name}")
return service_status.enabled
end

alias_method :stop_service, :disable_service
alias_method :start_service, :enable_service

def reload_service
run_command(:command => "#{@init_command} refresh #{@new_resource.service_name}")
end

def restart_service
disable_service
return enable_service
end

def service_status
status = popen4("#{@status_command} #{@current_resource.service_name}") do |pid, stdin, stdout, stderr|
stdout.each do |line|
case line
when /state\s+online/
@current_resource.enabled(true)
@current_resource.running(true)
end
end
end
unless @current_resource.enabled
@current_resource.enabled(false)
@current_resource.running(false)
end
@current_resource
end

end
end
end
end
2 changes: 2 additions & 0 deletions chef/lib/chef/providers.rb
Expand Up @@ -60,6 +60,7 @@
require 'chef/provider/package/yum'
require 'chef/provider/package/zypper'
require 'chef/provider/package/solaris'
require 'chef/provider/package/smartos'

require 'chef/provider/service/arch'
require 'chef/provider/service/debian'
Expand All @@ -75,6 +76,7 @@
require 'chef/provider/service/windows'
require 'chef/provider/service/solaris'
require 'chef/provider/service/macosx'
require 'chef/provider/service/smartos'

require 'chef/provider/user/dscl'
require 'chef/provider/user/pw'
Expand Down

0 comments on commit aeaa465

Please sign in to comment.