Last active
December 17, 2015 02:29
-
-
Save gondoi/5536321 to your computer and use it in GitHub Desktop.
lock_wait has been added as an option to the apt_package resource.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class File | |
def flocked? &block | |
flockstruct = [Fcntl::F_RDLCK, 0, 0, 0, 0].pack("ssqqi") | |
fcntl Fcntl::F_GETLK, flockstruct | |
status = flockstruct.unpack("ssqqi")[0] | |
case status | |
when Fcntl::F_UNLCK | |
return false | |
when Fcntl::F_WRLCK|Fcntl::F_RDLCK | |
return true | |
else | |
raise SystemCallError, status | |
end | |
end | |
alias_method "if_not_flocked", "flocked?" | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'timeout' | |
require 'chef/provider/package' | |
require 'chef/mixin/command' | |
require 'chef/resource/package' | |
require 'chef/mixin/shell_out' | |
require 'chef/mixin/file' | |
class Chef | |
class Provider | |
class Package | |
class Apt < Chef::Provider::Package | |
... | |
def install_package(name, version) | |
package_name = "#{name}=#{version}" | |
package_name = name if @is_virtual_package | |
AptDB::Locks.wait_on_lock(@new_resource.lock_wait) | |
run_command_with_systems_locale( | |
:command => "apt-get -q -y#{expand_options(default_release_options)}#{expand_options(@new_resource.options)} install #{package_name}", | |
:environment => { | |
"DEBIAN_FRONTEND" => "noninteractive" | |
} | |
) | |
end | |
... | |
end | |
module AptDB | |
module Locks | |
#This function opens the file passed, and checks to see if it is locked | |
def self.is_locked? fname | |
f = File.new(fname) | |
if f.flocked? | |
f.close | |
return true | |
else | |
f.close | |
return false | |
end | |
end | |
#This function runs through possible apt lock files and checks for a current lock | |
def self.apt_locked? | |
lock_files = [ | |
"/var/lib/dpkg/lock", | |
"/var/lock/aptitude", | |
"/var/cache/apt/archives/lock", | |
"/var/lib/apt/lists/lock" | |
] | |
lock_files.each do |f| | |
if File.exists?(f) and is_locked?(f) | |
return true | |
end | |
end | |
return false | |
end | |
#This function will ask if apt is locked and sleep | |
def self.wait_on_lock( timeout_sec = 60 ) | |
begin | |
Timeout::timeout(timeout_sec) do | |
if apt_locked? | |
Chef::Log.warn("Apt DB is locked. Sleeping...") | |
while apt_locked? | |
sleep(5) | |
end | |
Chef::Log.info("Apt DB is free. Waking up.") | |
end | |
end | |
rescue | |
Chef::Application.fatal!("Apt has been locked for too long.", -10) | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'chef/resource/package' | |
require 'chef/provider/package/apt' | |
class Chef | |
class Resource | |
class AptPackage < Chef::Resource::Package | |
def initialize(name, run_context=nil) | |
super | |
@resource_name = :apt_package | |
@provider = Chef::Provider::Package::Apt | |
@default_release = nil | |
@lock_wait = 300 | |
end | |
def default_release(arg=nil) | |
set_or_return( | |
:default_release, | |
arg, | |
:kind_of => [ String ] | |
) | |
end | |
def lock_wait(arg=nil) | |
set_or_return( | |
:lock_wait, | |
arg, | |
:kind_of => [ Integer ] | |
) | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Failures: | |
1) Chef::Provider::Package::Apt install_package should run apt-get install with the package name and version | |
Failure/Error: @provider.install_package("irssi", "0.8.12-7") | |
NoMethodError: | |
undefined method `lock_wait' for Chef::Resource::Package | |
# ./lib/chef/resource.rb:293:in `method_missing' | |
# ./lib/chef/provider/package/apt.rb:96:in `install_package' | |
# ./spec/unit/provider/package/apt_spec.rb:203:in `block (3 levels) in <top (required)>' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment