Class: RightScraper::Scanners::CookbookMetadata

Inherits:
Base
  • Object
show all
Defined in:
lib/right_scraper/scanners/cookbook_metadata.rb

Overview

Load cookbook metadata from a filesystem.

Direct Known Subclasses

CookbookMetadataReadOnly

Defined Under Namespace

Classes: MetadataError

Constant Summary collapse

JSON_METADATA =
'metadata.json'
RUBY_METADATA =
'metadata.rb'
UNDEFINED_COOKBOOK_NAME =
'undefined'
KNIFE_METADATA_SCRIPT_NAME =
'knife_metadata.rb'
JAILED_FILE_SIZE_CONSTRAINT =

128 KB

128 * 1024
FREED_FILE_SIZE_CONSTRAINT =

64 KB

64 * 1024

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ CookbookMetadata

Returns a new instance of CookbookMetadata.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/right_scraper/scanners/cookbook_metadata.rb', line 51

def initialize(options)
  super

  # we will free the generated 'metadata.json' to a path relative to the
  # repository directory. this allows for multiple passes over the
  # generated file(s) using different child processes, some or all of
  # which may execute in containers. the exact location of the freed file
  # depends on the cookbook position; recall that multiple cookbooks can
  # appear within a given repository.
  @freed_dir = options[:freed_dir].to_s
  if @freed_dir.empty? || !::File.directory?(@freed_dir)
    raise ::ArgumentError, "Missing or invalid freed_dir: #{@freed_dir.inspect}"
  end
end

Instance Attribute Details

#freed_dirObject (readonly)

Returns the value of attribute freed_dir.



46
47
48
# File 'lib/right_scraper/scanners/cookbook_metadata.rb', line 46

def freed_dir
  @freed_dir
end

Instance Method Details

#begin(resource) ⇒ Object



70
71
72
73
74
# File 'lib/right_scraper/scanners/cookbook_metadata.rb', line 70

def begin(resource)
  @read_blk = nil
  @cookbook = resource
  true
end

#end(resource) ⇒ Object

Complete a scan for the given resource.

Parameters ===

resource(RightScraper::Resources::Base)

resource to scan



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/right_scraper/scanners/cookbook_metadata.rb', line 80

def end(resource)
  @logger.operation(:metadata_parsing) do
    if @read_blk
       = ::JSON.parse(@read_blk.call)
      resource. = 

      # check for undefined cookbook name.
      #
      # note that many specs in right_scraper use badly formed metadata
      # that is not even a hash so, to avoid having to fix all of them
      # (and also in case the user's metadata.json is not a hash) check
      # for the has_key? method.
      #
      # if real metadata is not a hash then that should cause failure
      # at a higher level. if the cookbook name is actually defined as
      # being 'undefined' then the user gets a warning anyway.
      if (.respond_to?(:has_key?) &&
          ['name'] == UNDEFINED_COOKBOOK_NAME)
        message =
          'Cookbook name appears to be undefined and has been' +
          ' supplied automatically.'
        @logger.note_warning(message)
      end
    else
      # should not be scanning at all unless one of the metadata files was
      # detected before starting scan.
      fail 'Unexpected missing metadata'
    end
  end
  true
ensure
  @read_blk = nil
  @cookbook = nil
end

#finishObject

All done scanning this repository.



117
118
119
120
121
122
123
124
125
126
# File 'lib/right_scraper/scanners/cookbook_metadata.rb', line 117

def finish
  begin
    ::FileUtils.remove_entry_secure(tls[:tmpdir]) if tls[:tmpdir]
  rescue ::Exception => e
    @logger.note_warning(e.message)
  end
ensure
  # Cleanup thread-local storage
  tls.clear
end

#notice(relative_position, &blk) ⇒ Object

Notice a file during scanning.

Block

Return the data for this file. We use a block because it may not always be necessary to read the data.

Parameters

relative_position(String)

relative pathname for the file from root of cookbook



136
137
138
139
140
141
142
143
144
145
146
# File 'lib/right_scraper/scanners/cookbook_metadata.rb', line 136

def notice(relative_position, &blk)
  case relative_position
  when JSON_METADATA
    # preferred over RUBY_METADATA.
    @read_blk = blk
  when RUBY_METADATA
    # defer to any JSON_METADATA, which we hope refers to the same info.
    @read_blk ||= self.method(:generate_metadata_json)
  end
  true
end

#notice_dir(relative_position) ⇒ Object

Notice a directory during scanning. Since metadata.json,rb is by definition only in the root directory we don’t need to recurse, but we do need to go into the first directory (identified by relative_position being nil).

Parameters

relative_position(String)

relative pathname for the directory from root of cookbook

Returns

Boolean

should the scanning recurse into the directory



158
159
160
# File 'lib/right_scraper/scanners/cookbook_metadata.rb', line 158

def notice_dir(relative_position)
  relative_position == nil
end

#tlsObject



66
67
68
# File 'lib/right_scraper/scanners/cookbook_metadata.rb', line 66

def tls
  Thread.current[self.class.to_s.to_sym] ||= {}
end