Moving to a hosted Git Repository

I thought I would check out both Google and Amazons' code repository management offerings to see if either of them would make a good backup for my local git repository using ssh. In this post I’m going to walk through pushing a local git repository up to Googles' Cloud Source Repositories. I have gone through this process with both github and gitlab and I’m curious to find out if there are any difference between those offerings and those provided by Google and Amazon.

Getting Started

On GCP, the Source Repositories console is available off the main ‘hamburger’ menu in the upper left hand corner of your Google Console.

FromProjectConsole

I assume since I currently do not have any source repositories, selecting ‘Source Repositories’ leads me to an informative screen that explains the offering. To move forward, it appears as though a project is required. The console has detected that I do have a project so It looks like I’m clear to proceed with creating a repository.

GettingStarted

It’s interesting that there is a path here to pull external repositories into a personal repository. This is not really unusual and can be done through other means (outside scope), it’s just interesting that they provide an option to do it directly. This would effectively fork a repository.

Add A Repository

For the sake of continuity with the last post, I will use the small example repository ‘MyNewCode’ for my first attempt.

Create New Repository

Notice the informative statement regarding pricing. Any costs of the source code repository will be associated with the project. For my situation, I’m going to use the project ‘GCPTraining’ which I have set aside for learning GCP. (With a very small budget!) After reading through the pricing documentation, I am fairly confident that I will be able to post all my repositories up to Google with little or no cost. I’m the only one doing pushes to the repository so I don’t think I will come anywhere near their maximum allowed pushes for the free tier.

After pressing ‘Create’, I am directed to a page containing instructions on how to push code from local into the repository. Well, that seems pretty painless.

Add A Repository

There are several ways to connect to the repository. I am going to stick with SSH as I’m already familiar with the method.

Conceptually, here is what the instructions describe. The git remote add google ssh://... command will add a second remote repository called google to the already existing origin remote repository.

Adding A remote

After the additional remote has been added, then I’ll push everything (--all) from a local repository to the named google remote.

Adding A remote

But before we can do that, we have to clear up some ssh related details.

Configuring ssh

I glossed over this a bit in my last post, and thought I would walk through the process for this one. In order to ensure that only authorized people can push/pull code from the repository, Google is requiring that I configure a public/private key pair. Google will get a copy of the public key, and when I try to pull or push something from/to the repository, that public key will be compared to my private key to verify that they are, in fact, a pair.

ssh-keygen

I choose to create new named public/private key pairs for various services rather than depending on the default keypair. This can be done with the ssh-keygen tool and using the -f option to specify the destination file names for the resulting public and private keys. Here is the command and interactions… Note that no passphrase is entered when prompted, just hit enter.

$ ssh-keygen -f $HOME/.ssh/google_cloud_source_repositories_gcptraining
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/**redacted**/.ssh/google_cloud_source_repositories_gcptraining.
Your public key has been saved in /home/**redacted**/.ssh/google_cloud_source_repositories_gcptraining.pub.
The key fingerprint is:
SHA256:6zCupB8Yfakefakefake8DFbgds8H6jjzIN4MA6Anfo **redacted**@hostname
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|    .            |
|.. o .           |
|o o + o          |
|.o.+ * .S        |
|=fake o ..       |
|+++*= +..        |
|o+E=.*.+         |
|..oBX==o.        |
+----[SHA256]-----+

As described in ssh-keygen results, the program generated a private key file called google_cloud_source_repositories_gcptraining. It also created a public key file called google_cloud_source_repositories_gcptraining.pub.

Both files are located in the standard $HOME/.ssh directory where ssh will look for them and where other related ssh configuration information resides.

SSH config

How does ssh know which private key to use to validate against the public key that we supplied to Google? Well it doesn’t yet. That is another configuration change. I will tell ssh to use the google_cloud_source_repositories_gcptraining private key when it receives a request to validate from the host source.developers.google.com.

$ cat ~/.ssh/config
Host source.developers.google.com
 IdentityFile ~/.ssh/google_cloud_source_repositories_gcptraining

SSH $HOME/.ssh permissions

To verify that the permissions on your $HOME/.ssh directory are only visible to you. Use this command.

$ ls -ald $HOME/.ssh
drwx------ 2 **redacted** **redacted** 4096 Sep 18 09:37 /home/**redacted**/.ssh/

You should expect to see:

drwx------

Any other permissions signature is right out. It would indicate that groups or others can view your private keys. If they are not set as described above, then set them1.

$ chmod u=rwx,g=,o= $HOME/.ssh

What’s the point of having a secret if other people can read it? Also ssh will not work if it identifies that your $HOME/.ssh directory is not private.

Share public key

Now that we have a newly created public/private key pair, I can share the public key with Google. The easiest way to do this is cat the google_cloud_source_repositories_gcptraining.pubfile and copy and paste the entire contents into the field provided.

Register SSH key

Adding the Remote

Using the directions provided, I’ll use this command to add an additional Git remote:

$ git remote add google
ssh://**redacted**@gmail.com@source.developers.google.com:2022/p/**redacted**/r/MyNewCode

To see what remotes are now define in the sandbox.

$ git remote -v
google	ssh://**redacted**@gmail.com@source.developers.google.com:2022/p/**redacted**/r/MyNewCode (fetch)
google	ssh://**redacted**@gmail.com@source.developers.google.com:2022/p/**redacted**/r/MyNewCode (push)
origin	ssh://**redacted**@hostname:/home/**redacted**/GitSharedRepo/MyNewCode.git (fetch)
origin	ssh://**redacted**@hostname:/home/**redacted**/GitSharedRepo/MyNewCode.git (push)

Pushing to remote

Now that I have established a second remote, I can push to the remote by specifying it in the git push command. I have to answer yest to add the host to the $HOME/.ssh/known-hosts file on the first attempt. Subsequent pushes will not prompt for this.

$ git push --all google
The authenticity of host '[source.developers.google.com]:2022 ([209.85.232.82]:2022)' can't be established.
ECDSA key fingerprint is SHA256:AGvEpqYNMqsRNIviwyk4J4HM0lEyfakefakefakefake434.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[source.developers.google.com]:2022,[209.85.232.82]:2022' (ECDSA) to the list of known hosts.
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 457 bytes | 0 bytes/s, done.
Total 6 (delta 0), reused 6 (delta 0)
To ssh://gmail.com@source.developers.google.com:2022/p/**redacted**/r/MyNewCode
 * [new branch]      master -> master

If you try these directions on your own and you get the following error:

$ git push --all google
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

The two most likely causes are that either your $HOME/.ssh directory is not private and/or ssh is using the default private key to validate against the public key rather than using the private key specifically set for validations with the host source.developers.google.com. Perhaps go review the section ‘SSH Remote’?

Successfully Pushed to Google

Now that the source code has been pushed up to the remote, I can go take a look at the Google Cloud Source Repository interface to see what it looks like.

Here is the repository listing screen:

RepositoryListing

And the specifically ‘MyNewCode’ repository information.

MyNewCode

It’s a little sparse as I only have one file in this test repo. That will change soon.

But that’s enough for now.

References

Cloud Source Repositories


  1. I’m a fan of explicit chmod. What the heck does 700 really mean anyway? ↩︎