Class: Katello::Util::CdnVarSubstitutor

Inherits:
Object
  • Object
show all
Defined in:
app/lib/katello/util/cdn_var_substitutor.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cdn_resource) ⇒ CdnVarSubstitutor

cdn_resource - an object providing access to CDN. It has to provide a get method that takes a path (e.g. /content/rhel/6.2/listing) and returns the body response)



9
10
11
12
13
14
# File 'app/lib/katello/util/cdn_var_substitutor.rb', line 9

def initialize(cdn_resource)
  @resource = cdn_resource
  @substitutions = Thread.current[:cdn_var_substitutor_cache] || {}
  @good_listings = Set.new
  @bad_listings = Set.new
end

Instance Attribute Details

#bad_listingsObject (readonly)

Returns the value of attribute bad_listings.



5
6
7
# File 'app/lib/katello/util/cdn_var_substitutor.rb', line 5

def bad_listings
  @bad_listings
end

#good_listingsObject (readonly)

Returns the value of attribute good_listings.



4
5
6
# File 'app/lib/katello/util/cdn_var_substitutor.rb', line 4

def good_listings
  @good_listings
end

Class Method Details

.with_cache(&_block) ⇒ Object

using substitutor from whithin the block makes sure that every request is made only once.



18
19
20
21
22
23
# File 'app/lib/katello/util/cdn_var_substitutor.rb', line 18

def self.with_cache(&_block)
  Thread.current[:cdn_var_substitutor_cache] = {}
  yield
ensure
  Thread.current[:cdn_var_substitutor_cache] = nil
end

Instance Method Details

#precalculate(paths_with_vars) ⇒ Object

precalcuclate all paths at once - let’s you discover errors and stop before it causes more pain



27
28
29
30
31
32
# File 'app/lib/katello/util/cdn_var_substitutor.rb', line 27

def precalculate(paths_with_vars)
  paths_with_vars.uniq.reduce({}) do |ret, path_with_vars|
    ret[path_with_vars] = substitute_vars(path_with_vars)
    ret
  end
end

#substituable?(path) ⇒ Boolean

Returns:

  • (Boolean)


89
90
91
# File 'app/lib/katello/util/cdn_var_substitutor.rb', line 89

def substituable?(path)
  path.include?("$")
end

#substitute_vars(path_with_vars) ⇒ Object

takes path e.g. “/rhel/server/5/$releasever/$basearch/os” returns hash substituting variables:

{ {"releasever" => "6Server", "basearch" => "i386"} =>  "/rhel/server/5/6Server/i386/os",
  {"releasever" => "6Server", "basearch" => "x86_64"} =>  "/rhel/server/5/6Server/x84_64/os"}

values are loaded from CDN



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'app/lib/katello/util/cdn_var_substitutor.rb', line 41

def substitute_vars(path_with_vars)
  if path_with_vars =~ /^(.*\$\w+)(.*)$/
    prefix_with_vars, suffix_without_vars =  Regexp.last_match[1], Regexp.last_match[2]
  else
    prefix_with_vars, suffix_without_vars = "", path_with_vars
  end

  prefixes_without_vars = substitute_vars_in_prefix(prefix_with_vars)
  paths_without_vars = prefixes_without_vars.reduce({}) do |h, (substitutions, prefix_without_vars)|
    h[substitutions] = prefix_without_vars + suffix_without_vars
    h
  end
  return paths_without_vars
end

#substitute_vars_in_prefix(prefix_with_vars) ⇒ Object

prefix_with_vars is the part of url containing some vars. We can cache calcualted values for this parts. So for example for:

"/a/$b/$c/d"
"/a/$b/$c/e"

prefix_with_vars is “/a/$b/$c” and we store the result after resolving for the first path.



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/lib/katello/util/cdn_var_substitutor.rb', line 62

def substitute_vars_in_prefix(prefix_with_vars)
  paths_with_vars = { {} => prefix_with_vars}
  prefixes_without_vars = @substitutions[prefix_with_vars]

  unless prefixes_without_vars
    prefixes_without_vars = {}
    until paths_with_vars.empty?
      substitutions, path = paths_with_vars.shift

      if substituable? path
        for_each_substitute_of_next_var substitutions, path do |new_substitution, new_path|
          begin
            paths_with_vars[new_substitution] = new_path
          rescue Errors::SecurityViolation
            # Some paths may not be accessible
            @resource.log :warn, "#{new_path} is not accessible, ignoring"
          end
        end
      else
        prefixes_without_vars[substitutions] = path
      end
    end
    @substitutions[prefix_with_vars] = prefixes_without_vars
  end
  return prefixes_without_vars
end

#valid_substitutions(content, substitutions) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'app/lib/katello/util/cdn_var_substitutor.rb', line 93

def valid_substitutions(content, substitutions)
  validate_all_substitutions_accepted(content, substitutions)
  content_url = content.contentUrl
  real_path = gsub_vars(content_url, substitutions)

  if substituable?(real_path)
    fail Errors::CdnSubstitutionError, _("Missing arguments %{substitutions} for %{content_url}") %
        { substitutions: substitutions_needed(real_path).join(', '),
          content_url: real_path }
  else
    is_valid = valid_path?(real_path, 'repodata/repomd.xml') || valid_path?(real_path, 'PULP_MANIFEST')
    unless is_valid
      @resource.log :error, "No valid metadata files found for #{real_path}"
      fail Errors::CdnSubstitutionError, _("%{substitutions} are not valid substitutions for %{content_url}."\
             " No valid metadata files found for %{real_path}") %
        { substitutions: substitutions, content_url: content.contentUrl, real_path: real_path}
    end
  end
end