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

Inherits:
AuthStore show all
Defined in:
lib/vendor/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

#clear_deprecation_warnings, #deprecation_warning, #send_log

Constructor Details

#initialize(name, path = nil) ⇒ Mount

Create out object. It must have a name.



472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 472

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.



407
408
409
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 407

def name
  @name
end

Instance Method Details

#clientmap(client) ⇒ Object

Create a map for a specific client.



416
417
418
419
420
421
422
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 416

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.



608
609
610
611
612
613
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 608

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.



425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 425

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)


447
448
449
450
451
452
453
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 447

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.



457
458
459
460
461
462
463
464
465
466
467
468
469
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 457

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



489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 489

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”.



636
637
638
639
640
641
642
643
644
645
646
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 636

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.



525
526
527
528
529
530
531
532
533
534
535
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 525

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.



538
539
540
541
542
543
544
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 538

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

#path=(path) ⇒ Object

Set the path.



547
548
549
550
551
552
553
554
555
556
557
558
559
560
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 547

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)


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

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

#properties(obj) ⇒ Object

Return the current values for the object.



569
570
571
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 569

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.



519
520
521
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 519

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

#reclist(abspath, recurse, ignore) ⇒ Object



650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 650

def reclist(abspath, recurse, ignore)
  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.



575
576
577
578
579
580
581
582
583
584
585
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 575

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



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

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

#to_sObject



592
593
594
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 592

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)


598
599
600
601
602
603
604
# File 'lib/vendor/puppet/network/handler/fileserver.rb', line 598

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