class OpenShift::Runtime::Node

Constants

DEFAULT_MAX_ACTIVE_GEARS
DEFAULT_NODE_PROFILE
DEFAULT_NO_OVERCOMMIT_ACTIVE
DEFAULT_PAM_LIMITS
DEFAULT_PAM_LIMITS_DIR
DEFAULT_PAM_LIMITS_ORDER
DEFAULT_PAM_LIMITS_VARS
DEFAULT_PAM_SOFT_VARS
DEFAULT_QUOTA
DEFAULT_QUOTA_BLOCKS
DEFAULT_QUOTA_FILES

Public Class Methods

find_system_messages(pattern) click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 196
def self.find_system_messages(pattern)
  regex = Regexp.new(pattern)
  open('/var/log/messages') { |f| f.grep(regex) }.join("\n")
end
get_cartridge_list(list_descriptors = false, porcelain = false, oo_debug = false) click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 62
def self.get_cartridge_list(list_descriptors = false, porcelain = false, oo_debug = false)
  carts = []
  CartridgeRepository.instance.latest_versions do |cartridge|
    begin
      print "Loading #{cartridge.name}-#{cartridge.version}..." if oo_debug

      # Deep copy is necessary here because OpenShift::Cartridge makes destructive changes
      # to the hash passed to from_descriptor
      v1_manifest            = Marshal.load(Marshal.dump(cartridge.manifest))
      v1_manifest['Version'] = cartridge.version
      carts.push OpenShift::Cartridge.new.from_descriptor(v1_manifest)
      print "OK\n" if oo_debug
    rescue Exception => e
      print "ERROR\n" if oo_debug
      print "#{e.message}\n#{e.backtrace.inspect}\n" unless porcelain
    end
  end

  print "\n\n\n" if oo_debug

  output = ""
  if porcelain
    if list_descriptors
      output << "CLIENT_RESULT: "
      output << carts.map{|c| c.to_descriptor.to_yaml}.to_json
    else
      output << "CLIENT_RESULT: "
      output << carts.map{|c| c.name}.to_json
    end
  else
    if list_descriptors
      carts.each do |c|
        output << "Cartridge name: #{c.name}\n\nDescriptor:\n #{c.to_descriptor.inspect}\n\n\n"
      end
    else
      output << "Cartridges:\n"
      carts.each do |c|
        output << "\t#{c.name}\n"
      end
    end
  end
  output
end
get_gear_mountpoint() click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 131
def self.get_gear_mountpoint
  cartridge_path = OpenShift::Config.new.get("GEAR_BASE_DIR")

  oldpath=File.absolute_path(cartridge_path)
  olddev=File.stat(oldpath).dev
  while true
    newpath = File.dirname(oldpath)
    newdev  = File.stat(newpath).dev
    if (newpath == oldpath) or (newdev != olddev)
      break
    end
    oldpath = newpath
  end
  oldpath
end
get_pam_limits(uuid) click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 249
def self.get_pam_limits(uuid)
  resource = resource_limits
  limits_order = (resource.get('limits_order') or DEFAULT_PAM_LIMITS_ORDER)
  limits_file = PathUtils.join(DEFAULT_PAM_LIMITS_DIR, "#{limits_order}-#{uuid}.conf")

  limits = {}

  begin
    File.open(limits_file, File::RDONLY) do |f|
      f.each do |l|
        l.gsub!(/\#.*$/,'')
        l.strip!
        l.chomp!
        limset = l.split()
        if (limset[0] == uuid) and limset[2] and limset[3]
          limits[limset[2]]=limset[3]
        end
      end
    end
  rescue Errno::ENOENT
  end

  limits
end
get_quota(uuid) click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 106
def self.get_quota(uuid)
  begin
    Etc.getpwnam(uuid)
  rescue ArgumentError
    raise NodeCommandException.new(
              Utils::Sdk.translate_out_for_client("Unable to obtain quota user #{uuid} does not exist",
                                                  :error))
  end

  stdout, _, _ = Utils.oo_spawn("quota --always-resolve -w #{uuid}")
  results      = stdout.split("\n").grep(%r(^.*/dev/))
  if results.empty?
    raise NodeCommandException.new(
              Utils::Sdk.translate_out_for_client("Unable to obtain quota for user #{uuid}",
                                                  :error))
  end

  results = results.first.strip.split(' ')

  {device:      results[0],
   blocks_used: results[1].to_i, blocks_quota: results[2].to_i, blocks_limit: results[3].to_i,
   inodes_used: results[4].to_i, inodes_quota: results[5].to_i, inodes_limit: results[6].to_i
  }
end
init_pam_limits(uuid, limits={}) click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 215
def self.init_pam_limits(uuid, limits={})
  resource = resource_limits
  limits_order = (resource.get('limits_order') or DEFAULT_PAM_LIMITS_ORDER)
  limits_file = PathUtils.join(DEFAULT_PAM_LIMITS_DIR, "#{limits_order}-#{uuid}.conf")

  DEFAULT_PAM_LIMITS_VARS.each do |k|
    if not limits.has_key?(k)
      v = resource.get("limits_#{k}")
      if not v.nil?
        limits[k]=v
      end
    end
  end

  DEFAULT_PAM_LIMITS.each { |k, v| limits[k]=v unless limits.has_key?(k) }

  File.open(limits_file, File::RDWR | File::CREAT | File::TRUNC ) do |f|
    f.write("# PAM process limits for guest #{uuid}\n")
    f.write("# see limits.conf(5) for details\n")
    f.write("#Each line describes a limit for a user in the form:\n")
    f.write("#\n")
    f.write("#<domain>        <type>  <item>  <value>\n")
    limits.each do |k, v|
      if DEFAULT_PAM_SOFT_VARS.include?(k) and (v.to_i != 0)
        limtype = "soft"
      else
        limtype = "hard"
      end
      f.write("#{uuid}\t#{limtype}\t#{k}\t#{v}\n")
    end
    f.fsync
  end
end
init_pam_limits_all() click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 201
def self.init_pam_limits_all
  config = OpenShift::Config.new
  gecos = (config.get("GEAR_GECOS") || "OO application container")

  uuids=[]
  Etc.passwd do |pwent|
    uuids << pwent.name if pwent.gecos == gecos
  end

  uuids.each do |uuid|
    init_pam_limits(uuid)
  end
end
init_quota(uuid, blocksmax=nil, inodemax=nil) click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 181
def self.init_quota(uuid, blocksmax=nil, inodemax=nil)
  resource = resource_limits
  blocksmax = (blocksmax or resource.get('quota_blocks') or DEFAULT_QUOTA['quota_blocks'])
  inodemax  = (inodemax  or resource.get('quota_files')  or DEFAULT_QUOTA['quota_files'])
  self.set_quota(uuid, blocksmax.to_i, inodemax.to_i)
end
node_utilization() click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 304
def self.node_utilization
  res = Hash.new(nil)

  resource = resource_limits
  return res unless resource

  res['node_profile'] = resource.get('node_profile', DEFAULT_NODE_PROFILE)
  res['quota_blocks'] = resource.get('quota_blocks', DEFAULT_QUOTA_BLOCKS)
  res['quota_files'] = resource.get('quota_files', DEFAULT_QUOTA_FILES)
  res['no_overcommit_active'] = resource.get_bool('no_overcommit_active', DEFAULT_NO_OVERCOMMIT_ACTIVE)

  # use max_{active_,}gears if set in resource limits, or fall back to old "apps" names
  res['max_active_gears'] = (resource.get('max_active_gears') or resource.get('max_active_apps') or DEFAULT_MAX_ACTIVE_GEARS)

  #
  # Count number of git repos and gear status counts
  #
  res['git_repos_count'] = 0
  res['gears_total_count'] = 0
  res['gears_idled_count'] = 0
  res['gears_stopped_count'] = 0
  res['gears_started_count'] = 0
  res['gears_deploying_count'] = 0
  res['gears_unknown_count'] = 0
  OpenShift::Runtime::ApplicationContainer.all(nil, false).each do |app|
    # res['git_repos_count'] += 1 if ApplicationRepository.new(app).exists?
    res['gears_total_count'] += 1

    case app.state.value
    # expected values: building, deploying, started, idle, new, stopped, or unknown
    when 'idle'
      res['gears_idled_count'] += 1
    when 'stopped'
      res['gears_stopped_count'] += 1
    when 'started'
      res['gears_started_count'] += 1
    when *%w[new building deploying]
      res['gears_deploying_count'] += 1
    else # literally 'unknown' or something else
      res['gears_unknown_count'] += 1
    end
  end

  # consider a gear active unless explicitly not
  res['gears_active_count'] = res['gears_total_count'] - res['gears_idled_count'] - res['gears_stopped_count']
  res['gears_usage_pct'] = begin res['gears_total_count'] * 100.0 / res['max_active_gears'].to_f; rescue; 0.0; end
  res['gears_active_usage_pct'] = begin res['gears_active_count'] * 100.0 / res['max_active_gears'].to_f; rescue; 0.0; end
  res['capacity'] = res['gears_usage_pct'].to_s
  res['active_capacity'] = res['gears_active_usage_pct'].to_s
  return res
end
pam_freeze(uuid) click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 274
def self.pam_freeze(uuid)
  limits = self.get_pam_limits(uuid)
  limits["nproc"]=0
  init_pam_limits(uuid, limits)
end
remove_pam_limits(uuid) click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 294
def self.remove_pam_limits(uuid)
  resource = resource_limits
  limits_order = (resource.get('limits_order') or DEFAULT_PAM_LIMITS_ORDER)
  limits_file = PathUtils.join(DEFAULT_PAM_LIMITS_DIR, "#{limits_order}-#{uuid}.conf")
  begin
    File.unlink(limits_file)
  rescue Errno::ENOENT
  end
end
remove_pam_limits_all() click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 280
def self.remove_pam_limits_all
  config = OpenShift::Config.new
  gecos = (config.get("GEAR_GECOS") || "OO application container")

  uuids=[]
  Etc.passwd do |pwent|
    uuids << pwent.name if pwent.gecos == gecos
  end

  uuids.each do |uuid|
    remove_pam_limits(uuid)
  end
end
remove_quota(uuid) click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 188
def self.remove_quota(uuid)
  begin
    self.set_quota(uuid, 0, 0)
  rescue NodeCommandException
    # If the user no longer exists than it has no quota
  end
end
resource_limits() click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 50
def self.resource_limits
  unless @@resource_limits_cache
    limits = '/etc/openshift/resource_limits.conf'
    if File.readable? limits
      @@resource_limits_cache = OpenShift::Config.new(limits)
    else
      return nil
    end
  end
  return @@resource_limits_cache
end
set_quota(uuid, blocksmax, inodemax) click to toggle source
# File lib/openshift-origin-node/model/node.rb, line 147
def self.set_quota(uuid, blocksmax, inodemax)
  current_quota, current_inodes, cur_quota = 0, 0, nil

  begin
    cur_quota = get_quota(uuid)
  rescue NodeCommandException
    # keep defaults
  end

  unless nil == cur_quota
    current_quota  = cur_quota[:blocks_used]
    blocksmax      = cur_quota[:blocks_limit] if blocksmax.to_s.empty?
    current_inodes = cur_quota[:inodes_used]
    inodemax       = cur_quota[:inodes_limit] if inodemax.to_s.empty?
  end

  if current_quota > blocksmax.to_i
    raise NodeCommandException.new(
              Utils::Sdk.translate_out_for_client("Current usage #{current_quota} exceeds requested quota #{blocksmax}",
                                                  :error))
  end

  if current_inodes > inodemax.to_i
    raise NodeCommandException.new(
              Utils::Sdk.translate_out_for_client("Current inodes #{current_inodes} exceeds requested inodes #{inodemax}",
                                                  :error))
  end

  mountpoint      = self.get_gear_mountpoint
  cmd             = "setquota --always-resolve -u #{uuid} 0 #{blocksmax} 0 #{inodemax} -a #{mountpoint}"
  _, stderr, rc = Utils.oo_spawn(cmd)
  raise NodeCommandException.new "Error: #{stderr} executing command #{cmd}" unless rc == 0
end