module ASF
The ASF
module contains a set of classes which encapsulate access to a number of data sources such as LDAP
, ICLAs, auth lists, etc. This code originally was developed as a part of separate tools and was later refactored out into a common library. Some of the older tools don’t fully make use of this refactoring.
Access to documents/* (except member_apps)
Find site image files
Constants
- ETCLDAP
-
Directory where ldap.conf resides. Differs based on operating system.
- PETRI_INFO
-
Represents a
Petri
culture currently defined in petri.apache.org/info.yaml
Public Class Methods
Source
# File lib/whimsy/asf/ldap.rb, line 305 def self._init_ldap(reset = false, hosts = nil) ASF::LDAP::CONNECT_LOCK.synchronize do # fetch the default LDAP connection details if @ldap_dn.nil? || @ldap_pw.nil? Wunderbar.info("Reading #{ASF::LDAP::LDAP_CREDS}") File.open(ASF::LDAP::LDAP_CREDS) do |io| @ldap_dn = io.readline.strip @ldap_pw = io.readline.strip end end @ldap = nil if reset @ldap ||= ASF::LDAP.connect(hosts) end end
private entry point for establishing a connection safely
Source
# File lib/whimsy/asf/ldap.rb, line 438 def self.committerids weakref(:committerids) {RoleGroup.find('committers').memberids} end
Obtain a list of committerids from LDAP
cn=committers,ou=role,ou=groups,dc=apache,dc=org
Source
# File lib/whimsy/asf/ldap.rb, line 432 def self.committers weakref(:committers) {RoleGroup.find('committers').members} end
Obtain a list of committers from LDAP
cn=committers,ou=role,ou=groups,dc=apache,dc=org
Source
# File lib/whimsy/asf/ldap.rb, line 389 def self.dereference_weakref(object, attr, &block) attr = "@#{attr}" value = object.instance_variable_get(attr) || block.call value[0..-1] rescue WeakRef::RefError value = block.call ensure if not value or RUBY_VERSION.start_with? '1' object.instance_variable_set(attr, value) elsif value and not value.instance_of? WeakRef object.instance_variable_set(attr, WeakRef.new(value)) end # keep track of which weak references are saved @@weakrefs << attr if object == self end
safely dereference a weakref array attribute. Block provided is used when reference is not set or has been reclaimed. N.B. dereference_weakref
(object, :XYZ, block) stores the reference in @XYZ
Source
# File lib/whimsy/asf.rb, line 44 def self.dup(obj) obj.dup.tap do |new_obj| new_obj.each do |key, val| new_obj[key] = ASF.dup(val) if val.is_a?(Hash) end end end
duplicate an object, allowing for nested hashes
Source
# File lib/whimsy/asf/ldap.rb, line 406 def self.flush_weakrefs @@weakrefs.each do |attr| self.remove_instance_variable(attr) end @@weakrefs.clear # run garbage collection GC.start end
Source
# File lib/whimsy/asf/ldap.rb, line 328 def self.ldap @ldap || ASF._init_ldap # ensure the connection is bound unless @ldap.bound? Wunderbar.debug("#{@ldap.object_id}: bind as #{@ldap_dn} as #{@ldap}") @ldap.bind(@ldap_dn, @ldap_pw) end @ldap end
Returns LDAP
connection, creating and binding one if necessary.
Source
# File lib/whimsy/asf.rb, line 38 def self.library_gitinfo return @info if @info @info = `git show --format="%h %ci" -s HEAD`.strip end
Last commit in this clone, and the date and time of that commit.
Source
# File lib/whimsy/asf.rb, line 30 def self.library_mtime parent_dir = File.dirname(File.expand_path(__FILE__)) sources = Dir.glob("#{parent_dir}/**/*") times = sources.map {|source| File.mtime(source)} times.max.gmtime end
Last modified time of any file in the entire source tree.
Source
Source
Source
# File lib/whimsy/asf/ldap.rb, line 426 def self.pmc_chairs weakref(:pmc_chairs) {Service.find('pmc-chairs').members} end
Obtain a list of PMC chairs from LDAP
cn=pmc-chairs,ou=groups,ou=services,dc=apache,dc=org
Note: this list may include non-PMC VPs.
Source
# File lib/whimsy/asf/icla.rb, line 329 def self.search_archive_by_id(id) name = JSON.parse(File.read(File.join(ASF::SVN['officers_historic'], 'committers.json')))[id] name = id if name and name.empty? name end
Search archive for historical records of people who were committers but never submitted an ICLA
(some of which are still ASF
members or members of a PMC).
Source
# File lib/whimsy/asf/ldap.rb, line 339 def self.search_one(base, filter, attrs=nil) self.search_scope(::LDAP::LDAP_SCOPE_ONELEVEL, base, filter, attrs) end
search with a scope of one, with automatic retry/failover
Source
# File lib/whimsy/asf/ldap.rb, line 349 def self.search_scope(scope, base, filter, attrs=nil) # Dummy command, used for logging purposes only sname = %w(base one sub children)[scope] rescue scope cmd = "ldapsearch -x -LLL -b #{base} -s #{sname} #{filter} " + [attrs].flatten.join(' ') # try once per host, with a minimum of two tries attempts_left = [ASF::LDAP.hosts.length, 2].max target = nil # ensure access from rescue block begin attempts_left -= 1 ASF.ldap # creates connection if necessary and binds it return [] unless @ldap target = @ldap.get_option(::LDAP::LDAP_OPT_HOST_NAME) rescue '?' Wunderbar.info "[#{target}] #{cmd}" result = @ldap.search2(base, scope, filter, attrs) rescue Exception => re if attempts_left <= 0 Wunderbar.error "[#{target}] => #{re.inspect} for #{cmd}" raise else Wunderbar.warn "[#{target}] => #{re.inspect} for #{cmd}, retrying ..." @ldap.unbind if @ldap.bound? rescue nil @ldap = nil # force new connection sleep 1 retry end end result.map! {|hash| hash[attrs]} if attrs.is_a? String result.compact end
search with a specified scope, with automatic retry/failover
Source
# File lib/whimsy/asf/ldap.rb, line 344 def self.search_subtree(base, filter, attrs=nil) self.search_scope(::LDAP::LDAP_SCOPE_SUBTREE, base, filter, attrs) end
search with a scope of subtree, with automatic retry/failover
Source
# File lib/whimsy/asf/ldap.rb, line 419 def self.weakref(attr, &block) self.dereference_weakref(self, attr, &block) end
shortcut for dereference weakref N.B. weakref(:XYZ) stores the reference in @XYZ