BigW Consortium Gitlab

shell.rb 7.47 KB
Newer Older
1
module Gitlab
2
  class Shell
3
    class AccessDenied < StandardError; end
4

5 6 7 8 9 10
    class KeyAdder < Struct.new(:io)
      def add_key(id, key)
        io.puts("#{id}\t#{key.strip}")
      end
    end

11 12 13 14 15 16 17
    class << self
      def version_required
        @version_required ||= File.read(Rails.root.
                                        join('GITLAB_SHELL_VERSION')).strip
      end
    end

18
    # Init new repository
19
    #
20
    # name - project path with namespace
21 22
    #
    # Ex.
23
    #   add_repository("gitlab/gitlab-ci")
24
    #
25
    def add_repository(name)
26 27
      Gitlab::Utils.system_silent([gitlab_shell_projects_path,
                                   'add-project', "#{name}.git"])
28 29
    end

30 31 32 33 34 35 36 37
    # Import repository
    #
    # name - project path with namespace
    #
    # Ex.
    #   import_repository("gitlab/gitlab-ci", "https://github.com/randx/six.git")
    #
    def import_repository(name, url)
38 39
      Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'import-project',
                                   "#{name}.git", url, '240'])
40 41
    end

42 43 44 45 46 47 48 49 50
    # Move repository
    #
    # path - project path with namespace
    # new_path - new project path with namespace
    #
    # Ex.
    #   mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new.git")
    #
    def mv_repository(path, new_path)
51 52
      Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'mv-project',
                                   "#{path}.git", "#{new_path}.git"])
53 54
    end

55 56 57 58 59 60 61 62 63
    # Update HEAD for repository
    #
    # path - project path with namespace
    # branch - repository branch name
    #
    # Ex.
    #  update_repository_head("gitlab/gitlab-ci", "3-1-stable")
    #
    def update_repository_head(path, branch)
64 65
      Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'update-head',
                                   "#{path}.git", branch])
66 67
    end

68 69 70 71 72 73 74 75 76
    # Fork repository to new namespace
    #
    # path - project path with namespace
    # fork_namespace - namespace for forked project
    #
    # Ex.
    #  fork_repository("gitlab/gitlab-ci", "randx")
    #
    def fork_repository(path, fork_namespace)
77 78
      Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'fork-project',
                                   "#{path}.git", fork_namespace])
79 80
    end

81
    # Remove repository from file system
82
    #
83
    # name - project path with namespace
84 85 86 87
    #
    # Ex.
    #   remove_repository("gitlab/gitlab-ci")
    #
88
    def remove_repository(name)
89 90
      Gitlab::Utils.system_silent([gitlab_shell_projects_path,
                                   'rm-project', "#{name}.git"])
91 92
    end

93 94 95 96 97 98 99 100 101 102
    # Add repository branch from passed ref
    #
    # path - project path with namespace
    # branch_name - new branch name
    # ref - HEAD for new branch
    #
    # Ex.
    #   add_branch("gitlab/gitlab-ci", "4-0-stable", "master")
    #
    def add_branch(path, branch_name, ref)
103 104
      Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'create-branch',
                                   "#{path}.git", branch_name, ref])
105 106 107 108 109 110 111 112 113 114 115
    end

    # Remove repository branch
    #
    # path - project path with namespace
    # branch_name - branch name to remove
    #
    # Ex.
    #   rm_branch("gitlab/gitlab-ci", "4-0-stable")
    #
    def rm_branch(path, branch_name)
116 117
      Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'rm-branch',
                                   "#{path}.git", branch_name])
118 119
    end

120 121 122 123 124
    # Add repository tag from passed ref
    #
    # path - project path with namespace
    # tag_name - new tag name
    # ref - HEAD for new tag
125
    # message - optional message for tag (annotated tag)
126 127 128
    #
    # Ex.
    #   add_tag("gitlab/gitlab-ci", "v4.0", "master")
129
    #   add_tag("gitlab/gitlab-ci", "v4.0", "master", "message")
130
    #
131 132 133 134
    def add_tag(path, tag_name, ref, message = nil)
      cmd = %W(#{gitlab_shell_path}/bin/gitlab-projects create-tag #{path}.git
               #{tag_name} #{ref})
      cmd << message unless message.nil? || message.empty?
135
      Gitlab::Utils.system_silent(cmd)
136 137 138 139 140 141 142 143 144 145 146
    end

    # Remove repository tag
    #
    # path - project path with namespace
    # tag_name - tag name to remove
    #
    # Ex.
    #   rm_tag("gitlab/gitlab-ci", "v4.0")
    #
    def rm_tag(path, tag_name)
147 148
      Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'rm-tag',
                                   "#{path}.git", tag_name])
149 150
    end

151
    # Add new key to gitlab-shell
152
    #
153
    # Ex.
154
    #   add_key("key-42", "sha-rsa ...")
155
    #
156
    def add_key(key_id, key_content)
157 158
      Gitlab::Utils.system_silent([gitlab_shell_keys_path,
                                   'add-key', key_id, key_content])
159 160
    end

161 162 163 164 165 166 167 168 169 170
    # Batch-add keys to authorized_keys
    #
    # Ex.
    #   batch_add_keys { |adder| adder.add_key("key-42", "sha-rsa ...") }
    def batch_add_keys(&block)
      IO.popen(%W(#{gitlab_shell_path}/bin/gitlab-keys batch-add-keys), 'w') do |io|
        block.call(KeyAdder.new(io))
      end
    end

171
    # Remove ssh key from gitlab shell
172 173
    #
    # Ex.
174
    #   remove_key("key-342", "sha-rsa ...")
175
    #
176
    def remove_key(key_id, key_content)
177 178
      Gitlab::Utils.system_silent([gitlab_shell_keys_path,
                                   'rm-key', key_id, key_content])
179 180
    end

181 182 183
    # Remove all ssh keys from gitlab shell
    #
    # Ex.
Johannes Schleifenbaum committed
184
    #   remove_all_keys
185 186
    #
    def remove_all_keys
187
      Gitlab::Utils.system_silent([gitlab_shell_keys_path, 'clear'])
188 189
    end

190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
    # Add empty directory for storing repositories
    #
    # Ex.
    #   add_namespace("gitlab")
    #
    def add_namespace(name)
      FileUtils.mkdir(full_path(name), mode: 0770) unless exists?(name)
    end

    # Remove directory from repositories storage
    # Every repository inside this directory will be removed too
    #
    # Ex.
    #   rm_namespace("gitlab")
    #
    def rm_namespace(name)
      FileUtils.rm_r(full_path(name), force: true)
    end

    # Move namespace directory inside repositories storage
    #
    # Ex.
    #   mv_namespace("gitlab", "gitlabhq")
    #
    def mv_namespace(old_name, new_name)
      return false if exists?(new_name) || !exists?(old_name)

      FileUtils.mv(full_path(old_name), full_path(new_name))
    end

    # Remove GitLab Satellites for provided path (namespace or repo dir)
    #
    # Ex.
    #   rm_satellites("gitlab")
    #
    #   rm_satellites("gitlab/gitlab-ci.git")
    #
    def rm_satellites(path)
      raise ArgumentError.new("Path can't be blank") if path.blank?

      satellites_path = File.join(Gitlab.config.satellites.path, path)
      FileUtils.rm_r(satellites_path, force: true)
    end

234
    def url_to_repo(path)
235
      Gitlab.config.gitlab_shell.ssh_path_prefix + "#{path}.git"
236
    end
237

238 239
    # Return GitLab shell version
    def version
240
      gitlab_shell_version_file = "#{gitlab_shell_path}/VERSION"
241 242 243 244 245 246

      if File.readable?(gitlab_shell_version_file)
        File.read(gitlab_shell_version_file)
      end
    end

247 248
    protected

249 250 251 252
    def gitlab_shell_path
      Gitlab.config.gitlab_shell.path
    end

253 254 255 256
    def gitlab_shell_user_home
      File.expand_path("~#{Gitlab.config.gitlab_shell.ssh_user}")
    end

257 258 259 260 261 262 263 264 265 266 267 268 269
    def repos_path
      Gitlab.config.gitlab_shell.repos_path
    end

    def full_path(dir_name)
      raise ArgumentError.new("Directory name can't be blank") if dir_name.blank?

      File.join(repos_path, dir_name)
    end

    def exists?(dir_name)
      File.exists?(full_path(dir_name))
    end
270 271 272 273 274 275 276 277

    def gitlab_shell_projects_path
      File.join(gitlab_shell_path, 'bin', 'gitlab-projects')
    end

    def gitlab_shell_keys_path
      File.join(gitlab_shell_path, 'bin', 'gitlab-keys')
    end
278 279
  end
end