Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"bauklotze/pkg/machine/define"
"bauklotze/pkg/machine/events"
"context"
"errors"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -84,7 +85,9 @@ func RootCmdExecute() {
err := rootCmd.ExecuteContext(context.Background())
if err != nil {
logrus.Errorf("Exit duto error: %v", err)
events.NotifyError(err)
if errors.Is(err, define.ErrVMAlreadyRunning) {
events.NotifyError(err)
}
registry.NotifyAndExit(1)
} else {
registry.NotifyAndExit(0)
Expand Down
1 change: 1 addition & 0 deletions pkg/api/backend/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ import "errors"
var (
ErrMachineConfigNull = errors.New("machineConfig is null")
ErrStreamNotSupport = errors.New("stream not support")
ErrStopVMFailed = errors.New("stop vm failed")
)
25 changes: 25 additions & 0 deletions pkg/api/backend/stop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package backend

import (
"bauklotze/pkg/machine/ssh/service"
"net/http"

"bauklotze/pkg/api/types"
"bauklotze/pkg/api/utils"
"bauklotze/pkg/machine/vmconfig"
)

func StopVM(w http.ResponseWriter, r *http.Request) {
mc := r.Context().Value(types.McKey).(*vmconfig.MachineConfig)
if mc == nil {
utils.Error(w, http.StatusInternalServerError, ErrMachineConfigNull)
return
}

// in busybox init system, reboot cause vCPU 0 received shutdown signal so the
// krunkit will be shutdown after the vm shutdown
err := service.GracefulShutdownVK(mc)
if err != nil {
utils.Error(w, http.StatusInternalServerError, ErrStopVMFailed)
}
}
1 change: 1 addition & 0 deletions pkg/api/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ func (s *APIServer) Shutdown() error {
func (s *APIServer) setupRouter(r *mux.Router) *mux.Router {
r.Handle("/{name}/info", s.APIHandler(backend.GetInfos)).Methods(http.MethodGet)
r.Handle("/{name}/exec", s.APIHandler(backend.DoExec)).Methods(http.MethodPost)
r.Handle("/{name}/stop", s.APIHandler(backend.StopVM)).Methods(http.MethodPost)
return r
}

Expand Down
1 change: 1 addition & 0 deletions pkg/machine/define/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ var (
ErrConstructVMFile = errors.New("construct VMFile failed")
ErrCatchSignal = errors.New("catch signal")
ErrPPIDNotRunning = errors.New("PPID exited")
ErrVMMExitNormally = errors.New("hypervisor exited normally")
)
5 changes: 4 additions & 1 deletion pkg/machine/shim/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,10 @@ func Wait(ctx context.Context, mc *vmconfig.MachineConfig) error {
case err := <-errChanGvp:
return fmt.Errorf("network provider exit: %w", err)
case err := <-errChanVmm:
return fmt.Errorf("hypervisor exit: %w", err)
if err != nil {
return fmt.Errorf("hypervisor exit: %w", err)
}
return define.ErrVMMExitNormally
}
}

Expand Down
30 changes: 30 additions & 0 deletions pkg/machine/ssh/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"fmt"
"time"

"github.com/sirupsen/logrus"

"bauklotze/pkg/machine/vmconfig"
)

Expand All @@ -30,3 +32,31 @@ func DoSync(mc *vmconfig.MachineConfig) error {
"sync",
})
}

func GracefulShutdownVK(mc *vmconfig.MachineConfig) error {
logrus.Infoln("stop all containers")
if err := run(mc, "podman", []string{
"stop",
"-a",
"-t",
"3",
}); err != nil {
logrus.Warnf("podman stop failed: %v", err)
}

logrus.Infoln("sync disk")
if err := run(mc, "sync", []string{}); err != nil {
logrus.Warnf("sync disk failed: %v", err)
}

logrus.Infoln("stop vm now")
// poweroff (provided by busybox init system) cause vCPU 0 received shutdown signal,and active power off
// so the krunkit will exit clearly after vm shutdown
// halt (provided by busybox init system) shutdown the kernel, but uninterrupted power supply, so the krunkit
// will continue to run after vm shutdown
if err := run(mc, "poweroff", []string{}); err != nil {
return fmt.Errorf("stop vm failed: %w", err)
}

return nil
}
Loading