shell.rb 6.6 KB
Newer Older
1
module Gitlab
2
  class Shell
D
Dmitriy Zaporozhets 已提交
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
    # Init new repository
12
    #
13
    # name - project path with namespace
14 15
    #
    # Ex.
16
    #   add_repository("gitlab/gitlab-ci")
17
    #
18
    def add_repository(name)
19
      system gitlab_shell_projects_path, 'add-project', "#{name}.git"
20 21
    end

22 23 24 25 26 27 28 29
    # Import repository
    #
    # name - project path with namespace
    #
    # Ex.
    #   import_repository("gitlab/gitlab-ci", "https://github.com/randx/six.git")
    #
    def import_repository(name, url)
30
      system gitlab_shell_projects_path, 'import-project', "#{name}.git", url, '240'
31 32
    end

33 34 35 36 37 38 39 40 41
    # 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)
42
      system gitlab_shell_projects_path, 'mv-project', "#{path}.git", "#{new_path}.git"
43 44
    end

45 46 47 48 49 50 51 52 53
    # 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)
54
      system gitlab_shell_projects_path, 'update-head', "#{path}.git", branch
55 56
    end

57 58 59 60 61 62 63 64 65
    # 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)
66
      system gitlab_shell_projects_path, 'fork-project', "#{path}.git", fork_namespace
67 68
    end

D
Dmitriy Zaporozhets 已提交
69
    # Remove repository from file system
70
    #
71
    # name - project path with namespace
72 73 74 75
    #
    # Ex.
    #   remove_repository("gitlab/gitlab-ci")
    #
76
    def remove_repository(name)
77
      system gitlab_shell_projects_path, 'rm-project', "#{name}.git"
D
Dmitriy Zaporozhets 已提交
78 79
    end

80 81 82 83 84 85 86 87 88 89
    # 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)
90
      system gitlab_shell_projects_path, 'create-branch', "#{path}.git", branch_name, ref
91 92 93 94 95 96 97 98 99 100 101
    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)
102
      system gitlab_shell_projects_path, 'rm-branch', "#{path}.git", branch_name
103 104
    end

105 106 107 108 109
    # Add repository tag from passed ref
    #
    # path - project path with namespace
    # tag_name - new tag name
    # ref - HEAD for new tag
110
    # message - optional message for tag (annotated tag)
111 112 113
    #
    # Ex.
    #   add_tag("gitlab/gitlab-ci", "v4.0", "master")
114
    #   add_tag("gitlab/gitlab-ci", "v4.0", "master", "message")
115
    #
116 117 118 119 120
    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?
      system *cmd
121 122 123 124 125 126 127 128 129 130 131
    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)
132
      system gitlab_shell_projects_path, 'rm-tag', "#{path}.git", tag_name
133 134
    end

135
    # Add new key to gitlab-shell
D
Dmitriy Zaporozhets 已提交
136
    #
137
    # Ex.
138
    #   add_key("key-42", "sha-rsa ...")
139
    #
140
    def add_key(key_id, key_content)
141
      system gitlab_shell_keys_path, 'add-key', key_id, key_content
142 143
    end

144 145 146 147 148 149 150 151 152 153
    # 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

154
    # Remove ssh key from gitlab shell
155 156
    #
    # Ex.
157
    #   remove_key("key-342", "sha-rsa ...")
158
    #
159
    def remove_key(key_id, key_content)
160
      system gitlab_shell_keys_path, 'rm-key', key_id, key_content
161 162
    end

163 164 165
    # Remove all ssh keys from gitlab shell
    #
    # Ex.
J
Johannes Schleifenbaum 已提交
166
    #   remove_all_keys
167 168
    #
    def remove_all_keys
169
      system gitlab_shell_keys_path, 'clear'
170 171
    end

172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 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
    # 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

216
    def url_to_repo(path)
217
      Gitlab.config.gitlab_shell.ssh_path_prefix + "#{path}.git"
R
randx 已提交
218
    end
219

220 221
    # Return GitLab shell version
    def version
222
      gitlab_shell_version_file = "#{gitlab_shell_path}/VERSION"
223 224 225 226 227 228

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

229 230
    protected

231 232 233 234
    def gitlab_shell_path
      Gitlab.config.gitlab_shell.path
    end

235 236 237 238
    def gitlab_shell_user_home
      File.expand_path("~#{Gitlab.config.gitlab_shell.ssh_user}")
    end

239 240 241 242 243 244 245 246 247 248 249 250 251
    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
252 253 254 255 256 257 258 259

    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
D
Dmitriy Zaporozhets 已提交
260 261
  end
end