/usr/lib/ruby/vendor_ruby/berkshelf/api/cache_builder/worker/github.rb is in berkshelf-api 2.2.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 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 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 114 115 116 117 118 119 120 | require 'octokit'
require 'semverse'
require 'net/http'
module Berkshelf::API
class CacheBuilder
module Worker
class Github < Worker::Base
worker_type "github"
include Logging
# @return [String]
attr_reader :organization
# @option options [String] :organization
# the organization to crawl for cookbooks
# @option options [String] :access_token
# authentication token for accessing the Github organization. This is necessary
# since Github throttles unauthenticated API requests
def initialize(options = {})
@connection = Octokit::Client.new(access_token: options[:access_token], auto_paginate: true,
api_endpoint: options[:api_endpoint], web_endpoint: options[:web_endpoint],
connection_options: {ssl: {verify: options[:ssl_verify].nil? ? true : options[:ssl_verify]}})
@organization = options[:organization]
log.warn "You have configured a GitHub endpoint to index the #{@organization} organization."
log.warn "Using unfinalized artifacts, such as cookbooks retrieved from Git, to satisfiy your"
log.warn "dependencies is *STRONGLY FROWNED UPON* and potentially *DANGEROUS*."
log.warn ""
log.warn "Please consider setting up a release process for the cookbooks you wish to retrieve from this"
log.warn "GitHub organization where the cookbook is uploaded into a Hosted Chef organization, an internal"
log.warn "Chef Server, or the community site, and then replace this endpoint with a chef_server endpoint."
super(options)
end
# @return [String]
def to_s
friendly_name(organization)
end
# @return [Array<RemoteCookbook>]
# The list of cookbooks this builder can find
def cookbooks
[].tap do |cookbook_versions|
connection.organization_repositories(organization).each do |repo|
connection.tags(repo.full_name).each do |tag|
if match = /^v(?<version>.*)$/.match(tag.name)
begin
next unless cookbook_metadata = load_metadata(repo.name, tag.name)
if cookbook_metadata.version.to_s == match[:version].to_s
cookbook_versions << RemoteCookbook.new(cookbook_metadata.name, cookbook_metadata.version,
self.class.worker_type, repo.html_url, priority, {:repo_name => repo.name} )
else
log.warn "Version found in metadata for #{repo.name} (#{tag.name}) does not " +
"match the tag. Got #{cookbook_metadata.version}."
end
rescue Semverse::InvalidVersionFormat
log.debug "Ignoring tag #{tag.name} for: #{repo.name}. Does not conform to semver."
rescue Octokit::NotFound
log.debug "Ignoring tag #{tag.name} for: #{repo.name}. No raw metadata found."
end
else
log.debug "Version number cannot be parsed"
end
end
end
end
end
# Return the metadata of the given RemoteCookbook. If the metadata could not be found or parsed
# nil is returned.
#
# @param [RemoteCookbook] remote
#
# @return [Ridley::Chef::Cookbook::Metadata, nil]
def metadata(remote)
load_metadata(remote.info[:repo_name], "v#{remote.version}")
end
private
attr_reader :connection
# Helper function for loading metadata from a particular ref in a Github repository
#
# @param [String] repo
# name of repository to load from
# @param [String] ref
# reference, tag, or branch to load from
#
# @return [Ridley::Chef::Cookbook::Metadata, nil]
def load_metadata(repo, ref)
metadata_content = read_content(repo, ref, Ridley::Chef::Cookbook::Metadata::RAW_FILE_NAME)
cookbook_metadata = Ridley::Chef::Cookbook::Metadata.new
cookbook_metadata.instance_eval(metadata_content)
cookbook_metadata
rescue => ex
nil
end
# Read content from a file from a particular ref in a Github repository
#
# @param [String] repo
# name of the repository to load from
# @param [String] ref
# reference, tag, or branch to load from
# @param [String] file
# file to read content from
#
# @return [String]
def read_content(repo, ref, file)
Base64.decode64(connection.contents("#{organization}/#{repo}", path: file, ref: ref).content)
end
end
end
end
end
|