Reputation: 563
I'm using ansible (Trellis) to deploy my projects.
I have a repo on github.
This is my ansible code
- name: UPDATE - Clone project files
become: yes
# become_user: "{{ project.user.name | default(ansible_web_user) }}"
git:
repo: "{{ project.git.ssh }}"
dest: "{{ project_root }}/shared/source"
version: "{{ project.git.branch | default('master') }}"
accept_hostkey: "{{ project.git.accept_hostkey | default(repo_accept_hostkey | default(true)) }}"
force: yes
# key_file: "/root/.ssh/id_rsa.pub"
ignore_errors: false
no_log: false
register: git_clone
For some days this error has appeared for no apparent reason, nothing has changed
FAILED! => {"changed": false, "cmd": "/usr/bin/git ls-remote origin -h refs/heads/master", "msg": "fatal: 'origin' does not appear to be a git repository\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.", "rc": 128, "stderr": "fatal: 'origin' does not appear to be a git repository\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.\n", "stderr_lines": ["fatal: 'origin' does not appear to be a git repository", "fatal: Could not read from remote repository.", "", "Please make sure you have the correct access rights", "and the repository exists."], "stdout": "", "stdout_lines": []}
I've tried several solutions, even removing the forwardAgent
and forcing the key_file
directly into the git call. It still returns an error.
But if I connect via ssh to the target machine and try to do a git clone ....
everything works.
I don't understand what the problem could be.
Upvotes: 4
Views: 5121
Reputation: 600
I also ran into this a few months ago:
- name: "Git clone"
git:
repo: "ssh://[email protected]/somewhere/something.git"
accept_hostkey: yes
key_file: "/foo/bar/{{ deployment_name }}/.ssh/id_rsa"
dest: "/foo/bar/{{ deployment_name }}/foofoo/barbar"
version: "{{ my_version }}"
The root cause seems to be that Ansible is running git as root (or become_user
), while the git clone on disk is (on purpose) owned by someone else.
Also, the message "'origin' does not appear to be a git repository" from git is misleading.
I had to resort to desperate measures to uncover this, though, namely replacing /usr/bin/git
with:
#!/bin/bash
mkdir -p /tmp/git-db < /dev/null || exit 1
env < /dev/null > /tmp/git-db/git.$$.env 2> /tmp/git-db/err
echo "$@" < /dev/null > /tmp/git-db//git.$$.args 2> /tmp/git-db/err
pwd < /dev/null > /tmp/git-db//git.$$.pwd 2> /tmp/git-db/err
id < /dev/null > /tmp/git-db//git.$$.id 2> /tmp/git-db/err
#sleep 3600 < /dev/null 2> /tmp/git-db/err
exec /usr/bin/git.real "$@"
Looking at the /tmp/git-db/git.*.id
files (and ps
with the sleep enabled) showed that ansible was running /usr/bin/git as root. Testing git as root on the gave a clue to the workaround OP already posted:
root@foo-app01:/data/www/foo/foobar# git status
fatal: unsafe repository ('/data/www/foo/foobar' is owned by someone else)
To add an exception for this directory, call:
git config --global --add safe.directory /data/www/foo/foobar
Reproducing the git invocation that Ansible actually chokes on produced the same broken error message we've seen:
root@foo-app01:/data/www/foo/foobar# GIT_SSH_OPTS=-o StrictHostKeyChecking=no GIT_KEY=/data/www/foo/.ssh/id_rsa /usr/bin/git.real ls-remote origin -h refs/heads/master
fatal: 'origin' does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
As OP already mentioned, whitelisting the directory in the target machine's git configuration works around the issue:
(EDIT: replaced "--add" with idempotent syntax. Using --add appends redundant lines to your /root/.gitconfig on every execution (see git-config(1)
).
- name: "Patch /root/.gitconfig"
# This invocation (without --add, with the dir name twice) is idempotent
command: |-
git config --global safe.directory /data/www/{{ foo }}/{{ bar}} /data/www/{{ foo }}/{{ bar}}
A more appropriate fix would be to execute git as the user that owns the git clone directory. This should be possible with become_user
, but adding the incantations to the invocation has no effect. With ...
- name: "Git clone"
become_user: foobar
become: true
git:
repo: "ssh://[email protected]/somewhere/something.git"
accept_hostkey: yes
key_file: "/foo/bar/{{ deployment_name }}/.ssh/id_rsa"
dest: "/foo/bar/{{ deployment_name }}/foofoo/barbar"
version: "{{ my_version }}"
... ansible is still executing /usr/bin/git
as root, evidenced by the wrapper above. This happens on ansible 2.9 and 6.2.0 (installed using pip).
Upvotes: 4
Reputation: 563
Adding
- name: UPDATE - Safe Directory
command: git config --global --add safe.directory {{ project_root }}/shared/source
check_mode: no
and editing
- name: UPDATE - Clone project files
# become: yes
# become_user: "{{ project.user.name | default(ansible_web_user) }}"
git:
repo: "{{ project.git.ssh }}"
dest: "{{ project_root }}/shared/source"
version: "{{ project.git.branch | default('master') }}"
accept_hostkey: "{{ project.git.accept_hostkey | default(repo_accept_hostkey | default(true)) }}"
force: yes
key_file: "/root/.ssh/id_rsa"
update: no
ignore_errors: false
no_log: false
register: git_clone
I solve the problem ;)
Upvotes: 3
Reputation: 1326596
# key_file: "/root/.ssh/id_rsa.pub"
Note, the key_file
attribute of the git
Ansible module is supposed to reference a private key, not the public one.
But check first the value of {{ project.git.ssh }}
, to make sure it is a valid GitHub SSH URL like [email protected]:me/myRepo
. If not, or if empty, that would explain the fatal: 'origin' does not appear to be a git repository
error message.
Upvotes: 0