class Gitolite::GitoliteAdmin
Constants
- DEFAULTS
Default settings
Attributes
Public Class Methods
# File lib/gitolite/gitolite_admin.rb, line 52 def admin_url(settings) ['ssh://', settings[:git_user], '@', settings[:host], '/gitolite-admin.git'].join end
Checks if the given path is a gitolite-admin repository A valid repository contains a conf folder, keydir folder, and a configuration file within the conf folder
# File lib/gitolite/gitolite_admin.rb, line 35 def is_gitolite_admin_repo?(dir) # First check if it is a git repository begin repo = Rugged::Repository.new(dir) return false if repo.empty? rescue Rugged::RepositoryError, Rugged::OSError return false end # Check if config file, key directory exist [ File.join(dir, DEFAULTS[:config_dir]), File.join(dir, DEFAULTS[:key_dir]), File.join(dir, DEFAULTS[:config_dir], DEFAULTS[:config_file]) ].each { |f| return false unless File.exists?(f) } true end
Intialize with the path to the gitolite-admin repository
Settings:
- Connection
-
:git_user: The git user to SSH to (:git_user@localhost:gitolite-admin.git), defaults to ‘git’ :private_key: The key file containing the private SSH key for :git_user :public_key: The key file containing the public SSH key for :git_user :host: Hostname for clone url. Defaults to ‘localhost’
- Gitolite-Admin
-
:config_dir:
Config
directory within gitolite repository (defaults to ‘conf’) :key_dir: Public key directory within gitolite repository (defaults to ‘keydir’) :config_file:Config
file to parse (default: ‘gitolite.conf’) **use only when you use the ‘include’ directive of gitolite)** :key_subdir: Where to store gitolite-rugged known keys, defaults to ” (i.e., directly in keydir) :lock_file_path: location of the transaction lockfile, defaults to <gitolite-admin.git>/.lockThe settings hash is forwarded to
GitoliteAdmin.new
as options.
# File lib/gitolite/gitolite_admin.rb, line 76 def initialize(path, settings = {}) @path = path @settings = DEFAULTS.merge(settings) # Ensure SSH key settings exist @settings.fetch(:public_key) @settings.fetch(:private_key) # setup credentials @credentials = Rugged::Credentials::SshKey.new( username: @settings[:git_user], publickey: settings[:public_key], privatekey: settings[:private_key] ) @config_dir_path = File.join(@path, @settings[:config_dir]) @config_file_path = File.join(@config_dir_path, @settings[:config_file]) @key_dir_path = File.join(@path, relative_key_dir) @commit_author = { email: @settings[:author_email], name: @settings[:author_name] } if self.class.is_gitolite_admin_repo?(path) @repo = Rugged::Repository.new(path, credentials: @credentials ) # Update repository if @settings[:update_on_init] update end else @repo = clone end reload! end
Public Instance Methods
# File lib/gitolite/gitolite_admin.rb, line 142 def add_key(key) unless key.instance_of? Gitolite::SSHKey raise GitoliteAdminError, "Key must be of type Gitolite::SSHKey!" end ssh_keys[key.owner] << key end
Push back to origin
# File lib/gitolite/gitolite_admin.rb, line 226 def apply @repo.push('origin', ['refs/heads/master'], credentials: @credentials) end
# File lib/gitolite/gitolite_admin.rb, line 127 def config @config ||= load_config end
# File lib/gitolite/gitolite_admin.rb, line 132 def config=(config) @config = config end
This method will destroy the in-memory data structures and reload everything from the file system
# File lib/gitolite/gitolite_admin.rb, line 169 def reload! @ssh_keys = load_keys @config = load_config end
This method will destroy all local tracked changes, resetting the local gitolite git repo to HEAD
# File lib/gitolite/gitolite_admin.rb, line 162 def reset! @repo.reset('origin/master', :hard) end
# File lib/gitolite/gitolite_admin.rb, line 151 def rm_key(key) unless key.instance_of? Gitolite::SSHKey raise GitoliteAdminError, "Key must be of type Gitolite::SSHKey!" end ssh_keys[key.owner].delete key end
Writes all changed aspects out to the file system will also stage all changes then commit
# File lib/gitolite/gitolite_admin.rb, line 177 def save(commit_msg = nil) # Add all changes to index (staging area) index = @repo.index #Process config file (if loaded, i.e. may be modified) if @config new_conf = @config.to_file(path=@config_dir_path) index.add(relative_config_file) end #Process ssh keys (if loaded, i.e. may be modified) if @ssh_keys files = list_keys.map{|f| relative_key_path(f) } keys = @ssh_keys.values.map{|f| f.map {|t| t.relative_path}}.flatten to_remove = (files - keys).each do |key| SSHKey.remove(key, @key_dir_path) index.remove File.join(relative_key_dir, key) end @ssh_keys.each_value do |key| # Write only keys from sets that has been modified next if key.respond_to?(:dirty?) && !key.dirty? key.each do |k| new_key = k.to_file(@key_dir_path) index.add File.join(relative_key_dir, k.relative_path) end end end # Write index to git and resync fs commit_tree = index.write_tree @repo index.write commit_author = @commit_author.merge(time: Time.now) Rugged::Commit.create(@repo, author: commit_author, committer: commit_author, message: commit_msg || @settings[:commit_msg], parents: [repo.head.target], tree: commit_tree, update_ref: 'HEAD' ) end
Commits all staged changes and pushes back to origin
# File lib/gitolite/gitolite_admin.rb, line 232 def save_and_apply() save apply end
# File lib/gitolite/gitolite_admin.rb, line 137 def ssh_keys @ssh_keys ||= load_keys end
Lock the gitolite-admin directory and yield. After the block is completed, calls apply
only. You have to commit your changes within the transaction block
# File lib/gitolite/gitolite_admin.rb, line 241 def transaction get_lock do yield # Push all changes apply end end
Updates the repo with changes from remote master Warning: This resets the repo before pulling in the changes.
# File lib/gitolite/gitolite_admin.rb, line 253 def update() # Reset --hard repo before update if @settings[:reset_before_update] reset! end # Fetch changes from origin @repo.fetch('origin', credentials: @credentials ) # Currently, only merging from origin/master into master is supported. master = @repo.references["refs/heads/master"].target origin_master = @repo.references["refs/remotes/origin/master"].target # Create the merged index in memory merge_index = repo.merge_commits(master, origin_master) # Complete the merge by comitting it merge_commit = Rugged::Commit.create(@repo, parents: [ master, origin_master ], tree: merge_index.write_tree(@repo), message: '[gitolite-rugged] Merged `origin/master` into `master`', author: @commit_author, committer: @commit_author, update_ref: 'refs/heads/master' ) reload! end
Private Instance Methods
Clone the gitolite-admin repo to the given path.
The repo is cloned from the url +(:git_user)@(:hostname)/gitolite-admin.git+
The hostname may use an optional :port to allow for custom SSH ports. E.g., +git@localhost:2222/gitolite-admin.git+
# File lib/gitolite/gitolite_admin.rb, line 296 def clone Rugged::Repository.clone_at(GitoliteAdmin.admin_url(@settings), File.expand_path(@path), credentials: @credentials ) end
Aquire LOCK_EX on the gitolite-admin.git directory . Use GitoliteAdmin.transaction
to modify with flock.
# File lib/gitolite/gitolite_admin.rb, line 343 def get_lock File.open(lock_file_path, File::RDWR|File::CREAT, 0644) do |file| file.sync = true file.flock(File::LOCK_EX) yield file.flock(File::LOCK_UN) end end
# File lib/gitolite/gitolite_admin.rb, line 306 def list_keys Dir.glob(@key_dir_path + '/**/*.pub') end
# File lib/gitolite/gitolite_admin.rb, line 301 def load_config Config.new(@config_file_path) end
Loads all .pub files in the gitolite-admin keydir directory
# File lib/gitolite/gitolite_admin.rb, line 320 def load_keys keys = Hash.new {|k,v| k[v] = DirtyProxy.new([])} list_keys.each do |key| new_key = SSHKey.from_file(key) owner = new_key.owner keys[owner] << new_key end # Mark key sets as unmodified (for dirty checking) keys.values.each{|set| set.clean_up!} keys end
# File lib/gitolite/gitolite_admin.rb, line 336 def lock_file_path File.expand_path(@settings[:lock_file_path], @path) end
Returns the relative key path <owner>/<location>/<owner> given an absolute path below the keydir.
# File lib/gitolite/gitolite_admin.rb, line 313 def relative_key_path(key_path) Pathname.new(key_path).relative_path_from(Pathname.new(@key_dir_path)).to_s end