package main import ( "errors" "flag" "log" "os" "os/signal" "syscall" ) var GruauPort int var GruauPrivateKeyFile string var GruauRepositoriesRoot string var GruauGitHost, GruauWebgitHost string var GruauCertbotAgreeTOS bool var GruauCertbotEmail string func init() { flag.IntVar(&GruauPort, "port", 22, "Port to listen on for SSH 'exec' requests (matching `^git-(receive|upload)-pack '~[0-9a-z_.-]+/[0-9a-z_.-]+\\.git'$`).") flag.StringVar(&GruauPrivateKeyFile, "private-key-file", "/root/.gruau/key/gruau", "Private ssh key (in the OpenSSH format).") flag.StringVar(&GruauRepositoriesRoot, "repositories-root", "/root/gruau-repositories", "All repositories' root (a directory holding directories containing git repositories).") flag.StringVar(&GruauGitHost, "git-host", "", "When nonempty: enable dumb HTTP git transport over port 443 using the given host to issue a Let's Encrypt certificate. Also listens on port 80 redirecting to the `https` scheme.") flag.StringVar(&GruauWebgitHost, "webgit-host", "", "Where to refer HTTP requests which end in the HTML suffix or have a trailing slash to. Only takes effect when `--git-host` is nonempty.") flag.BoolVar(&GruauCertbotAgreeTOS, "certbot-agree-tos", false, "Passed to `certbot` when requesting Let's Encrypt certificates.") flag.StringVar(&GruauCertbotEmail, "certbot-email", "", "Passed to `certbot` when requesting Let's Encrypt certificates.") } func main() { flag.Parse() auth := NewAuth(GruauRepositoriesRoot) gssh := &GruauSSHServer{ RepositoriesRoot: GruauRepositoriesRoot, PrivateKeyFile: GruauPrivateKeyFile, Port: GruauPort, } web := &Web{GitHost: GruauGitHost, WebgitHost: GruauWebgitHost,} done := make(chan error, 1) go func() { done <- gssh.ListenAndServe(auth) }() defer gssh.Shutdown() web.Spawn(func(authtoken string, repo *GitRepository) bool { return auth.HasReadAccess(authtoken, repo) }) defer web.Kill() signals := make(chan os.Signal) signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) select { case <-signals: gssh.Shutdown() case err := <-done: if !errors.Is(err, ErrServerClosed) { log.Printf("gruau: exit failure: %v", err) } break } signal.Reset() log.Printf("gruau: exiting") }