Edit2: This change currently has a side effect since there are no users in the deployment keys. So you will find some ugly messages like ERROR -> POST-RECEIVE: Triggered hook for non-existing user . Invalidity of the cache (and possibly other things) for this is not processed when writing push keys, which is a bit ugly. bundle exec rake cache:clear RAILS_ENV=production is your friend until I find a way to fix it (see the GitHub link below) - and please remember that clearing Redis-cache also logs out all users.
The following is a short workaround for archiving for each key:
Make My SSH keys read-only. This allows you to add read-only machines to all account repositories. Well, if you work with trainloads of git subprojects.
Make Deploy-Key read and write at developer level.
- Make Deploy-Key read-write at master level.
This is archived by adding a key header using special characters:
* to make My SSH keys readonly! to do a read-write Deploy-Key!! to make a key deployment wizard (write to secure branches)
So, instead of calling the key โMy global keyโ, you call it โmy global key for reading,โ etc.
diff --git a/lib/api/internal.rb b/lib/api/internal.rb index ed6b50c..ce350b1 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -30,7 +30,11 @@ module API if key.is_a? DeployKey - key.projects.include?(project) && DOWNLOAD_COMMANDS.include?(git_cmd) +return false unless key.projects.include?(project) +return true if DOWNLOAD_COMMANDS.include?(git_cmd) +return true if key.title.start_with? '!!' +return false if project.protected_branch?(params[:ref]) +key.title.start_with? '!' else user = key.user @@ -42,6 +46,7 @@ module API then :download_code when *PUSH_COMMANDS then +return false if key.title.start_with? '*' # VAHI 2014-02-09 if project.protected_branch?(params[:ref]) :push_code_to_protected_branches else
Edit1: This patch is now available as cherry-pick on GitHub, see https://github.com/hilbix/gitlabhq/wiki
Edit3: You may need the following workaround if you miss the deployment key. This is not ideal, since it does not call all these interceptors, but it invalidates caches so that web pages no longer display obsolete data:
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index 6416aa6..2fe98d4 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -26,6 +26,8 @@ class PostReceive unless user log("Triggered hook for non-existing user \"#{identifier} \"") + project.ensure_satellite_exists + project.repository.expire_cache return false end
The problems remain:
Not only that, you cannot use the same key at the account level and at the deployment level at the same time. Thus, for keys that have read-only access on a global basis (which is probably the default), you need a second special push only key that allows push access to the repositories.
Edit3: And most importantly, the deployment keys are not connected to the user, so all amenities do not work. If this is a problem for you, the only way is to create a dummy user for each SSH key and add it to the group / project and provide these dummies with the correct permissions.
Full Linux example for test repo with git@gitlab.example.com :root/test.git
Apply the above patch to GitLab
Restart GitLab to read in new code
Add ~/.ssh/id_rsa.pub to GitLab Admin under My SSH keys and name it * my readonly key (or something else starting with * ).
Make sure the following works: git clone git@gitlab.example.com :root/test.git
Make sure the following is done during the git push step:
cd test date > DATE.tmp git add DATE.tmp git commit -m testing git push
Create a second SSH key ~/.ssh/id_push : ssh-keygen -b 4096 -f ~/.ssh/id_push
Add ~/.ssh/id_push.pub as the Deploy-Key for the root/test.git . Call him ! my push key ! my push key (or something else starting with ! )
Add to ~/.ssh/config
following: Host gitlab-push Hostname gitlab.example.com User git IdentityFile ~/.ssh/id_push
Add this target to your cloned repo: git remote add to gitlab-push:root/test.git
Check out the following works: git push to master
Notes:
I used copy + paste to paste the patch. This will probably not be applied cleanly. Unfortunately.
Yes, this is really a very rude hack that should not get into the trunk. The correct implementation should be to have a flag in the database that does this so that you can edit it through the graphical interface.
For deployment keys, this "key level" -flag must be in the interesection table between the key and the project. And in the non-deployment option, the key must be on the key itself. Perhaps this field can then act as the default value when adding a deployment key to another project and recording the last use of such a key.
Unfortunately, I am not able to implement this correctly myself, because I lack knowledge on how to add the necessary elements in the GUI, sorry .; (