epubjs
Version:
Render ePub documents in the browser, across many devices
180 lines (128 loc) • 11.7 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Pro Git - professional version control</title>
<meta content="http://www.w3.org/1999/xhtml; charset=utf-8" http-equiv="Content-Type"/>
<link href="stylesheet.css" type="text/css" rel="stylesheet"/>
<style type="text/css">
@page { margin-bottom: 5.000000pt; margin-top: 5.000000pt; }</style>
</head>
<body class="calibre">
<h2 class="calibre4" id="calibre_pb_36">Gitosis</h2>
<p class="calibre3">Keeping all users' public keys in the <code class="calibre10">authorized_keys</code> file for access works well only for a while. When you have hundreds of users, it's much more of a pain to manage that process. You have to shell onto the server each time, and there is no access control - everyone in the file has read and write access to every project.</p>
<p class="calibre3">At this point, you may want to turn to a widely used software project called Gitosis. Gitosis is basically a set of scripts that help you manage the <code class="calibre10">authorized_keys</code> file as well as implement some simple access controls. The really interesting part is that the UI for this tool for adding people and determining access isn't a web interface but a special Git repository. You set up the information in that project; and when you push it, Gitosis reconfigures the server based on that, which is cool.</p>
<p class="calibre3">Installing Gitosis isn't the simplest task ever, but it's not too difficult. It's easiest to use a Linux server for it - these examples use a stock Ubuntu 8.10 server.</p>
<p class="calibre3">Gitosis requires some Python tools, so first you have to install the Python setuptools package, which Ubuntu provides as python-setuptools:</p>
<pre class="calibre9"><code class="calibre10">$ apt-get install python-setuptools
</code></pre>
<p class="calibre3">Next, you clone and install Gitosis from the project's main site:</p>
<pre class="calibre9"><code class="calibre10">$ git clone git://eagain.net/gitosis.git
$ cd gitosis
$ sudo python setup.py install
</code></pre>
<p class="calibre3">That installs a couple of executables that Gitosis will use. Next, Gitosis wants to put its repositories under <code class="calibre10">/home/git</code>, which is fine. But you have already set up your repositories in <code class="calibre10">/opt/git</code>, so instead of reconfiguring everything, you create a symlink:</p>
<pre class="calibre9"><code class="calibre10">$ ln -s /opt/git /home/git/repositories
</code></pre>
<p class="calibre3">Gitosis is going to manage your keys for you, so you need to remove the current file, re-add the keys later, and let Gitosis control the <code class="calibre10">authorized_keys</code> file automatically. For now, move the <code class="calibre10">authorized_keys</code> file out of the way:</p>
<pre class="calibre9"><code class="calibre10">$ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak
</code></pre>
<p class="calibre3">Next you need to turn your shell back on for the 'git' user, if you changed it to the <code class="calibre10">git-shell</code> command. People still won't be able to log in, but Gitosis will control that for you. So, let's change this line in your <code class="calibre10">/etc/passwd</code> file</p>
<pre class="calibre9"><code class="calibre10">git:x:1000:1000::/home/git:/usr/bin/git-shell
</code></pre>
<p class="calibre3">back to this:</p>
<pre class="calibre9"><code class="calibre10">git:x:1000:1000::/home/git:/bin/sh
</code></pre>
<p class="calibre3">Now it's time to initialize Gitosis. You do this by running the <code class="calibre10">gitosis-init</code> command with your personal public key. If your public key isn't on the server, you'll have to copy it there:</p>
<pre class="calibre9"><code class="calibre10">$ sudo -H -u git gitosis-init < /tmp/id_dsa.pub
Initialized empty Git repository in /opt/git/gitosis-admin.git/
Reinitialized existing Git repository in /opt/git/gitosis-admin.git/
</code></pre>
<p class="calibre3">This lets the user with that key modify the main Git repository that controls the Gitosis setup. Next, you have to manually set the execute bit on the <code class="calibre10">post-update</code> script for your new control repository.</p>
<pre class="calibre9"><code class="calibre10">$ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update
</code></pre>
<p class="calibre3">You're ready to roll. If you're set up correctly, you can try to SSH into your server as the user for which you added the public key to initialize Gitosis. You should see something like this:</p>
<pre class="calibre9"><code class="calibre10">$ ssh git@gitserver
PTY allocation request failed on channel 0
fatal: unrecognized command 'gitosis-serve schacon@quaternion'
Connection to gitserver closed.
</code></pre>
<p class="calibre3">That means Gitosis recognized you but shut you out because you're not trying to do any Git commands. So, let's do an actual Git command - you'll clone the Gitosis control repository:</p>
<pre class="calibre9"><code class="calibre10"># on your local computer
$ git clone git@gitserver:gitosis-admin.git
</code></pre>
<p class="calibre3">Now you have a directory named <code class="calibre10">gitosis-admin</code>, which has two major parts:</p>
<pre class="calibre9"><code class="calibre10">$ cd gitosis-admin
$ find .
./gitosis.conf
./keydir
./keydir/scott.pub
</code></pre>
<p class="calibre3">The <code class="calibre10">gitosis.conf</code> file is the control file you use to specify users, repositories, and permissions. The <code class="calibre10">keydir</code> directory is where you store the public keys of all the users who have any sort of access to your repositories - one file per user. The name of the file in <code class="calibre10">keydir</code> (in the previous example, <code class="calibre10">scott.pub</code>) will be different for you - Gitosis takes that name from the description at the end of the public key that was imported with the <code class="calibre10">gitosis-init</code> script.</p>
<p class="calibre3">If you look at the <code class="calibre10">gitosis.conf</code> file, it should only specify information about the <code class="calibre10">gitosis-admin</code> project that you just cloned:</p>
<pre class="calibre9"><code class="calibre10">$ cat gitosis.conf
[gitosis]
[group gitosis-admin]
writable = gitosis-admin
members = scott
</code></pre>
<p class="calibre3">It shows you that the 'scott' user - the user with whose public key you initialized Gitosis - is the only one who has access to the <code class="calibre10">gitosis-admin</code> project.</p>
<p class="calibre3">Now, let's add a new project for you. You'll add a new section called <code class="calibre10">mobile</code> where you'll list the developers on your mobile team and projects that those developers need access to. Because 'scott' is the only user in the system right now, you'll add him as the only member, and you'll create a new project called <code class="calibre10">iphone_project</code> to start on:</p>
<pre class="calibre9"><code class="calibre10">[group mobile]
writable = iphone_project
members = scott
</code></pre>
<p class="calibre3">Whenever you make changes to the <code class="calibre10">gitosis-admin</code> project, you have to commit the changes and push them back up to the server in order for them to take effect:</p>
<pre class="calibre9"><code class="calibre10">$ git commit -am 'add iphone_project and mobile group'
[master]: created 8962da8: "changed name"
1 files changed, 4 insertions(+), 0 deletions(-)
$ git push
Counting objects: 5, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 272 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To git@gitserver:/opt/git/gitosis-admin.git
fb27aec..8962da8 master -> master
</code></pre>
<p class="calibre3">You can make your first push to the new <code class="calibre10">iphone_project</code> project by adding your server as a remote to your local version of the project and pushing. You no longer have to manually create a bare repository for new projects on the server - Gitosis creates them automatically when it sees the first push:</p>
<pre class="calibre9"><code class="calibre10">$ git remote add origin git@gitserver:iphone_project.git
$ git push origin master
Initialized empty Git repository in /opt/git/iphone_project.git/
Counting objects: 3, done.
Writing objects: 100% (3/3), 230 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@gitserver:iphone_project.git
* [new branch] master -> master
</code></pre>
<p class="calibre3">Notice that you don't need to specify the path (in fact, doing so won't work), just a colon and then the name of the project - Gitosis finds it for you.</p>
<p class="calibre3">You want to work on this project with your friends, so you'll have to re-add their public keys. But instead of appending them manually to the <code class="calibre10">~/.ssh/authorized_keys</code> file on your server, you'll add them, one key per file, into the <code class="calibre10">keydir</code> directory. How you name the keys determines how you refer to the users in the <code class="calibre10">gitosis.conf</code> file. Let's re-add the public keys for John, Josie, and Jessica:</p>
<pre class="calibre9"><code class="calibre10">$ cp /tmp/id_rsa.john.pub keydir/john.pub
$ cp /tmp/id_rsa.josie.pub keydir/josie.pub
$ cp /tmp/id_rsa.jessica.pub keydir/jessica.pub
</code></pre>
<p class="calibre3">Now you can add them all to your 'mobile' team so they have read and write access to <code class="calibre10">iphone_project</code>:</p>
<pre class="calibre9"><code class="calibre10">[group mobile]
writable = iphone_project
members = scott john josie jessica
</code></pre>
<p class="calibre3">After you commit and push that change, all four users will be able to read from and write to that project.</p>
<p class="calibre3">Gitosis has simple access controls as well. If you want John to have only read access to this project, you can do this instead:</p>
<pre class="calibre9"><code class="calibre10">[group mobile]
writable = iphone_project
members = scott josie jessica
[group mobile_ro]
readonly = iphone_project
members = john
</code></pre>
<p class="calibre3">Now John can clone the project and get updates, but Gitosis won't allow him to push back up to the project. You can create as many of these groups as you want, each containing different users and projects. You can also specify another group as one of the members (using <code class="calibre10">@</code> as prefix), to inherit all of its members automatically:</p>
<pre class="calibre9"><code class="calibre10">[group mobile_committers]
members = scott josie jessica
[group mobile]
writable = iphone_project
members = @mobile_committers
[group mobile_2]
writable = another_iphone_project
members = @mobile_committers john
</code></pre>
<p class="calibre3">If you have any issues, it may be useful to add <code class="calibre10">loglevel=DEBUG</code> under the <code class="calibre10">[gitosis]</code> section. If you've lost push access by pushing a messed-up configuration, you can manually fix the file on the server under <code class="calibre10">/home/git/.gitosis.conf</code> - the file from which Gitosis reads its info. A push to the project takes the <code class="calibre10">gitosis.conf</code> file you just pushed up and sticks it there. If you edit that file manually, it remains like that until the next successful push to the <code class="calibre10">gitosis-admin</code> project.</p>
</body>
</html>