Integrate Mercurial with SSH on Ubuntu Server 16.04
This article is Part 5 in a 7 Part Series.
- Part 1 - Install Redmine 3 on Ubuntu Server 16.04
- Part 2 - Secure Redmine 3 on Ubuntu Server 16.04 with Let's Encrypt
- Part 3 - Integrate Redmine 3 with Mercurial SCM on Ubuntu Server 16.04
- Part 4 - Integrate Redmine 3 with Git SCM on Ubuntu Server 16.04
- Part 5 - This Article
- Part 6 - Integrate Git with SSH on Ubuntu Server 16.04
- Part 7 - Install Sendmail with STARTTLS on Ubuntu Server 16.04
Introduction
In this installment of the Redmine tutorial series, I will instruct users on how to add SSH authentication to their private mercurial repos created earlier in the series.
This will allow users to perform mercurial (hg) operations e.g. push, pull, clone , on their repositories without having to input their credentials each time (as is the default with HTTP(S)).
SSH makes use of both a public and private keypair which we will start by creating on our local machine.
On your local client
On your local machine, create an RSA keypair
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Start the local SSH agent in the background
eval "$(ssh-agent -s)"
Add your private key to the SSH agent
ssh-add -K ~/.ssh/id_rsa
Copy your public key to the server
scp -v ~/.ssh/id_rsa.pub [username]@[your_domain]:~
On the Server
Install Mercurial server
sudo apt-get install mercurial-server
Move the newly copied key from your client to the mercurial-server key directory:
sudo mv -v id_rsa.pub /etc/mercurial-server/keys/root/<yourRedmineUserName>
Test if the installation was successful
Load the key into mercurial server by running the refresh-auth program:
sudo -u hg /usr/share/mercurial-server/refresh-auth
Clone the hgadmin test repo locally:
hg clone ssh://hg@[your_domain]/hgadmin
You should get:
$hg clone ssh://hg@[your_domain]/hgadmin
The authenticity of host 'your_domain (XX.XX.X.XX)' can't be established.
ECDSA key fingerprint is SHA256:QqLOjvSBFAGDo6v5PeG1evT9kJrT9Y8EsLqFEa7H2BE.
Are you sure you want to continue connecting (yes/no)? yes
remote: Warning: Permanently added '[your_domain]' (ECDSA) to the list of known hosts.
destination directory: hgadmin
no changes found
updating to branch default
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
Edit the mercurial server config
sudo vi /var/lib/mercurial-server/.mercurial-server
Modify repos = ~/repos to:
repos = /var/hg/repos
Modify the hg account permissions
Check the groups that hg user belongs to:
id hg
Add the hg user to the www-data group:
sudo usermod -G www-data hg
Give the group write permissions on the repository:
sudo chmod -R g+w /var/hg/repos/test
Add the changegroup hook
sudo vi /etc/mercurial-server/remote-hgrc.d/access.rc
Add under [hooks], add the following:
changegroup = /var/hg/changegroup-hook
On your local client
Clone the repo locally, edit a file, commit and push changes
hg clone ssh://hg@[your_domain]/test
You should see:
$hg clone ssh://hg@[your_domain]/test
destination directory: test
requesting all changes
remote: error: outgoing.aaaaa_servelog hook raised an exception: 'localrepository' object has no attribute 'join'
remote: (run with --traceback for stack trace)
adding changesets
adding manifests
adding file changes
added 3 changesets with 3 changes to 1 files
new changesets 99c57e1db0ac:54e179c4267b
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
<edit file>
hg push
You should see:
$hg push
pushing to ssh://hg@[your_domain]/test
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
remote: error: changegroup.aaaaa_servelog hook raised an exception: 'localrepository' object has no attribute 'join'
remote: (run with --traceback for stack trace)
In case you get the following errors when doing a push or a clone:
remote: error: changegroup.aaaaa_servelog hook raised an exception: 'localrepository' object has no attribute 'join'
Or:
remote: error: outgoing.aaaaa_servelog hook raised an exception: 'localrepository' object has no attribute 'join'
remote: (run with --traceback for stack trace)
The solution is to comment out the default logging hooks in the logging.rc file:
sudo vi /etc/mercurial-server/remote-hgrc.d/logging.rc
Change the file to the following:
[hooks]
# changegroup.aaaaa_servelog = python:mercurialserver.servelog.hook
# outgoing.aaaaa_servelog = python:mercurialserver.servelog.hook