Skip to content

Commit e6b586b

Browse files
feat: restart mirror on binary change (#461)
if the binary has changed the mirror should stop so systemd can restart it using the new binary.
1 parent f557d9d commit e6b586b

File tree

7 files changed

+60
-20
lines changed

7 files changed

+60
-20
lines changed

cmd/embedded-cluster/install.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ var ErrNothingElseToAdd = fmt.Errorf("")
3434
// service is responsible for serving on localhost, through http, all files that are used
3535
// during a cluster upgrade.
3636
func installAndEnableLocalArtifactMirror() error {
37-
ourbin := defaults.PathToEmbeddedClusterBinary("local-artifact-mirror")
38-
hstbin := defaults.LocalArtifactMirrorPath()
39-
if err := helpers.MoveFile(ourbin, hstbin); err != nil {
40-
return fmt.Errorf("unable to move local artifact mirror binary: %w", err)
41-
}
4237
if err := goods.MaterializeLocalArtifactMirrorUnitFile(); err != nil {
4338
return fmt.Errorf("failed to materialize artifact mirror unit: %w", err)
4439
}

cmd/embedded-cluster/uninstall.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,6 @@ var resetCommand = &cli.Command{
402402
if err := os.RemoveAll(lamPath); err != nil {
403403
return err
404404
}
405-
if err := os.RemoveAll(defaults.LocalArtifactMirrorPath()); err != nil {
406-
return err
407-
}
408405
}
409406

410407
if _, err := os.Stat(defaults.EmbeddedClusterHomeDirectory()); err == nil {

cmd/local-artifact-mirror/serve.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ var serveCommand = &cli.Command{
3737
stop := make(chan os.Signal, 1)
3838
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
3939

40+
if err := startBinaryWatcher(stop); err != nil {
41+
panic(err)
42+
}
43+
4044
server := &http.Server{Addr: "127.0.0.1:50000"}
4145
go func() {
4246
fmt.Println("Starting server on 127.0.0.1:50000")
@@ -60,6 +64,34 @@ var serveCommand = &cli.Command{
6064
},
6165
}
6266

67+
// startBinaryWatcher starts a loop that observes the binary until its modification
68+
// time changes. When the modification time changes a SIGTERM is send in the provided
69+
// channel.
70+
func startBinaryWatcher(stop chan os.Signal) error {
71+
fpath := defaults.PathToEmbeddedClusterBinary("local-artifact-mirror")
72+
stat, err := os.Stat(fpath)
73+
if err != nil {
74+
return fmt.Errorf("unable to stat %s: %s", fpath, err)
75+
}
76+
lastmod := stat.ModTime()
77+
go func() {
78+
fmt.Println("Watching for changes in the binary")
79+
ticker := time.NewTicker(5 * time.Second)
80+
for range ticker.C {
81+
if stat, err = os.Stat(fpath); err != nil {
82+
fmt.Println("Unable to stat binary:", err)
83+
continue
84+
}
85+
if stat.ModTime().Equal(lastmod) {
86+
continue
87+
}
88+
fmt.Println("Binary changed, sending signal to stop")
89+
stop <- syscall.SIGTERM
90+
}
91+
}()
92+
return nil
93+
}
94+
6395
// logAndFilterRequest is a middleware that logs the HTTP request details. Returns 404
6496
// if attempting to read the log files as those are not served by this server.
6597
func logAndFilterRequest(handler http.Handler) http.Handler {

e2e/local-artifact-mirror_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package e2e
22

33
import (
4+
"strings"
45
"testing"
56
"time"
67

@@ -54,5 +55,31 @@ func TestLocalArtifactMirror(t *testing.T) {
5455
t.Fatalf("we should not be able to fetch paths with ../")
5556
}
5657

58+
t.Logf("testing local artifact mirror restart after materialize")
59+
command = []string{"embedded-cluster", "materialize"}
60+
if _, _, err := RunCommandOnNode(t, tc, 0, command); err != nil {
61+
t.Fatalf("fail materialize embedded cluster binaries: %v", err)
62+
}
63+
64+
t.Logf("waiting to verify if local artifact mirror has restarted")
65+
time.Sleep(20 * time.Second)
66+
67+
command = []string{"journalctl", "-u", "local-artifact-mirror"}
68+
stdout, _, err := RunCommandOnNode(t, tc, 0, command)
69+
if err != nil {
70+
t.Fatalf("fail to get journalctl logs: %v", err)
71+
}
72+
73+
expected := []string{
74+
"Binary changed, sending signal to stop",
75+
"Scheduled restart job, restart counter is at",
76+
}
77+
for _, str := range expected {
78+
if !strings.Contains(stdout, str) {
79+
t.Fatalf("expected %q in journalctl logs, got %q", str, stdout)
80+
}
81+
t.Logf("found %q in journalctl logs", str)
82+
}
83+
5784
t.Logf("%s: test complete", time.Now().Format(time.RFC3339))
5885
}

pkg/defaults/defaults.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,6 @@ func K0sBinaryPath() string {
6464
return def().K0sBinaryPath()
6565
}
6666

67-
// LocalArtifactMirrorPath calls LocalArtifactMirrorPath on the default provider.
68-
func LocalArtifactMirrorPath() string {
69-
return def().LocalArtifactMirrorPath()
70-
}
71-
7267
// PathToEmbeddedClusterBinary calls PathToEmbeddedClusterBinary on the default provider.
7368
func PathToEmbeddedClusterBinary(name string) string {
7469
return def().PathToEmbeddedClusterBinary(name)

pkg/defaults/provider.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,6 @@ func (d *Provider) K0sBinaryPath() string {
105105
return "/usr/local/bin/k0s"
106106
}
107107

108-
// LocalArtifactMirrorPath returns the path where we install the local artifact mirror
109-
// binary.
110-
func (d *Provider) LocalArtifactMirrorPath() string {
111-
return "/usr/local/bin/local-artifact-mirror"
112-
}
113-
114108
// PathToEmbeddedClusterBinary is an utility function that returns the full path to a
115109
// materialized binary that belongs to embedded-cluster. This function does not check
116110
// if the file exists.

pkg/goods/systemd/local-artifact-mirror.service

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Description=Embedded Cluster Local Artifact Mirror
33

44
[Service]
5-
ExecStart=/usr/local/bin/local-artifact-mirror serve
5+
ExecStart=/var/lib/embedded-cluster/bin/local-artifact-mirror serve
66
Restart=always
77
RestartSec=5s
88

0 commit comments

Comments
 (0)