Remote git pull durch SSH Tunnel

Code-Stücke können hier veröffentlicht werden.
Antworten
jb_alvarado
User
Beiträge: 55
Registriert: Mittwoch 11. Juli 2018, 11:11

Wenn man seine Git Repos lokal hostet, z.B. mit Gogs, aber von einem online Server aus die Möglichkeit haben möchte einen git pull zu machen, kann dieses Script nützlich sein:

Code: Alles auswählen

#!/usr/bin/env python3

import os
import signal
import sys
import subprocess
from time import sleep

# Read STDIN (Format: "from_commit to_commit branch_name")
(old, new, branch) = sys.stdin.read().split()

# Only deploy if master branch was pushed
if branch == 'refs/heads/master':
    tunnel = subprocess.Popen(
        'ssh -R 8888:localhost:22 example.org', stdout=subprocess.PIPE,
        shell=True, preexec_fn=os.setsid)

    while not tunnel.pid:
        sleep(1)

    subprocess.call([
        "ssh", "example.org", "git",
        "--git-dir=/home/user/git/project.git",
        "--work-tree=/var/www/project/",
        "pull", "origin", "+refs/heads/master:refs/heads/master"])

os.killpg(os.getpgid(tunnel.pid), signal.SIGTERM)
Vor dem Pull muss natürlich ein Klone gemacht sein, für das obige Beispiel ist das git Verzeichnis nicht im Working Tree.

Schritte hierzu:

Vom System, auf dem das git Repo verwaltet wird, aus ein SSH Tunnel aufbauen:

Code: Alles auswählen

ssh -R 8888:localhost:22 example.org
(SSH Key sollte hinterlegt werden und gegebenenfalls in die ssh config eingetragen sein)

In einem zweiten Terminal noch eine SSH Verbindung zum Server aufbauen und dort das Repo klonen:

Code: Alles auswählen

git clone ssh://user@localhost:8888/user/project.git -git-dir=/home/user/git/project.git --work-tree=/var/www/project/
Hat das geklappt, das obige Script als post-receive Script als git-Hook auf dem lokalen git Server ablegen.

Wenn jetzt lokal git Pushs auf den Master gemacht werden, werden sie automatisch Online abgeglichen.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich verstehe nicht, warum man das braucht. Wen ich per SSH auf example.org komme, dann kann ich doch einfach dahin pushen. Und pullen.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nachtrag: ich muss auf dem example.org natuerlich mit "git init" repo erstellen, bevor ich dahin pushen kann.
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@jb_alvarado: Der erste Kommentar sagt ja nicht so wirklich viel aus. Den könnte man doch eigentlich dadurch ersetzen das man die Variablen auf die aufgeteilt wird `from_commit`, `to_commit`, und `branch_name` nennt‽

Die letzte Zeile ist falsch eingerückt weil es `tunnel` ja nur gibt wenn der ``if``-Zweig ausgeführt wird.

Die Dokumentation rät von `preexec_fn` ab – roter Kasten mit „Warning“. Statt dort `os.setsid()` anzugeben, soll man stattdessen dafür seit Python 3.2 das `start_new_session`-Argument verwenden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
jb_alvarado
User
Beiträge: 55
Registriert: Mittwoch 11. Juli 2018, 11:11

Danke für den Hinweis blackjack, das mit der Einrückung wird wohl ein Copy&Paste Fehler sein, kann das jetzt leider nicht mehr korrigieren, die anderen Tipps werde ich berücksichtigen.

@deets, ja hast recht das geht auch, aber wie machst du ein Push, wenn du nicht von der Online Quelle geklont hast? Mir geht es ja darum, dass ich lokal mein Repo mit Gogs, oder gitlab etc. verwalte. Davon tue ich dann pullen und pushen. Wenn ich dann Online pushen möchte müsste ich jedes mal vorher die url switchen - kann man sich aussuchen, was einem angenehmer ist.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Noe, musst du nicht. Du kannst problemlos mehrere remotes anlegen. Per "git push -u <remote> <branch>" hast du dann fuer die Zukunft einen default, aber "git push <anderes-remote> <branch>" ist jetzt ja auch nicht wirklich weniger Aufwand als da irgendwelche Tunnel zu schiessen. Da kannst du dir dann einfach ein alias bauen (gorp zB fuer git push <other>) und gut ist.
jb_alvarado
User
Beiträge: 55
Registriert: Mittwoch 11. Juli 2018, 11:11

Ok, das klingt gut. Würde das auch mit einem Serverside post-receive hook gehen, damit alle Arbeitsplätze die in das lokal Repo pushen automatisch Updates online stellen.
Und wie siehst du das:
A quick rule of thumb is to never push into a repository that has a work tree attached to it, until you know what you are doing.
Quelle: https://git.wiki.kernel.org/index.php/G ... cece5f6e73

Hier arbeitet deshalb auch jemand extra mit zwei Repos:
http://joemaller.com/990/a-web-focused-git-workflow/
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mit hooks arbeite ich persoenlich nicht. Sehe da aber auch die Notwendigkeit von Abkuerzungen nicht so, denn da kannst du das remote ja immer auch explizit angeben.

Was die Faustregel angeht: das hat ja mit der Diskussion hier erstmal nichts zu tun. Nur weil du "nur" pullst weil du einen Mirror willst, ist das konzeptionell fuer beide Faelle gleich. Wenn das deine Sorge ist, dann mach halt "git init --bare --shared", und gut ist.
Antworten