class Solaris::Patchdiag

Class to represent the Oracle patchdiag “database” (file). See the following Oracle support publication for format: support.oracle.com/CSP/main/article?cmd=show&type=NOT&doctype=REFERENCE&id=1019527.1

Constants

DEFAULT_XREF_FILE

Default patchdiag.xref file, as for Patch Check Advanced cache

DEFAULT_XREF_URL

URL of latest patchdiag.xref from Oracle.

Public Class Methods

download!(opts={}) click to toggle source

Download the patchdiag database and return it as a string. Note the contents will be returned as a string but not saved to disk unless :to_file or :to_dir are given. For the options hash argument see Solaris::Util.download!

# File lib/solaris/patchdiag.rb, line 40
def Patchdiag.download!(opts={})
  url = opts.delete( :url ) || DEFAULT_XREF_URL
  Util.download!( url, opts )
end
new(xref_file=DEFAULT_XREF_FILE) click to toggle source

Create a new patchdiag database object by reading the given xref file (this may be a filename (string) or a fileish object (File, StringIO)). If no xref file is given then the default is read (/var/tmp/patchdiag.xref); this is the cache file used by Patch Check Advanced (pca).

# File lib/solaris/patchdiag.rb, line 28
def initialize(xref_file=DEFAULT_XREF_FILE)
  xref_file = File.new( xref_file ) if xref_file.is_a?( String )
  @_entries = xref_file.
    readlines.
    reject { |line| line =~ %r^#|^\s*$/ }. # discard comments, blanks
    map { |line| PatchdiagEntry.new( line ) }
end
open(xref_file=DEFAULT_XREF_FILE) { |patchdiag| ... } click to toggle source

Open the given optional patchdiag xref file and yield to the optional block.

# File lib/solaris/patchdiag.rb, line 47
def Patchdiag.open(xref_file=DEFAULT_XREF_FILE, &blk)
  patchdiag = Patchdiag.new( xref_file )
  if block_given?
    yield patchdiag
  else
    patchdiag
  end
end

Public Instance Methods

clone() click to toggle source

Create and return a deep copy of this object.

# File lib/solaris/patchdiag.rb, line 57
def clone
  Marshal.load( Marshal.dump( self ) )
end
each(&blk) click to toggle source

For Enumerator module: yields each Solaris::PatchdiagEntry in turn.

# File lib/solaris/patchdiag.rb, line 63
def each(&blk)
  @_entries.each( &blk )
end
find(patch) click to toggle source

Returns an array of Solaris::PatchdiagEntry from the patchdiag.xref with the given patch number (a String like xxxxxx-yy or xxxxxx or a Solaris::Patch), sorted by minor number. If both a major and minor number are supplied (xxxxxx-yy) then returned entries (normally only one) will match exactly. If only a major number (xxxxxx) is supplied then all entries with that major number are returned. Returns an empty array if no such patches can be found. This method overrides Enumerable#find.

# File lib/solaris/patchdiag.rb, line 75
def find(patch)
  patch = Patch.new( patch.to_s )
  property = patch.minor ? :to_s : :major
  comparator = patch.send( property )
  entries.select { |pde| pde.patch.send( property ) == comparator }
end
last() click to toggle source

Strangely Enumerable module does not define Enumerable#last (although it does define Enumerable#first) so we define last here.

# File lib/solaris/patchdiag.rb, line 84
def last
  entries.last
end
latest(patch) click to toggle source

Return the Solaris::PatchdiagEntry of the latest version of the given patch (a String like xxxxxx-yy or xxxxxx or a Solaris::Patch). Throws Solaris::Patch::NotFound if the patch cannot be found in patchdiag.xref.

# File lib/solaris/patchdiag.rb, line 92
def latest(patch)
  major = Patch.new( patch.to_s ).major
  find( major ).max ||
    raise( Solaris::Patch::NotFound,
          "Cannot find patch #{patch} in patchdiag.xref" )
end
sort(&blk) click to toggle source

Returns a (deep) copy of self with the entries sorted, takes an optional block. This method overrides Enumerable#sort. See also #sort!.

# File lib/solaris/patchdiag.rb, line 102
def sort(&blk)
  clone.sort!( &blk )
end
sort!(&blk) click to toggle source

Returns self with the entries sorted in place, takes an optional block. See also #sort.

# File lib/solaris/patchdiag.rb, line 108
def sort!(&blk)
  # use @_entries since #entries returns a copy
  @_entries.sort!( &blk )
  self
end
successor(patch) click to toggle source

Return the Solaris::PatchdiagEntry of the latest non-obsolete successor of this patch. This is a convenience method for successors.last.

# File lib/solaris/patchdiag.rb, line 153
def successor(patch)
  latest( successors( patch ).last )
end
successors(patch, ancestors=[]) click to toggle source

Return an array of Solaris::Patch of the successors to the given patch terminating in the latest non-obsolete successor (where that exists).

Throws Solaris::Patch::NotFound if the patch or any of its named successors cannot be found in patchdiag.xref, or if no later version of the patch exists.

Throws Solaris::Patch::SuccessorLoop if the successor of a patch refers to a patch that has already been referenced (an ancestor).

The ancestors parameter is a recursion accumulator and should not normally be assigned to by callers.

# File lib/solaris/patchdiag.rb, line 127
def successors(patch, ancestors=[])
  patch = Patch.new( patch.to_s )
  raise Solaris::Patch::SuccessorLoop,
    "Loop detected for patch #{patch} with ancestors #{ancestors.inspect}" if ancestors.include?( patch )
  ancestors << patch
  if ! patch.minor # patch has no minor number
    successors( latest( patch ).patch, ancestors )
  elsif ! entry = find( patch ).last # explicit patch not found
    latest_patch = latest( patch ).patch
    raise Solaris::Patch::NotFound,
      "Patch #{patch} not found and has no later version" if latest_patch.minor <= patch.minor
    successors( latest_patch, ancestors )
  else
    if entry.obsolete?
      succ = entry.successor
      successors( succ, ancestors )
    elsif entry.bad?
      raise BadSuccessor, "Terminal successor #{patch} is bad/withdrawn"
    else
      ancestors
    end
  end
end
to_s() click to toggle source

Returns a string representation of the patchdiag.xref. All comments and blank lines are elided.

# File lib/solaris/patchdiag.rb, line 159
def to_s
  entries.join("\n")
end
Also aliased as: to_str
to_str() click to toggle source
Alias for: to_s