1 // Helper copied to the remote host to run commands and deploy configuration
3 // SPDX-License-Identifier: GPL-3.0-or-later
4 // Copyright (C) 2021-2024 Simon Ruderich
15 "ruderich.org/simon/safcm"
16 "ruderich.org/simon/safcm/remote/ainsl"
17 "ruderich.org/simon/safcm/remote/info"
18 "ruderich.org/simon/safcm/remote/run"
19 "ruderich.org/simon/safcm/remote/sync"
23 log.Fatalf("usage: %[1]s sync\n"+
24 "usage: %[1]s ainsl [options] <path> <line>",
29 // Timestamps are added by `safcm`
39 if len(os.Args) != 2 {
44 err = ainsl.Main(os.Args)
50 log.Fatalf("%s: %v", os.Args[0], err)
54 func mainLoop() error {
55 if term.IsTerminal(int(os.Stdin.Fd())) ||
56 term.IsTerminal(int(os.Stdout.Fd())) {
57 return fmt.Errorf("sync should only be called from `safcm` " +
58 "(redirect stdin/stdout to circumvent this check)")
61 conn := safcm.NewGobConn(os.Stdin, os.Stdout)
63 var logLevel safcm.LogLevel
64 logFunc := func(level safcm.LogLevel, msg string) {
65 if logLevel >= level {
66 // Handling errors here is complex and quite verbose.
67 // If it happens the connection is gone anyway so skip
68 // the error handling.
69 conn.Send(safcm.MsgLog{ //nolint:errcheck
76 var quitResp safcm.MsgQuitResp
84 switch x := x.(type) {
85 case safcm.MsgInfoReq:
86 logLevel = x.LogLevel // set log level globally
87 resp = info.Handle(x, run.ExecRunner{}, logFunc)
88 case safcm.MsgSyncReq:
89 resp = sync.Handle(x, run.ExecRunner{}, logFunc)
90 case safcm.MsgQuitReq:
93 return fmt.Errorf("unsupported message %#v", x)
100 if resp == quitResp {