class OpenShift::Runtime::ApplicationRepository

This class represents an Application's Git repository

Constants

COUNT_GIT_OBJECTS
GIT_ARCHIVE
GIT_CONFIG
GIT_DESCRIPTION
GIT_INIT
GIT_INIT_BARE
GIT_LOCAL_CLONE
GIT_URL_CLONE
POST_RECEIVE
PRE_RECEIVE

Attributes

path[R]

Public Class Methods

new(container) click to toggle source

Creates a new application Git repository from a template

container is of type ApplicationContainer

# File lib/openshift-origin-node/model/application_repository.rb, line 41
def initialize(container)
  @container = container
  @path = PathUtils.join(@container.container_dir, 'git', "#{@container.application_name}.git")
end

Public Instance Methods

archive() click to toggle source
# File lib/openshift-origin-node/model/application_repository.rb, line 173
def archive
  return unless exist?

  # expose variables for ERB processing
  @application_name = @container.application_name
  @target_dir       = PathUtils.join(@container.container_dir, 'app-root', 'runtime', 'repo')

  FileUtils.rm_rf Dir.glob(PathUtils.join(@target_dir, '*'))
  FileUtils.rm_rf Dir.glob(PathUtils.join(@target_dir, '.[^\.]*'))

  @container.run_in_container_context(ERB.new(GIT_ARCHIVE).result(binding),
      chdir:               @path,
      expected_exitstatus: 0)

  return unless File.exist? PathUtils.join(@target_dir, '.gitmodules')

  env = ::OpenShift::Runtime::Utils::Environ.load(PathUtils.join(@container.container_dir, '.env'))

  cache = PathUtils.join(env['OPENSHIFT_TMP_DIR'], 'git_cache')
  FileUtils.rm_r(cache) if File.exist?(cache)
  FileUtils.mkpath(cache)

  @container.run_in_container_context("/bin/sh #{PathUtils.join('/usr/libexec/openshift/lib', "archive_git_submodules.sh")} #{@path} #{@target_dir}",
      chdir:               @container.container_dir,
      env:                 env,
      expected_exitstatus: 0)

  @container.run_in_container_context("/bin/rm -rf #{cache} &")
end
build_bare(path) click to toggle source

Copy a file tree structure and build an application repository

# File lib/openshift-origin-node/model/application_repository.rb, line 229
def build_bare(path)
  template = PathUtils.join(@container.container_dir, 'git', 'template')
  FileUtils.rm_r(template) if File.exist? template

  git_path = PathUtils.join(@container.container_dir, 'git')
  ::OpenShift::Runtime::Utils::oo_spawn("/bin/cp -ad #{path} #{git_path}",
                 expected_exitstatus: 0)

  ::OpenShift::Runtime::Utils::oo_spawn(ERB.new(GIT_INIT).result(binding),
      chdir:               template,
      expected_exitstatus: 0)
  begin
    # trying to clone as the user proved to be painful as git managed to "lose" the selinux context
    ::OpenShift::Runtime::Utils::oo_spawn(ERB.new(GIT_LOCAL_CLONE).result(binding),
        chdir:               git_path,
        expected_exitstatus: 0)
  rescue ShellExecutionException => e
    FileUtils.rm_r(@path) if File.exist? @path

    raise ShellExecutionException.new(
              'Failed to clone application git repository from template repository',
              e.rc, e.stdout, e.stderr)
  ensure
    FileUtils.rm_r(template)
  end
end
configure() click to toggle source

Install Git repository hooks and set permissions

# File lib/openshift-origin-node/model/application_repository.rb, line 209
def configure
  @container.set_rw_permission_R(@path)

  # application developer cannot change git hooks
  hooks = PathUtils.join(@path, 'hooks')
  @container.set_ro_permission_R(hooks)

  render_file = lambda { |f, m, t|
    File.open(f, 'w', m) { |f| f.write(ERB.new(t).result(binding)) }
  }

  render_file.call(PathUtils.join(@path, 'description'), 0644, GIT_DESCRIPTION)
  render_file.call(PathUtils.join(@container.container_dir, '.gitconfig'), 0644, GIT_CONFIG)

  render_file.call(PathUtils.join(hooks, 'pre-receive'), 0755, PRE_RECEIVE)
  render_file.call(PathUtils.join(hooks, 'post-receive'), 0755, POST_RECEIVE)
end
destroy() click to toggle source
# File lib/openshift-origin-node/model/application_repository.rb, line 203
def destroy
  FileUtils.rm_r(@path) if File.exist? @path
end
empty?() click to toggle source
# File lib/openshift-origin-node/model/application_repository.rb, line 46
def empty?
  return false unless exist?
  out, err, exitstatus = Utils.oo_spawn(COUNT_GIT_OBJECTS,
                                        chdir:               @path)
  out.strip == "0" && exitstatus == 0
end
exist?() click to toggle source
# File lib/openshift-origin-node/model/application_repository.rb, line 53
def exist?
  File.directory?(@path)
end
Also aliased as: exists?
exists?()
Alias for: exist?
populate_empty(cartridge_name) click to toggle source

populate_empty initializes a default, empty Git repository for the gear

# File lib/openshift-origin-node/model/application_repository.rb, line 148
def populate_empty(cartridge_name)
  return nil if exists?

  git_path = @path
  FileUtils.mkpath(git_path)

  # expose variables for ERB processing
  @application_name = @container.application_name
  @cartridge_name   = cartridge_name
  @user_homedir     = @container.container_dir

  begin
    Utils.oo_spawn(ERB.new(GIT_INIT_BARE).result(binding),
                   chdir:               git_path,
                   expected_exitstatus: 0)
  rescue ::OpenShift::Runtime::Utils::ShellExecutionException => e
    raise ::OpenShift::Runtime::Utils::ShellExecutionException.new(
              "CLIENT_ERROR: Source code repository could not be created.  Please contact support.",
              131
          )
  end

  configure
end
populate_from_cartridge(cartridge_name) click to toggle source

populate_from_cartridge uses the provided cartridge_name to install a template application for the gear

Template search locations:

* ~/<cartridge home>/template
* ~/<cartridge home>/template.git
* ~/<cartridge home>/usr/template
* ~/<cartridge home>/usr/template.git

return nil if application bare repository exists or no template found

otherwise path of template used
# File lib/openshift-origin-node/model/application_repository.rb, line 71
def populate_from_cartridge(cartridge_name)
  return nil if exists?

  FileUtils.mkpath(PathUtils.join(@container.container_dir, 'git'))

  locations = [
      PathUtils.join(@container.container_dir, cartridge_name, 'template'),
      PathUtils.join(@container.container_dir, cartridge_name, 'template.git'),
      PathUtils.join(@container.container_dir, cartridge_name, 'usr', 'template'),
      PathUtils.join(@container.container_dir, cartridge_name, 'usr', 'template.git'),
  ]

  template = locations.find {|l| File.directory?(l)}
  logger.debug("Using '#{template}' to populate git repository for #{@container.uuid}")
  return nil unless template

  # expose variables for ERB processing
  @application_name = @container.application_name
  @cartridge_name   = cartridge_name

  if template.end_with? '.git'
    FileUtils.cp_r(template, @path, preserve: true)
  else
    build_bare(template)
  end

  configure
  template
end
populate_from_url(cartridge_name, url) click to toggle source

populate_from_url uses the provided cartridge_url to install a template application for the gear

# File lib/openshift-origin-node/model/application_repository.rb, line 105
def populate_from_url(cartridge_name, url)
  return nil if exists?

  repo_spec, commit = ::OpenShift::Git.safe_clone_spec(url, ::OpenShift::Git::ALLOWED_NODE_SCHEMES) rescue            raise ::OpenShift::Runtime::Utils::ShellExecutionException.new(
      "CLIENT_ERROR: The provided source code repository URL is not valid (#{$!.message})",
      130)
  unless repo_spec
    raise ::OpenShift::Runtime::Utils::ShellExecutionException.new(
      "CLIENT_ERROR: Source code repository URL protocol must be one of: #{::OpenShift::Git::ALLOWED_NODE_SCHEMES.join(', ')}",
      130)
  end

  git_path = PathUtils.join(@container.container_dir, 'git')
  FileUtils.mkpath(git_path)

  # expose variables for ERB processing
  @application_name = @container.application_name
  @cartridge_name   = cartridge_name
  @user_homedir     = @container.container_dir
  @url              = repo_spec
  @commit           = commit

  begin
    ::OpenShift::Runtime::Utils::oo_spawn(ERB.new(GIT_URL_CLONE).result(binding),
        chdir:               git_path,
        expected_exitstatus: 0)
  rescue ::OpenShift::Runtime::Utils::ShellExecutionException => e
    if ssh_like? url
      msg = "CLIENT_ERROR: Source code repository could not be cloned: '#{url}'. Please verify the repository is correct and try a non-SSH URL such as HTTP."
    else
      msg = "CLIENT_ERROR: Source code repository could not be cloned: '#{url}'. Please verify the repository is correct and contact support."
    end
    raise ::OpenShift::Runtime::Utils::ShellExecutionException.new(msg, 131)
  end

  configure
end

Private Instance Methods

ssh_like?(url) click to toggle source
# File lib/openshift-origin-node/model/application_repository.rb, line 257
def ssh_like?(url)
  # HTTP,SSH, and FTP URLs may contain '@' to delimit "user:password" before the host name
  url_s = url.to_s.downcase
  (url_s.include?('@') && ! url_s.include?('//')) || (url_s.start_with? 'ssh:')
end