class MogileFS::Admin

MogileFS administration client, this has little real-world usage and is considered a work-in-progress

Public Instance Methods

change_device_state(host, device, state) click to toggle source

Changes the device status of device on host to state which can be 'alive', 'down', or 'dead'.

# File lib/mogilefs/admin.rb, line 299
def change_device_state(host, device, state)
  raise MogileFS::ReadOnlyError if readonly?
  ! @backend.set_state(:host => host, :device => device, :state => state).nil?
end
change_device_weight(host, device, weight) click to toggle source

Changes the device weight of device on host to weight. weight should be a non-negative Integer. Devices with higher weight values are more likely to be chosen for reads and writes.

# File lib/mogilefs/admin.rb, line 308
def change_device_weight(host, device, weight)
  raise MogileFS::ReadOnlyError if readonly?
  opts = { :host => host, :device => device, :weight => weight }
  ! @backend.set_weight(opts).nil?
end
clear_cache() click to toggle source

Clears the tracker caches. Not implemented in all versions of MogileFS

# File lib/mogilefs/admin.rb, line 325
def clear_cache
  @backend.clear_cache
end
create_class(domain, klass, policy) click to toggle source

Creates a new class in domain named klass with policy for replication. Raises on failure.

# File lib/mogilefs/admin.rb, line 229
def create_class(domain, klass, policy)
  modify_class(domain, klass, policy, :create)
end
create_device(host, devid, opts = {}) click to toggle source

Creates device with Integer devid on host host may be an integer for hostid or String for hostname

# File lib/mogilefs/admin.rb, line 278
def create_device(host, devid, opts = {})
  raise MogileFS::ReadOnlyError if readonly?
  opts = opts.dup

  case host
  when Integer
    opts[:hostid] = host
  when String
    opts[:hostname] = host
  else
    raise ArgumentError, "host=#{host.inspect} is not a String or Integer"
  end

  opts[:devid] = devid
  ! @backend.create_device(opts).nil?
end
create_domain(domain) click to toggle source

Creates a new domain named domain. Returns nil if creation failed.

# File lib/mogilefs/admin.rb, line 210
def create_domain(domain)
  raise MogileFS::ReadOnlyError if readonly?
  res = @backend.create_domain :domain => domain
  res ? res['domain'] : nil
end
create_host(host, args = {}) click to toggle source

Creates a new host named host. args must contain :ip and :port. Returns true if successful, false if not.

# File lib/mogilefs/admin.rb, line 253
def create_host(host, args = {})
  raise ArgumentError, "Must specify ip and port" unless        args.include? :ip and args.include? :port

  modify_host(host, args, 'create')
end
delete_class(domain, klass) click to toggle source

Removes class klass from domain. Returns true if successful. Raises on failure

# File lib/mogilefs/admin.rb, line 245
def delete_class(domain, klass)
  ! @backend.delete_class(:domain => domain, :class => klass).nil?
end
delete_domain(domain) click to toggle source

Deletes domain. Returns true if successful, raises MogileFS::Backend::DomainNotFoundError if not

# File lib/mogilefs/admin.rb, line 220
def delete_domain(domain)
  raise MogileFS::ReadOnlyError if readonly?
  ! @backend.delete_domain(:domain => domain).nil?
end
delete_host(host) click to toggle source

Deletes host host. Returns nil on failure.

# File lib/mogilefs/admin.rb, line 270
def delete_host(host)
  raise MogileFS::ReadOnlyError if readonly?
  ! @backend.delete_host(:host => host).nil?
end
each_fid() { |fid| ... } click to toggle source

Enumerates fids using list_fids. Returns the number of valid fids processed

# File lib/mogilefs/admin.rb, line 10
def each_fid
  low = -1
  rv = 0
  begin
    fids = list_fids(low)
    fids.each { |fid| yield fid }
    rv += fids.size
  end while last = fids[-1] and low = last["fid"]
  rv
end
get_devices(devid = nil) click to toggle source

Returns an Array of device status Hashes. If devid is given only that device is returned.

admin.get_devices 1

Returns:

[{"status"=>"alive",
  "mb_asof"=>nil,
  "mb_free"=>666000,
  "devid"=>1,
  "hostid"=>1,
  "mb_used"=>666,
  "utilization"=>0.0,
  "reject_bad_md5"=>false,
  "observed_state"=>"writeable",
  "mb_total"=>666666}]
# File lib/mogilefs/admin.rb, line 64
def get_devices(devid = nil)
  to_i = %w(mb_asof mb_free mb_used mb_total devid weight hostid)
  want = %w(status reject_bad_md5 observed_state utilization).concat(to_i)
  rv = @backend.get_devices(devid ? { :devid => devid } : {})
  rv = clean('devices', 'dev', rv, true, to_i, want)

  rv.each do |row|
    u = row["utilization"] and
      row["utilization"] = nil == u ? nil : u.to_f

    case row["observed_state"]
    when ""
      row["observed_state"] = nil
    end

    # be sure we do not set this at all for pre-2.60 MogileFS-Server
    case row["reject_bad_md5"]
    when "1"
      row["reject_bad_md5"] = true
    when "0"
      row["reject_bad_md5"] = false
    end
  end
end
get_domains() click to toggle source

Returns the domains and classes, and their policies present in the mogilefs.

admin.get_domains

Returns (on newer MogileFS servers):

{
  "test" => {
    "default" => {
      "mindevcount" => 2,
      "replpolicy" => "MultipleHosts()",
      "hashtype => nil,
    }
  }
}

Returns (on older MogileFS servers without replication policies):

{"test"=>{"normal"=>3, "default"=>2}}
# File lib/mogilefs/admin.rb, line 178
def get_domains
  res = @backend.get_domains
  have_replpolicy = false

  domains = {}
  to_i = %w(mindevcount)
  want = %w(name replpolicy hashtype mindevcount)
  (1..res['domains'].to_i).each do |i|
    domain = clean("domain#{i}classes", "domain#{i}class", res, false, to_i,
                   want)
    tmp = domains[res["domain#{i}"]] = {}
    domain.each do |d|
      tmp[d.delete("name")] = d
      have_replpolicy ||= d.include?("replpolicy")
    end
  end

  # only for MogileFS 1.x?, maybe we can drop support for this...
  unless have_replpolicy
    domains.each do |namespace, class_data|
      class_data.each do |class_name, data|
        class_data[class_name] = data["mindevcount"]
      end
    end
  end

  domains
end
get_hosts(hostid = nil) click to toggle source

Returns an Array of host status Hashes. If hostid is given only that host is returned.

admin.get_hosts 1

Returns:

[{"status"=>"alive",
  "http_get_port"=>nil,
  "http_port"=>7500,
  "hostid"=>1,
  "hostip"=>"192.168.1.2",
  "hostname"=>"rur-1",
  "altip"=>"",
  "altmask"=>""}]
# File lib/mogilefs/admin.rb, line 38
def get_hosts(hostid = nil)
  to_i = %w(hostid http_port http_get_port)
  want = %w(status hostip hostname altip altmask).concat(to_i)
  rv = @backend.get_hosts(hostid ? { :hostid => hostid } : {})
  clean('hosts', 'host', rv, true, to_i, want)
end
get_stats(type = 'all') click to toggle source

Returns a statistics structure representing the state of mogilefs.

*** This command no longer works with recent versions of MogileFS *** *** Use mogstats(1) from the MogileFS::Utils package on CPAN *** *** We will remove this method in 4.x ***

admin.get_stats

Returns:

{"fids"=>{"max"=>"99", "count"=>"2"},
 "device"=>
  [{"status"=>"alive", "files"=>"2", "id"=>"1", "host"=>"rur-1"},
   {"status"=>"alive", "files"=>"2", "id"=>"2", "host"=>"rur-2"}],
 "replication"=>
  [{"files"=>"2", "class"=>"normal", "devcount"=>"2", "domain"=>"test"}],
 "file"=>[{"files"=>"2", "class"=>"normal", "domain"=>"test"}]}
# File lib/mogilefs/admin.rb, line 136
def get_stats(type = 'all')
  res = @backend.stats type => 1
  stats = {}

  stats['device'] = clean 'devicescount', 'devices', res, false
  stats['file'] = clean 'filescount', 'files', res, false
  stats['replication'] = clean 'replicationcount', 'replication', res, false

  if res['fidmax'] or res['fidcount'] then
    stats['fids'] = {
      'max' => res['fidmax'].to_i,
      'count' => res['fidcount'].to_i
    }
  end

  %w(device file replication).each do |s|
    stats.delete(s) if stats[s].empty?
  end

  stats
end
list_fids(from_fid, count = 100) click to toggle source

Returns an Array of fid Hashes from from_fid, limited to count

admin.list_fids 0, 100

Returns:

[{"fid"=>99,
  "class"=>"normal",
  "domain"=>"test",
  "devcount"=>2,
  "length"=>4,
  "key"=>"file_key"},
 {"fid"=>82,
  "class"=>"normal",
  "devcount"=>2,
  "domain"=>"test",
  "length"=>9,
  "key"=>"new_new_key"}]
# File lib/mogilefs/admin.rb, line 109
def list_fids(from_fid, count = 100)
  to_i = %w(fid devcount length)
  want = %w(domain class key).concat(to_i)
  rv = @backend.list_fids(:from => from_fid, :to => count)
  # :to is now :count internally in mogilefsd
  clean('fid_count', 'fid_', rv, true, to_i, want)
end
replicate_now() click to toggle source

reschedules all deferred replication, returns a hash with the number of files rescheduled:

admin.replicate_now => { "count" => 5 }
# File lib/mogilefs/admin.rb, line 318
def replicate_now
  rv = @backend.replicate_now
  rv["count"] = rv["count"].to_i
  rv
end
update_class(domain, klass, policy) click to toggle source

Updates class klass in domain with policy for replication. Raises on failure.

# File lib/mogilefs/admin.rb, line 237
def update_class(domain, klass, policy)
  modify_class(domain, klass, policy, :update)
end
update_host(host, args = {}) click to toggle source

Updates host with args. Returns true if successful, false if not.

# File lib/mogilefs/admin.rb, line 263
def update_host(host, args = {})
  modify_host(host, args, 'update')
end

Protected Instance Methods

clean(count, prefix, res, underscore = true, to_i = [], want = nil) click to toggle source

Turns the response res from the backend into an Array of Hashes from 1 to res. If underscore is true then a '_' character is assumed between the prefix and the hash key value.

res = {"host1_remoteroot"=>"/mnt/mogilefs/rur-1",
       "host1_hostname"=>"rur-1",
       "host1_hostid"=>"1",
       "host1_http_get_port"=>"",
       "host1_altip"=>"",
       "hosts"=>"1",
       "host1_hostip"=>"",
       "host1_http_port"=>"",
       "host1_status"=>"alive",
       "host1_altmask"=>""}
admin.clean 'hosts', 'host', res

Returns:

[{"status"=>"alive",
  "http_get_port"=>nil,
  "http_port"=>7600,
  "hostid"=>1,
  "hostip"=>"192.168.1.3",
  "hostname"=>"rur-1",
  "altip"=>"",
  "altmask"=>""}]
# File lib/mogilefs/admin.rb, line 389
def clean(count, prefix, res, underscore = true, to_i = [], want = nil)
  empty = ""
  underscore = underscore ? '_' : empty

  # convert array to hash for O(1) lookups
  to_i = to_i.inject({}) { |m,k| m[k] = m }
  if want
    (1..res[count].to_i).map do |i|
      row = {}
      want.each do |k|
        v = res["#{prefix}#{i}#{underscore}#{k}"] or next
        row[k] = to_i.include?(k) ? (empty == v ? nil : v.to_i) : v
      end
      row
    end
  else
    keys = res.keys
    (1..res[count].to_i).map do |i|
      re = /^#{prefix}#{i}#{underscore}/
      row = {}
      keys.grep(re).each do |k|
        v = res[k]
        k = k.sub(re, empty)
        row[k] = to_i.include?(k) ? (empty == v ? nil : v.to_i) : v
      end
      row
    end
  end
end
modify_class(domain, klass, policy, action) click to toggle source

Modifies klass on domain to store files on mindevcount devices via action. Returns the class name if successful, raises if not

# File lib/mogilefs/admin.rb, line 335
def modify_class(domain, klass, policy, action)
  raise MogileFS::ReadOnlyError if readonly?
  args = { :domain => domain, :class => klass }
  case policy
  when Integer
    args[:mindevcount] = policy
  when String
    args[:replpolicy] = policy
  when Hash
    args.merge!(policy)
  else
    raise ArgumentError,
         "policy=#{policy.inspect} not understood for #{action}_class"
  end
  @backend.__send__("#{action}_class", args)["class"]
end
modify_host(host, args = {}, action = 'create') click to toggle source

Modifies host using args via action. Returns true if successful, false if not.

# File lib/mogilefs/admin.rb, line 356
def modify_host(host, args = {}, action = 'create')
  args[:host] = host
  ! @backend.__send__("#{action}_host", args).nil?
end