Class: Solaris::Patchdiag
- Inherits:
-
Object
- Object
- Solaris::Patchdiag
- Includes:
- Enumerable
- Defined in:
- lib/solaris/patchdiag.rb
Overview
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
Constant Summary collapse
- DEFAULT_XREF_FILE =
Default patchdiag.xref file, as for Patch Check Advanced cache
'/var/tmp/patchdiag.xref'
- DEFAULT_XREF_URL =
URL of latest patchdiag.xref from Oracle.
'https://getupdates.oracle.com/reports/patchdiag.xref'
Instance Attribute Summary collapse
-
#date ⇒ Object
Return the date parsed from the patchdiag.xref comment lines.
-
#footer ⇒ Object
The array of lines that comprise the footer, sans trailing newline.
-
#header ⇒ Object
The array of lines that comprise the header, sans trailing newline.
Class Method Summary collapse
-
.download!(opts = {}) ⇒ Object
Download the patchdiag database and return it as a string.
-
.open(xref_file = DEFAULT_XREF_FILE, &blk) ⇒ Object
Open the given optional patchdiag xref file and yield to the optional block.
Instance Method Summary collapse
-
#clone ⇒ Object
Create and return a deep copy of this object.
-
#each(&blk) ⇒ Object
For Enumerator module: yields each Solaris::PatchdiagEntry in turn.
-
#find(patch) ⇒ Object
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.
-
#initialize(xref_file = DEFAULT_XREF_FILE) ⇒ Patchdiag
constructor
Create a new patchdiag database object by reading the given xref file (this may be a filename (string) or a fileish object (File, StringIO)).
-
#last ⇒ Object
Strangely Enumerable module does not define Enumerable#last (although it does define Enumerable#first) so we define last here.
-
#latest(patch) ⇒ Object
Return the Solaris::PatchdiagEntry of the latest version of the given patch (a String like xxxxxx-yy or xxxxxx or a Solaris::Patch).
-
#sort(&blk) ⇒ Object
Returns a (deep) copy of
self
with the entries sorted, takes an optional block. -
#sort!(&blk) ⇒ Object
Returns
self
with the entries sorted in place, takes an optional block. -
#successor(patch) ⇒ Object
Return the Solaris::PatchdiagEntry of the latest non-obsolete successor of this patch.
-
#successors(patch, ancestors = []) ⇒ Object
Return an array of Solaris::Patch of the successors to the given patch terminating in the latest non-obsolete successor (where that exists).
-
#to_s ⇒ Object
(also: #to_str)
Returns a string representation of the patchdiag.xref.
Constructor Details
#initialize(xref_file = DEFAULT_XREF_FILE) ⇒ Patchdiag
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).
36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/solaris/patchdiag.rb', line 36 def initialize(xref_file=DEFAULT_XREF_FILE) xref_file = File.new(xref_file) if xref_file.is_a?(String) @entries, @header, @footer = [], [], [] xref_file.each_line do |line| if line =~ /^\d/ @entries << PatchdiagEntry.new(line) else (@entries.empty? ? @header : @footer) << line.chomp end end end |
Instance Attribute Details
#date ⇒ Object
Return the date parsed from the patchdiag.xref comment lines.
74 75 76 77 78 |
# File 'lib/solaris/patchdiag.rb', line 74 def date ## PATCHDIAG TOOL CROSS-REFERENCE FILE AS OF Jan/23/14 ## @date ||= @header.find { |line| line =~ /\s(\w\w\w\/\d\d\/\d\d)\s/ } && Date.parse($1) end |
#footer ⇒ Object
The array of lines that comprise the footer, sans trailing newline.
29 30 31 |
# File 'lib/solaris/patchdiag.rb', line 29 def @footer end |
#header ⇒ Object
The array of lines that comprise the header, sans trailing newline.
26 27 28 |
# File 'lib/solaris/patchdiag.rb', line 26 def header @header end |
Class Method Details
.download!(opts = {}) ⇒ Object
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!
52 53 54 55 |
# File 'lib/solaris/patchdiag.rb', line 52 def Patchdiag.download!(opts={}) url = opts.delete(:url) || DEFAULT_XREF_URL Util.download!(url, opts) end |
.open(xref_file = DEFAULT_XREF_FILE, &blk) ⇒ Object
Open the given optional patchdiag xref file and yield to the optional block.
59 60 61 62 63 64 65 66 |
# File 'lib/solaris/patchdiag.rb', line 59 def Patchdiag.open(xref_file=DEFAULT_XREF_FILE, &blk) patchdiag = Patchdiag.new(xref_file) if block_given? yield patchdiag else patchdiag end end |
Instance Method Details
#clone ⇒ Object
Create and return a deep copy of this object.
69 70 71 |
# File 'lib/solaris/patchdiag.rb', line 69 def clone Marshal.load(Marshal.dump(self)) end |
#each(&blk) ⇒ Object
For Enumerator module: yields each Solaris::PatchdiagEntry in turn.
82 83 84 |
# File 'lib/solaris/patchdiag.rb', line 82 def each(&blk) @entries.each(&blk) end |
#find(patch) ⇒ Object
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.
94 95 96 97 98 99 |
# File 'lib/solaris/patchdiag.rb', line 94 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 ⇒ Object
Strangely Enumerable module does not define Enumerable#last (although it does define Enumerable#first) so we define last here.
103 104 105 |
# File 'lib/solaris/patchdiag.rb', line 103 def last @entries.last end |
#latest(patch) ⇒ Object
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.
111 112 113 114 115 116 |
# File 'lib/solaris/patchdiag.rb', line 111 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) ⇒ Object
Returns a (deep) copy of self
with the entries sorted, takes an optional block. This method overrides Enumerable#sort. See also Solaris::Patchdiag#sort!.
121 122 123 |
# File 'lib/solaris/patchdiag.rb', line 121 def sort(&blk) clone.sort!(&blk) end |
#sort!(&blk) ⇒ Object
Returns self
with the entries sorted in place, takes an optional block. See also Solaris::Patchdiag#sort.
127 128 129 130 131 |
# File 'lib/solaris/patchdiag.rb', line 127 def sort!(&blk) # use @entries since #entries returns a copy @entries.sort!(&blk) self end |
#successor(patch) ⇒ Object
Return the Solaris::PatchdiagEntry of the latest non-obsolete successor of this patch. This is a convenience method for #successors.last.
172 173 174 |
# File 'lib/solaris/patchdiag.rb', line 172 def successor(patch) latest(successors(patch).last) end |
#successors(patch, ancestors = []) ⇒ Object
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.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/solaris/patchdiag.rb', line 146 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 ⇒ Object Also known as: to_str
Returns a string representation of the patchdiag.xref. All comments and blank lines are elided.
178 179 180 |
# File 'lib/solaris/patchdiag.rb', line 178 def to_s (@header + @entries + @footer).join("\n") << "\n" end |