Skip to content

Commit 4f21a78

Browse files
use tar to transfer configuration files to the remote server
1 parent a7b304f commit 4f21a78

File tree

5 files changed

+76
-4
lines changed

5 files changed

+76
-4
lines changed

config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,8 @@ func (c *Config) GetRemote(remoteName string) (*Remote, error) {
709709
remote := NewRemote(c, remoteName)
710710
err := c.unmarshalKey(c.flatKey(constants.SectionConfigurationRemotes, remoteName), remote)
711711

712+
rootPath := filepath.Dir(c.GetConfigFile())
713+
remote.SetRootPath(rootPath)
712714
return remote, err
713715
}
714716

config/remote .go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,10 @@ func NewRemote(config *Config, name string) *Remote {
1818
}
1919
return remote
2020
}
21+
22+
// SetRootPath changes the path of all the relative paths and files in the configuration
23+
func (r *Remote) SetRootPath(rootPath string) {
24+
for i := range r.SendFiles {
25+
r.SendFiles[i] = fixPath(r.SendFiles[i], expandEnv, absolutePrefix(rootPath))
26+
}
27+
}

send.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package main
22

33
import (
4+
"archive/tar"
45
"fmt"
56
"io"
7+
"net/http"
8+
"os"
69

10+
"github.com/creativeprojects/clog"
711
"github.com/creativeprojects/resticprofile/ssh"
812
)
913

@@ -15,16 +19,58 @@ func sendProfileCommand(w io.Writer, cmdCtx commandContext) error {
1519
if err != nil {
1620
return err
1721
}
22+
// send the files to the remote using tar
23+
handler := http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
24+
writer := tar.NewWriter(resp)
25+
defer writer.Close()
26+
27+
for _, filename := range remote.SendFiles {
28+
fileInfo, err := os.Stat(filename)
29+
if err != nil {
30+
clog.Errorf("unable to stat file %s: %v", filename, err)
31+
continue
32+
}
33+
fileHeader, err := tar.FileInfoHeader(fileInfo, "")
34+
if err != nil {
35+
clog.Errorf("unable to create tar header for file %s: %v", filename, err)
36+
continue
37+
}
38+
err = writer.WriteHeader(fileHeader)
39+
if err != nil {
40+
clog.Errorf("unable to write tar header for file %s: %v", filename, err)
41+
break
42+
}
43+
file, err := os.Open(filename)
44+
if err != nil {
45+
clog.Errorf("unable to open file %s: %v", filename, err)
46+
continue
47+
}
48+
defer file.Close()
49+
50+
written, err := io.Copy(writer, file)
51+
if err != nil {
52+
clog.Errorf("unable to write file %s: %v", filename, err)
53+
break
54+
}
55+
if written != fileInfo.Size() {
56+
clog.Errorf("file %s written %d bytes, expected %d", filename, written, fileInfo.Size())
57+
break
58+
}
59+
clog.Debugf("file %s written %d bytes", filename, written)
60+
}
61+
})
1862
cnx := ssh.NewSSH(ssh.Config{
1963
Host: remote.Host,
2064
Username: remote.Username,
2165
PrivateKeyPath: remote.PrivateKeyPath,
2266
KnownHostsPath: remote.KnownHostsPath,
67+
Handler: handler,
2368
})
69+
defer cnx.Close()
70+
2471
err = cnx.Connect()
2572
if err != nil {
2673
return err
2774
}
28-
defer cnx.Close()
2975
return nil
3076
}

ssh/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ssh
22

33
import (
44
"fmt"
5+
"net/http"
56
"os"
67
"path/filepath"
78
"strings"
@@ -12,6 +13,7 @@ type Config struct {
1213
Username string
1314
PrivateKeyPath string
1415
KnownHostsPath string
16+
Handler http.Handler
1517
}
1618

1719
func (c *Config) Validate() error {

ssh/ssh.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ package ssh
22

33
import (
44
"bytes"
5+
"context"
56
"fmt"
67
"log"
78
"net"
89
"net/http"
910
"os"
11+
"time"
1012

1113
"github.com/creativeprojects/clog"
1214
"golang.org/x/crypto/ssh"
@@ -20,6 +22,7 @@ type SSH struct {
2022
port int
2123
client *ssh.Client
2224
tunnel net.Listener
25+
server *http.Server
2326
}
2427

2528
func NewSSH(config Config) *SSH {
@@ -71,10 +74,14 @@ func (s *SSH) Connect() error {
7174
}
7275

7376
go func() {
77+
s.server = &http.Server{
78+
Handler: s.config.Handler,
79+
}
7480
// Serve HTTP with your SSH server acting as a reverse proxy.
75-
http.Serve(s.tunnel, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
76-
fmt.Fprintf(resp, "Hello world!\n")
77-
}))
81+
err := s.server.Serve(s.tunnel)
82+
if err != nil && err != http.ErrServerClosed {
83+
clog.Warningf("unable to serve http: %s", err)
84+
}
7885
}()
7986

8087
// Each ClientConn can support multiple interactive sessions,
@@ -103,6 +110,14 @@ func (s *SSH) Close() {
103110
clog.Warningf("unable to close tunnel: %s", err)
104111
}
105112
}
113+
if s.server != nil {
114+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
115+
defer cancel()
116+
err := s.server.Shutdown(ctx)
117+
if err != nil {
118+
clog.Warningf("unable to close http server: %s", err)
119+
}
120+
}
106121
if s.client != nil {
107122
err := s.client.Close()
108123
if err != nil {

0 commit comments

Comments
 (0)