Class: Puppet::Network::Handler::FileServer::Mount

Inherits:
AuthStore show all
Defined in:
lib/puppet/network/handler/fileserver.rb

Overview

A simple class for wrapping mount points. Instances of this class don’t know about the enclosing object; they’re mainly just used for authorization.

Direct Known Subclasses

PluginMount

Constant Summary collapse

@@syncs =
{}
@@files =
{}

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from AuthStore

#allow, #allowed?, #deny, #empty?, #globalallow?, #interpolate, #reset_interpolation

Methods included from Util::Logging

#send_log

Constructor Details

#initialize(name, path = nil) ⇒ Mount

Create out object. It must have a name.



467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
# File 'lib/puppet/network/handler/fileserver.rb', line 467

def initialize(name, path = nil)
  unless name =~ %r{^[-\w]+$}
    raise FileServerError, "Invalid name format '#{name}'"
  end
  @name = name

  if path
    self.path = path
  else
    @path = nil
  end

  @files = {}

  super()
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



402
403
404
# File 'lib/puppet/network/handler/fileserver.rb', line 402

def name
  @name
end

Instance Method Details

#clientmap(client) ⇒ Object

Create a map for a specific client.



411
412
413
414
415
416
417
# File 'lib/puppet/network/handler/fileserver.rb', line 411

def clientmap(client)
  {
    "h" => client.sub(/\..*$/, ""),
    "H" => client,
    "d" => client.sub(/[^.]+\./, "") # domain name
  }
end

#copy(name, path) ⇒ Object

Return a new mount with the same properties as self, except with a different name and path.



603
604
605
606
607
608
# File 'lib/puppet/network/handler/fileserver.rb', line 603

def copy(name, path)
  result = self.clone
  result.path = path
  result.instance_variable_set(:@name, name)
  result
end

#expand(path, client = nil) ⇒ Object

Replace % patterns as appropriate.



420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
# File 'lib/puppet/network/handler/fileserver.rb', line 420

def expand(path, client = nil)
  # This map should probably be moved into a method.
  map = nil

  if client
    map = clientmap(client)
  else
    Puppet.notice "No client; expanding '#{path}' with local host"
    # Else, use the local information
    map = localmap
  end
  path.gsub(/%(.)/) do |v|
    key = $1
    if key == "%"
      "%"
    else
      map[key] || v
    end
  end
end

#expandable?Boolean

Do we have any patterns in our path, yo?

Returns:

  • (Boolean)


442
443
444
445
446
447
448
# File 'lib/puppet/network/handler/fileserver.rb', line 442

def expandable?
  if defined?(@expandable)
    @expandable
  else
    false
  end
end

#file_path(relative_path, node = nil) ⇒ Object

Return a fully qualified path, given a short path and possibly a client name.



452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'lib/puppet/network/handler/fileserver.rb', line 452

def file_path(relative_path, node = nil)
  full_path = path(node)

  unless full_path
    p self
    raise ArgumentError.new("Mounts without paths are not usable") unless full_path
  end

  # If there's no relative path name, then we're serving the mount itself.
  return full_path unless relative_path and relative_path != "/"

  File.join(full_path, relative_path)
end

#fileobj(path, links, client) ⇒ Object



484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
# File 'lib/puppet/network/handler/fileserver.rb', line 484

def fileobj(path, links, client)
  obj = nil
  if obj = @files[file_path(path, client)]
    # This can only happen in local fileserving, but it's an
    # important one.  It'd be nice if we didn't just set
    # the check params every time, but I'm not sure it's worth
    # the effort.
    obj[:audit] = CHECKPARAMS
  else

    obj = Puppet::Type.type(:file).new(

      :name => file_path(path, client),

      :audit => CHECKPARAMS
    )
    @files[file_path(path, client)] = obj
  end

  if links == :manage
    links = :follow
  end

  # This, ah, might be completely redundant
  obj[:links] = links unless obj[:links] == links

  obj
end

#list(relpath, recurse, ignore, client = nil) ⇒ Object

List the contents of the relative path relpath of this mount.

recurse is the number of levels to recurse into the tree, or false to provide no recursion or true if you just want to go for broke.

ignore is an array of filenames to ignore when traversing the list.

The return value of this method is a complex nest of arrays, which describes a directory tree. Each file or directory is represented by an array, where the first element is the path of the file (relative to the root of the mount), and the second element is the type. A directory is represented by an array as well, where the first element is a “directory” array, while the remaining elements are other file or directory arrays. Confusing? Hell yes. As an added bonus, all names must start with a slash, because… well, I’m fairly certain a complete explanation would involve the words “crack pipe” and “bad batch”.



631
632
633
634
635
636
637
638
639
640
641
# File 'lib/puppet/network/handler/fileserver.rb', line 631

def list(relpath, recurse, ignore, client = nil)
  abspath = file_path(relpath, client)
  if FileTest.exists?(abspath)
    if FileTest.directory?(abspath) and recurse
      return reclist(abspath, recurse, ignore)
    else
      return [["/", File.stat(abspath).ftype]]
    end
  end
  nil
end

#localmapObject

Cache this manufactured map, since if it’s used it’s likely to get used a lot.



520
521
522
523
524
525
526
527
528
529
530
# File 'lib/puppet/network/handler/fileserver.rb', line 520

def localmap
  unless defined?(@@localmap)
    @@localmap = {
      "h" =>  Facter.value("hostname"),
      "H" => [Facter.value("hostname"),
        Facter.value("domain")].join("."),
      "d" =>  Facter.value("domain")
    }
  end
  @@localmap
end

#path(client = nil) ⇒ Object

Return the path as appropriate, expanding as necessary.



533
534
535
536
537
538
539
# File 'lib/puppet/network/handler/fileserver.rb', line 533

def path(client = nil)
  if expandable?
    return expand(@path, client)
  else
    return @path
  end
end

#path=(path) ⇒ Object

Set the path.



542
543
544
545
546
547
548
549
550
551
552
553
554
555
# File 'lib/puppet/network/handler/fileserver.rb', line 542

def path=(path)
  # FIXME: For now, just don't validate paths with replacement
  # patterns in them.
  if path =~ /%./
    # Mark that we're expandable.
    @expandable = true
  else
    raise FileServerError, "#{path} does not exist" unless FileTest.exists?(path)
    raise FileServerError, "#{path} is not a directory" unless FileTest.directory?(path)
    raise FileServerError, "#{path} is not readable" unless FileTest.readable?(path)
    @expandable = false
  end
  @path = path
end

#path_exists?(relpath, client = nil) ⇒ Boolean

Verify that the path given exists within this mount’s subtree.

Returns:

  • (Boolean)


559
560
561
# File 'lib/puppet/network/handler/fileserver.rb', line 559

def path_exists?(relpath, client = nil)
  File.exists?(file_path(relpath, client))
end

#properties(obj) ⇒ Object

Return the current values for the object.



564
565
566
# File 'lib/puppet/network/handler/fileserver.rb', line 564

def properties(obj)
  obj.retrieve.inject({}) { |props, ary| props[ary[0].name] = ary[1]; props }
end

#read_file(relpath, client) ⇒ Object

Read the contents of the file at the relative path given.



514
515
516
# File 'lib/puppet/network/handler/fileserver.rb', line 514

def read_file(relpath, client)
  File.read(file_path(relpath, client))
end

#reclist(abspath, recurse, ignore) ⇒ Object



643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
# File 'lib/puppet/network/handler/fileserver.rb', line 643

def reclist(abspath, recurse, ignore)
  require 'puppet/file_serving'
  require 'puppet/file_serving/fileset'
  if recurse.is_a?(Fixnum)
    args = { :recurse => true, :recurselimit => recurse, :links => :follow }
  else
    args = { :recurse => recurse, :links => :follow }
  end
  args[:ignore] = ignore if ignore
  fs = Puppet::FileServing::Fileset.new(abspath, args)
  ary = fs.files.collect do |file|
    if file == "."
      file = "/"
    else
      file = File.join("/", file )
    end
    stat = fs.stat(File.join(abspath, file))
    next if stat.nil?
    [ file, stat.ftype ]
  end

  ary.compact
end

#subdir(dir = nil, client = nil) ⇒ Object

Retrieve a specific directory relative to a mount point. If they pass in a client, then expand as necessary.



570
571
572
573
574
575
576
577
578
579
580
# File 'lib/puppet/network/handler/fileserver.rb', line 570

def subdir(dir = nil, client = nil)
  basedir = self.path(client)

  dirname = if dir
    File.join(basedir, *dir.split("/"))
  else
    basedir
  end

  dirname
end

#sync(path) ⇒ Object



582
583
584
585
# File 'lib/puppet/network/handler/fileserver.rb', line 582

def sync(path)
  @@syncs[path] ||= Sync.new
  @@syncs[path]
end

#to_sObject



587
588
589
# File 'lib/puppet/network/handler/fileserver.rb', line 587

def to_s
  "mount[#{@name}]"
end

#valid?Boolean

Verify our configuration is valid. This should really check to make sure at least someone will be allowed, but, eh.

Returns:

  • (Boolean)


593
594
595
596
597
598
599
# File 'lib/puppet/network/handler/fileserver.rb', line 593

def valid?
  if name == MODULES
    return @path.nil?
  else
    return ! @path.nil?
  end
end