Mercurial over ssh with config file - mercurial

Say I have the following ssh .config file:
Host host_nickname
User xxx
HostName yyy.zz.vvv
ControlMaster auto
ControlPath ~/.ssh/%r#%h:%p
In case you are not familiar with ControlMaster or ControlPath, here is the description from the ssh_config manual:
ControlMaster:
Enables the sharing of multiple sessions over a single network
connection. When set to ``yes'', ssh(1) will listen for connec-
tions on a control socket specified using the ControlPath argu-
ment. Additional sessions can connect to this socket using the
same ControlPath with ControlMaster set to ``no'' (the default).
These sessions will try to reuse the master instance's network
connection rather than initiating new ones, but will fall back to
connecting normally if the control socket does not exist, or is
not listening.
In Mercurial, if you want to push or pull from a repository, you could just type the following:
hg push ssh://user#example.com/hg/
Now, my question:
I would like to ask Mercurial to push (or pull) against a repository at /path/to/repository on the server corresponding to my ssh config entry host_nickname. How do I do this?

If you look under hg help urls you'll find
ssh://[user#]host[:port]/[path][#revision]
So, assuming that /path/to/repository works from your login dir on the remote machine, then type
hg [push|pull] ssh://host_nickname/path/to/repository
This works because hg isn't doing the name resolution; ssh is, and you've specified the correspondence between host_nickname and the real HostName. Also, ControlMaster won't affect this, as that just allows multiplexing over a single ssh connection. Note, if hg isn't in your remote PATH, then you need to specify it via --remotecmd /path/to/hg.

Related

hg clone hangs at sending between command

I'm trying to clone a Mercurial repository hosted on BitBucket via SSH from the Windows command line.
When I add the --debug flag I can see that it never gets past the 'sending between command'
When I ctrl+c, it just shows interrupted! without any other error messages.
I'm also looking at the Resource Monitor and it's not showing any related network traffic after the first minute or so.
I have tried adding the --noupdate option and the --uncompressed option with the same results.
Windows Server 2012 with just Mercurial - No TortoiseHg
Any ideas?
Is there a reason the 'sending between command' would take awhile? The repository is about 150MB
I know I'm late to the party, since Bitbucket has long dropped the Mercurial support, still this might be relevant to those setting it up on Windows to use with any other service or in a self-hosted environment.
I assume that you've set plink as your SSH client. If not, this can be easily done by adding the ssh parameter in your Mercurial configuration. Here is what my mercurial.ini file's contents look like:
>hg config --edit
[ui]
ssh="C:\programs\putty\plink.exe" -ssh -2
I spent like two hours tinkering around with my setup before I had an Aha! moment and tried to connect to the server with plink to see if the problem lies there:
>plink.exe hg-ssh#hg.example.com -noagent id
The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's ssh-ed25519 key fingerprint is:
ssh-ed25519 255 90:8d:b0:26:c5:6e:74:2a:6c:3d:80:42:54:9e:15:47
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n)
Bingo!
As you can see here, plink prompts for the input, and we have to provide it before it can proceed any further. So this is what makes hg hang indefinitely if we don't.
You can also download Process Explorer, open it and choose Show Process Tree (Ctrl+T) from the View menu, and search for the process plink. You can see that this process is running and is a child of hg.
I answered "y", and the key was cached in a registry entry under the
Computer\HKEY_CURRENT_USER\SOFTWARE\SimonTatham\PuTTY\SshHostKeys
The new entry contains the remote server name and the key itself.
Once that was out of the way, I could go about my business using clone, push, pull, as well as other commands, like in and out:
>hg clone ssh://hg-ssh#hg.example.com/review
destination directory: review
requesting all changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 4 changes to 4 files
new changesets f82779871203:e9b1a2b79f98 (1 drafts)
updating to branch default
4 files updated, 0 files merged, 0 files removed, 0 files unresolved
It looks like hg messes with the input and the output of the SSH client, and you never get to see what is going on there, nor can you interact with it. And specifying the --debug option makes no difference.
You can also supply the -sshlog option to plink to save the log protocol details of a session to a file:
[ui]
ssh="C:\programs\putty\plink.exe" -ssh -2 -sshlog plink.log
Here is a portion of the log, where it says that a host key is unknown to the client:
Incoming packet #0x2, type 21 / 0x15 (SSH2_MSG_NEWKEYS)
Event Log: Server also has ecdsa-sha2-nistp256/ssh-rsa host keys,
but we don't know any of them
Event Log: Host key fingerprint is:
Event Log: ssh-ed25519 255 90:8d:b0:26:c5:6e:74:2a:6c:3d:80:42:54:9e:15:47
And it is getting stuck around that spot waiting for the user input.
Out of curiosity I downloaded the Mercurial source code and tracked the debug messages down to the method _performhandshake in hg/mercurial/sshpeer.py:
$ hg clone https://www.mercurial-scm.org/repo/hg
$ grep -R 'sending between command' hg
$ less hg/mercurial/sshpeer.py
ui.debug(b'sending hello command\n')
ui.debug(b'sending between command\n')
Full sshpeer.py source code.
You can see up the call stack there's a call inside the instance to the _makeconnection, which in turn calls the procutil.popen4, which then uses subprocess.Popen class constructor to spawn a new process, and subprocess.PIPE is used as a value of the stdin, stdout, and stderr arguments.
And from the subprocess manual, you can see that:
PIPE indicates that a new pipe to the child should be created.
So this pretty much explains why you cannot interact with the SSH client, as all its standard input, standard output, and standard error are eaten up by Mercurial.
Anyone reading this answer, give this solution a try, and let us know if it was helpful!

Gitlab with non-standard SSH port (on VM with Iptable forwarding)

My gitlab is on a virtual machine on a host server. I reach the VM with a non-standard SSH port (i.e. 766) which an iptable rule then forward from host:766 to vm:22.
So when I create a new repo, the instruction to add a remote provide a mal-formed URL (as it doesn't use the 766 port. For instance, the web interface give me this:
Malformed
git remote add origin git#git.domain.com:group/project.git
Instead of an URL containing :766/ before the group.
Wellformed
git remote add origin git#git.domain.com:766/group/project.git
So it time I create a repo, I have to do the modification manually, same for my collaborator.
How can I fix that ?
In Omnibus-packaged versions you can modify that property in the /etc/gitlab/gitlab.rb file:
gitlab_rails['gitlab_shell_ssh_port'] = 766
Then, you'll need to reconfigure GitLab:
# gitlab-ctl reconfigure
Your URIs will then be correctly displayed as ssh://git#git.domain.com:766/group/project.git in the web interface.
if you configure the ssh_port correctly in config/gitlab.yml, the webpages will show the correct repo url.
## GitLab Shell settings
gitlab_shell:
...
# If you use non-standard ssh port you need to specify it
ssh_port: 766
ps.
the correct url is:
ssh://git#git.domain.com:766/group/project.git
edit: after the change you need to clear caches, etc:
bundle exec rake cache:clear assets:clean assets:precompile RAILS_ENV=production
N.B.: this was tested on an old Giltab version (v5-v6), and might not be suitable for modern instance.
You can achieve similar behavior in a 2 step process:
1. Edit: config/gitlab.yml
On the server, set the port to the one you use:
ssh_port: 766
2. Edit ~/.ssh/config
On your machine, add the following section corresponding to your gitlab:
Host sub.domain.com
Port 766
Limit
You will need to repeat this operation on each user's computer…
References
GitLab and a non-standard SSH port
Easy way to fix this issue:
ssh://git#my-server:4837/~/test.git
git clone -v ssh://git#my-server:4837/~/test.git
Reference URL

Configuration for using Mercurial with Bitbucket from behind a certificate rewriting proxy?

I'm trying to access BitBucket from work. The only access to the Internet is via an authenticating HTTP proxy which proxies http on port 8080 and SSL on port 8070. This proxy conducts a man-in-the-middle attack on SSL connections, browsers are able to create HTTPS connections to the Internet only due to the installation of a fake Websense certificate on all clients.
I am able to connect to BitBucket using Git but not using Mercurial. I'm using Mercurial version 2.0.2.
With Git I use the following config in .gitconfig
[user]
name = Firstname Lastname
email = firstname_lastname#domain.co.uk
[http]
proxy = http://name:password#nnn.nnn.nnn.nnn:8080
And can clone a repository with the following command
D:\MercurialTesting>git clone http://Firstname_Lastname#bitbucket.org/Firstname_Lastname/bb102repo.git test1
Cloning into 'test1'...
Password for 'bitbucket.org':
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
D:\MercurialTesting>
With the addition of this config setting
[http]
sslverify = false
I can also clone the repository via the https url https://Firstname_Lastname#bitbucket.org/Firstname_Lastname/bb102repo.git
Using Mercurial though it's a different story. Using the following config in mercurial.ini
[http_proxy]
host = nnn.nnn.nnn.nnn:8080
user = firstname_lastname#domain.co.uk
passwd = password
Mercurial will access my own Mercurial server at home no problem.
D:\MercurialTesting>hg --debug clone http://nnn.nnn.nnn.nnn/hg/Workspaces/Test1
using http://nnn.nnn.nnn.nnn/hg/Workspaces/Test1
proxying through http://nnn.nnn.nnn.nnn:8080
sending capabilities command
http authorization required
realm: Mercurial Repositories
user: username
password:
http auth: user username, password *******
destination directory: Test1
query 1; heads
sending batch command
http auth: user username, password *******
requesting all changes
sending getbundle command
http auth: user username, password *******
adding changesets
changesets: 1 chunks
add changeset 711ff2c6f5b2
changesets: 2 chunks
add changeset 9034b963b4c1
. . .
Using the exact same configuration and trying to access BitBucket through Mercurial just hangs.
D:\MercurialTesting>hg --debug clone http://bitbucket.org/Firstname_Lastname/bb101repo
using http://bitbucket.org/Firstname_Lastname/bb101repo
proxying through http://nnn.nnn.nnn.nnn:8080
sending capabilities command
abort: error: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
D:\MercurialTesting>
Using the same configuration with SSL via the url https://bitbucket.org/Firstname_Lastname/bb101repo Mercurial hangs in exactly the same way. During this process Wireshark detects no network activity at all.
Changing the settings in Mercurial.ini to match the port which the proxy serves SSL through has no effect. Setting the environment variable http_proxy makes no difference, but setting the environment variable https_proxy changes the output completely. Setting https_proxy and adding --insecure to the hg command invocation results in:
D:\MercurialTesting>hg --debug clone http://bitbucket.org/Firstname_Lastname/bb101repo --insecure
using http://bitbucket.org/Firstname_Lastname/bb101repo
proxying through http://nnn.nnn.nnn.nnn:8080
sending capabilities command
warning: bitbucket.org certificate with fingerprint 79:ce:0d:30:b0:17:29:6a:d1:9f:dd:d3:62:80:70:28:5e:9f:c2:e3 not verified (check hostfingerprints or web.cacerts config setting)
http authorization required
realm: Bitbucket.org HTTP
user: Firstname_Lastname
password:
http auth: user Firstname_Lastname, password ***
warning: bitbucket.org certificate with fingerprint 79:ce:0d:30:b0:17:29:6a:d1:9f:dd:d3:62:80:70:28:5e:9f:c2:e3 not verified (check hostfingerprints or web.cacerts config setting)
abort: HTTP Error 502: Success
D:\MercurialTesting>
And now Wireshark does detect an exchange taking place between my workstation and the proxy server. What I find most confusing though is that it doesn't make the slightest difference what I set https_proxy to, hg always uses the http proxy setting from Mercurial.ini and produces the same output above irrespective of whether I set https_proxy to the correct details for the SSL proxy or to complete garbage. The only difference is that if the environment variable https_proxy isn't set at all then hg just hangs as described above.
The formats for https_proxy I've tried include all variations of:
https_proxy=ip.ip.ip.ip:8070
https_proxy=ip.ip.ip.ip:8080
https_proxy=username:password#ip.ip.ip.ip:8070
https_proxy=username:password#ip.ip.ip.ip:8080
https_proxy=http://ip.ip.ip.ip:8070
https_proxy=http://ip.ip.ip.ip:8080
https_proxy=http://username:password#ip.ip.ip.ip:8070
https_proxy=http://username:password#ip.ip.ip.ip:8080
The results are the same no matter what I set it to.
So the questions I could really use some help with are:
How come I can access my Mercurial repositories at home but not at BitBucket?
How come I can access BitBucket with Git but not with Mercurial using the same configuration?
Does anyone have any ideas of how I can get this to work or what I can test next?
I am also connecting via proxy to bitbucket. As my settings didn't work as expected I found this SO entry.
I noticed that if I use command line parameters then everything works.
hg --config http_proxy.host=192.168.1.1:8080 --config http_proxy.user=Vad1mo --config http_proxy.passwd=secret clone https://bitbucket.org/Vadimo/test
On the other hand same entries in Mercurial.ini didn't work.
[http_proxy]
host = 192.168.1.1
port = 8080
user = Vad1mo
passwd = internet
By accident I found out the tiny difference between CMD and ini. In CMD the port is postfixed to the host. In ini file it is a new entry.
Changing mercurial.ini to postfix the port to host like on command line solved the problem.
[http_proxy]
host = 192.168.1.1:8080
;port = 8080
user = Vad1mo
passwd = internet
Maybe this also will help you.
btw. my hg version is 2.6.3
I ran into a similar problem with my work's proxy- actually, almost identical.
I've gotten around the problem so far by setting the http_proxy in mercurial.ini and then connecting to BitBucket via their HTTP address hg.io.
For example, my repository at https://bitbucket.org/mattgwagner/mattgwagner.com can be accessed via http://hg.io/mattgwagner/mattgwagner.com . Of course, this will send your password and connection in plaintext, but at least it let me connect.
This came in more use for me when pulling in open source projects hosted on BitBucket for my use.
Mercurial.ini
[http_proxy]
host = 192.168.1.155:8080
no =
user = domainUsername
passwd = pass
Are you able to ssh out? Bitbucket supports ssh access and your proxy won't muck w/ that if it's allowed.

RabbitMQ database files

I'm running RabbitMQ V.2.0.0. on a Linux machine. The mnesia base is current the default, but the within that directory Rabbit creates directories, eg. rabbit#ip-123.1.1.123.
The ip in the directory name is based on the inet addr of the machine. This directories hold information about user, exchanges, vhost (I think).
My question is, how can I fix/config these directory names with ip to be not based on ip?
To change the Mnesia directory, just set MNESIA_DIR in /etc/rabbitmq/rabbitmq.conf.
Also, a great place to ask RabbitMQ related questions is on the rabbitmq-discuss mailing list.
It seems you can edit the scripts files (rabbitmq-server, rabbitmq-mulit and rabbitmqcti). In these scripts at the top is a hostname variable.
I set the hostname to localhost and restarted.
This is not the best, but good enough for my requirements. The hostname must be a proper address, it cannot be something arbitrary.
The main problem is that your new machine has new hostname - and directory is named after it (just renaming directory as mentioned before, does not help) so we need to rename your machine hostname and make RabbitMq to work with old files.
Let "ip-0-0-0-0" be old machine name (so there should be a mnesia folder /var/lib/rabbitmq/mnsesia/ip-0-0-0-0), and new machine host
name is something like "ip-1-1-1-1", but new name doesnot matter as we will overwrite it. Execute following commands:
sudo -s
echo "127.0.0.1 ip-0-0-0-0" >> /etc/hosts
echo "ip-0-0-0-0" > /etc/hostname
reboot
After reboot your machine will have a new name and RabbitMq should work with old files.

How to config mercurial to push without asking my password through ssh?

I use mercurial in my project, and every time I push new changesets to the server by ssh, it ask me for a password.
Then how to config the mercurial to push with out asking password?
I works on Ubuntu 9.10
On Linux and Mac, use ssh-agent.
Ensure you have an ssh keypair (see man ssh-keygen for details)
Copy your public key (from ~/.ssh/id_dsa.pub) to the remote machine, giving it a unique name (such as myhost_key.pub)
Log in to the remote machine normally and append the public key you just copied to the ~/.ssh/authorized_keys file
Run ssh-add on your local workstation to add your key to the keychain
You can now use any remote hg commands in this session without requiring authentication.
Assuming you're using Windows, have a read of my Mercurial/SSH guide. Down the bottom of the post you'll find info on how to use PuTTy to do this for you.
Edit: -- Here's the part of the post that I'm talking about (bear in mind you'll need to have pageant running with your key already loaded for this to work):
Client: Setting up Mercurial
If you haven't already, make sure you install Mercurial on the client machine using the default settings. Make sure you tell the installer to add the Mercurial path to the system PATH.
The last step of configuration for the client is to tell Mercurial to use the PuTTy tools when using SSH. Mercurial can be configured by a user-specific configuration file called .hgrc. On Windows it can also be called Mercurial.ini. The file is located in your home folder. If you don't know what your home folder is, simply open a command prompt and type echo %USERPROFILE% - this will tell you the path.
If you haven't set up your configuration yet, then chances are the configuration file doesn't exist. So you'll have to create it. Create a file call either .hgrc or Mercurial.ini in your home folder manually, and open it in a text editor. Here is what part of mine looks like:
[ui]
username = OJ Reeves
editor = vim
ssh = plink -ssh -i "C:/path/to/key/id_rsa.ppk" -C -agent
The last line is the key and this is what you need to make sure it set properly. We are telling Mercurial to use the plink program. This also comes with PuTTy and is a command-line version of what the PuTTY program itself does behind the scenes. We also add a few parameters:
-ssh : Indicates that we're using the SSH protocol.
-i "file.ppk" : Specifies the location of the private key file we want to use to log in to the remote server. Change this to point to your local putty-compatible ppk private key. Make sure you user forward-slashes for the path separators as well!
-C : This switch enables compression.
-agent : This tells plink to talk to the pageant utility to get the passphrase for the key instead of asking you for it interactively.
The client is now ready to rock!
Install PuTTY.
If you're on Windows, open projectdir/.hg/hgrc in your favorite text editor. Edit it to look like this:
[paths]
default = ssh://hg#bitbucket.org/name/project
[ui]
username = Your Name <your#email.com>
ssh = "C:\Program Files (x86)\PuTTY\plink.exe" -ssh -i "C:\path\to\your\private_key.ppk" -C -agent
If it's taking forever to push, the server might be trying to ask you a question (but it's not displayed).
Run this:
"C:\Program Files (x86)\PuTTY\plink.exe" -T hg#bitbucket.org -i "C:\Program Files (x86)\PuTTY\plink.exe" -ssh -i "C:\path\to\your\private_key.ppk"
Answer any questions, and then try pushing again.
If you're using Bitbucket, open your private key with puttygen, copy your public key out of the top textbox, and add it to your user account: https://bitbucket.org/account/user/USERNAME/ssh-keys/