[ARVADOS] created: 749c0d9f4775306bcdfd5db2c37a22ca62d83f7d
git at public.curoverse.com
git at public.curoverse.com
Tue Mar 31 17:02:41 EDT 2015
at 749c0d9f4775306bcdfd5db2c37a22ca62d83f7d (commit)
commit 749c0d9f4775306bcdfd5db2c37a22ca62d83f7d
Author: Brett Smith <brett at curoverse.com>
Date: Tue Mar 31 17:02:38 2015 -0400
4253: Add script to migrate existing Gitolite installations.
diff --git a/services/api/script/migrate-gitolite-to-uuid-storage.rb b/services/api/script/migrate-gitolite-to-uuid-storage.rb
new file mode 100755
index 0000000..2fe6751
--- /dev/null
+++ b/services/api/script/migrate-gitolite-to-uuid-storage.rb
@@ -0,0 +1,217 @@
+#!/usr/bin/env ruby
+#
+# Prior to April 2015, Arvados Gitolite integration stored repositories by
+# name. To improve user repository management, we switched to storing
+# repositories by UUID, and aliasing them to names. This makes it easy to
+# have rich name hierarchies, and allow users to rename repositories.
+#
+# This script will migrate a name-based Gitolite configuration to a UUID-based
+# one. To use it:
+#
+# 1. Change the value of REPOS_DIR below, if needed.
+# 2. Install this script in the same directory as `update-gitolite.rb`.
+# 3. Ensure that no *other* users can access Gitolite: firewall off
+# the SSH port (don't firewall your own connection!), and disable
+# the update-gitolite cron job.
+# 4. Run this script: `ruby migrate-gitolite-to-uuid-storage.rb production`.
+# 5. Undo step 3.
+
+require 'rubygems'
+require 'pp'
+require 'arvados'
+require 'tempfile'
+require 'yaml'
+
+REPOS_DIR = "/var/lib/gitolite/repositories"
+
+# Default is development
+production = ARGV[0] == "production"
+
+ENV["RAILS_ENV"] = "development"
+ENV["RAILS_ENV"] = "production" if production
+
+DEBUG = 1
+
+# load and merge in the environment-specific application config info
+# if present, overriding base config parameters as specified
+path = File.dirname(__FILE__) + '/config/arvados-clients.yml'
+if File.exists?(path) then
+ cp_config = YAML.load_file(path)[ENV['RAILS_ENV']]
+else
+ puts "Please create a\n " + File.dirname(__FILE__) + "/config/arvados-clients.yml\n file"
+ exit 1
+end
+
+gitolite_url = cp_config['gitolite_url']
+gitolite_arvados_git_user_key = cp_config['gitolite_arvados_git_user_key']
+
+gitolite_tmpdir = File.join(File.absolute_path(File.dirname(__FILE__)),
+ cp_config['gitolite_tmp'])
+gitolite_admin = File.join(gitolite_tmpdir, 'gitolite-admin')
+gitolite_keydir = File.join(gitolite_admin, 'keydir', 'arvados')
+
+ENV['ARVADOS_API_HOST'] = cp_config['arvados_api_host']
+ENV['ARVADOS_API_TOKEN'] = cp_config['arvados_api_token']
+if cp_config['arvados_api_host_insecure']
+ ENV['ARVADOS_API_HOST_INSECURE'] = 'true'
+else
+ ENV.delete('ARVADOS_API_HOST_INSECURE')
+end
+
+def ensure_directory(path, mode)
+ begin
+ Dir.mkdir(path, mode)
+ rescue Errno::EEXIST
+ end
+end
+
+def replace_file(path, contents)
+ unlink_now = true
+ dirname, basename = File.split(path)
+ new_file = Tempfile.new([basename, ".tmp"], dirname)
+ begin
+ new_file.write(contents)
+ new_file.flush
+ File.rename(new_file, path)
+ unlink_now = false
+ ensure
+ new_file.close(unlink_now)
+ end
+end
+
+def file_has_contents?(path, contents)
+ begin
+ IO.read(path) == contents
+ rescue Errno::ENOENT
+ false
+ end
+end
+
+module TrackCommitState
+ module ClassMethods
+ # Note that all classes that include TrackCommitState will have
+ # @@need_commit = true if any of them set it. Since this flag reports
+ # a boolean state of the underlying git repository, that's OK in the
+ # current implementation.
+ @@need_commit = false
+
+ def changed?
+ @@need_commit
+ end
+
+ def ensure_in_git(path, contents)
+ unless file_has_contents?(path, contents)
+ replace_file(path, contents)
+ system("git", "add", path)
+ @@need_commit = true
+ end
+ end
+ end
+
+ def ensure_in_git(path, contents)
+ self.class.ensure_in_git(path, contents)
+ end
+
+ def self.included(base)
+ base.extend(ClassMethods)
+ end
+end
+
+class Repository
+ include TrackCommitState
+
+ @@aliases = {}
+
+ def initialize(arv_repo)
+ @arv_repo = arv_repo
+ end
+
+ def self.ensure_system_config(conf_root)
+ ensure_in_git(File.join(conf_root, "arvadosaliases.pl"), alias_config)
+ end
+
+ def self.rename_repos(repos_root)
+ @@aliases.each_pair do |uuid, name|
+ begin
+ File.rename(File.join(repos_root, "#{name}.git/"),
+ File.join(repos_root, "#{uuid}.git"))
+ rescue Errno::ENOENT
+ end
+ end
+ end
+
+ def ensure_config(conf_root)
+ return if name.nil?
+ @@aliases[uuid] = name
+ name_conf_path = auto_conf_path(conf_root, name)
+ return unless File.exist?(name_conf_path)
+ conf_file = IO.read(name_conf_path)
+ conf_file.gsub!(/^repo #{Regexp.escape(name)}$/m, "repo #{uuid}")
+ ensure_in_git(auto_conf_path(conf_root, uuid), conf_file)
+ File.unlink(name_conf_path)
+ system("git", "rm", "--quiet", name_conf_path)
+ end
+
+ private
+
+ def auto_conf_path(conf_root, basename)
+ File.join(conf_root, "conf", "auto", "#{basename}.conf")
+ end
+
+ def uuid
+ @arv_repo[:uuid]
+ end
+
+ def name
+ if @arv_repo[:name].nil?
+ nil
+ else
+ @clean_name ||=
+ @arv_repo[:name].sub(/^[^A-Za-z]+/, "").gsub(/[^\w\.\/]/, "")
+ end
+ end
+
+ def self.alias_config
+ conf_s = "{\n"
+ @@aliases.sort.each do |(repo_name, repo_uuid)|
+ conf_s += "\t'#{repo_name}' \t=> '#{repo_uuid}',\n"
+ end
+ conf_s += "};\n"
+ conf_s
+ end
+end
+
+begin
+ # Get our local gitolite-admin repo up to snuff
+ if not File.exists?(gitolite_admin) then
+ ensure_directory(gitolite_tmpdir, 0700)
+ Dir.chdir(gitolite_tmpdir)
+ `git clone #{gitolite_url}`
+ Dir.chdir(gitolite_admin)
+ else
+ Dir.chdir(gitolite_admin)
+ `git pull`
+ end
+
+ arv = Arvados.new
+ permissions = arv.repository.get_all_permissions
+
+ permissions[:repositories].each do |repo_record|
+ repo = Repository.new(repo_record)
+ repo.ensure_config(gitolite_admin)
+ end
+ Repository.ensure_system_config(gitolite_admin)
+
+ message = "#{Time.now().to_s}: migrate to storing repositories by UUID"
+ Dir.chdir(gitolite_admin)
+ `git add --all`
+ `git commit -m '#{message}'`
+ Repository.rename_repos(REPOS_DIR)
+ `git push`
+
+rescue => bang
+ puts "Error: " + bang.to_s
+ puts bang.backtrace.join("\n")
+ exit 1
+end
+
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list