-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check for sufficient disk space before upgrade #1381
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
require 'mixlib/shellout' | ||
module Du | ||
# Calculate the disk space used by the given path. Requires that | ||
# `du` is in our PATH. | ||
# | ||
# @param path [String] Path to a directory on disk | ||
# @return [Integer] KB used by directory on disk | ||
# | ||
def self.du(path) | ||
# TODO(ssd) 2017-08-18: Do we need to worry about sparse files | ||
# here? If so, can we expect the --apparent-size flag to exist on | ||
# all of our platforms. | ||
command = Mixlib::ShellOut.new("du -sk #{path}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nevermind, you've already checked that. (Just now read the message) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah sorry for the noise, ignore me |
||
command.run_command | ||
if command.status.success? | ||
command.stdout.split("\t").first.to_i | ||
else | ||
Chef::Log.error("du -sk #{path} failed with exit status: #{command.exitstatus}") | ||
Chef::Log.error("du stderr: #{command.stderr}") | ||
raise "du failed" | ||
end | ||
rescue Errno::ENOENT | ||
raise "The du utility is not available. Unable to check disk usage" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this block upgrading? Can I override the disk usage check failure if I believe I know what I'm doing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently it does. We could use an environment variable to skip the check perhaps? |
||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
require 'ffi' | ||
|
||
class Statfs | ||
# | ||
# Statfs provides a simple interface to the statvfs system call. | ||
# Since the statvfs struct varies a bit across platforms, this | ||
# likely only works on Linux and OSX at the moment. | ||
# | ||
extend FFI::Library | ||
ffi_lib FFI::Library::LIBC | ||
|
||
attach_function(:statvfs, [:string, :pointer], :int) | ||
attach_function(:strerror, [:int], :string) | ||
|
||
FSBLKCNT_T = if RbConfig::CONFIG['host_os'] =~ /darwin|osx|mach/i | ||
:uint | ||
else | ||
:ulong | ||
end | ||
|
||
# See http://man7.org/linux/man-pages/man2/statvfs.2.html | ||
class Statvfs < FFI::Struct | ||
spec = [ | ||
:f_bsize, :ulong, # Filesystem block size | ||
:f_frsize, :ulong, # Fragement size | ||
:f_blocks, FSBLKCNT_T, # Size of fs in f_frsize units | ||
:f_bfree, FSBLKCNT_T, # Number of free blocks | ||
:f_bavail, FSBLKCNT_T, # Number of free blocks for unpriviledged users | ||
:f_files, FSBLKCNT_T, # Number of inodes | ||
:f_ffree, FSBLKCNT_T, # Number of free inodes | ||
:f_favail, FSBLKCNT_T, # Number of free inodes for unprivilged users | ||
:f_fsid, :ulong, # Filesystem ID | ||
:f_flag, :ulong, # Mount Flags | ||
:f_namemax, :ulong # Max filename length | ||
] | ||
|
||
# Linux has this at the end of the struct and if we don't include | ||
# it we end up getting a memory corruption error when th object | ||
# gets GCd. | ||
if RbConfig::CONFIG['host_os'] =~ /linux/i | ||
spec << :f_spare | ||
spec << [:int, 6] | ||
end | ||
|
||
layout(*spec) | ||
end | ||
|
||
def initialize(path) | ||
@statvfs = stat(path) | ||
end | ||
|
||
# | ||
# @returns [Integer] Free inodes on the given filesystem | ||
# | ||
def free_inodes | ||
@statvfs[:f_favail] | ||
end | ||
|
||
# | ||
# @returns [Integer] Free space in KB on the given filesystem | ||
# | ||
def free_space | ||
# Since we are running as root we could report f_bfree but will | ||
# stick with f_bavail since it will typically be more | ||
# conservative. | ||
(@statvfs[:f_frsize] * @statvfs[:f_bavail])/1024 | ||
end | ||
|
||
private | ||
|
||
def stat(path) | ||
statvfs = Statvfs.new | ||
if statvfs(path, statvfs.to_ptr) != 0 | ||
raise 'statvfs: ' + strerror(FFI.errno) | ||
end | ||
statvfs | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be hard to statfs for this, too? I've got the impression that this would let us stay clear of some potential compatibility issues...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind 😄