diff --git a/cgroups/cgroupsv1.go b/cgroups/cgroupsv1.go index a1b648f..1c356ad 100644 --- a/cgroups/cgroupsv1.go +++ b/cgroups/cgroupsv1.go @@ -23,7 +23,6 @@ func AddV1( if err != nil { return fmt.Errorf("create cgroups (path: %s): %w", path, err) } - defer cg.Delete() if err := cg.Add(cgroup1.Process{Pid: pid}); err != nil { return fmt.Errorf("add cgroups (path: %s, pid: %d): %w", path, pid, err) @@ -31,3 +30,18 @@ func AddV1( return nil } + +func DeleteV1(path string) error { + staticPath := cgroup1.StaticPath(path) + + cg, err := cgroup1.Load(staticPath) + if err != nil { + return fmt.Errorf("load cgroups (path: %s): %w", path, err) + } + + if err := cg.Delete(); err != nil { + return fmt.Errorf("delete cgroups (path: %s): %w", path, err) + } + + return nil +} diff --git a/container/container_delete.go b/container/container_delete.go index ef87de3..31d82c0 100644 --- a/container/container_delete.go +++ b/container/container_delete.go @@ -4,7 +4,9 @@ import ( "fmt" "os" "path/filepath" - "syscall" + + "github.com/nixpig/brownie/cgroups" + "golang.org/x/sys/unix" ) func (c *Container) Delete(force bool) error { @@ -12,12 +14,12 @@ func (c *Container) Delete(force bool) error { return fmt.Errorf("container cannot be deleted in current state (%s)", c.Status()) } - process, err := os.FindProcess(c.PID()) - if err != nil { - return fmt.Errorf("find container process (%d): %w", c.PID(), err) + if err := c.Kill(unix.SIGKILL); err != nil { + return fmt.Errorf("send sigkill to container: %w", err) } - if process != nil { - process.Signal(syscall.Signal(9)) + + if err := cgroups.DeleteV1(c.Spec.Linux.CgroupsPath); err != nil { + return fmt.Errorf("delete cgroups: %w", err) } if err := os.RemoveAll(filepath.Join(containerRootDir, c.ID())); err != nil { diff --git a/internal/commands/kill.go b/internal/commands/kill.go index c04d070..12bf7ce 100644 --- a/internal/commands/kill.go +++ b/internal/commands/kill.go @@ -1,8 +1,6 @@ package commands import ( - "fmt" - "github.com/nixpig/brownie/container" "github.com/nixpig/brownie/signal" ) @@ -18,10 +16,7 @@ func Kill(opts *KillOpts) error { return err } - s, err := signal.FromString(opts.Signal) - if err != nil { - return fmt.Errorf("failed to convert to signal: %w", err) - } + s := signal.FromString(opts.Signal) return cntr.Kill(s) } diff --git a/signal/signal.go b/signal/signal.go index 091de26..917117a 100644 --- a/signal/signal.go +++ b/signal/signal.go @@ -1,140 +1,139 @@ package signal import ( - "fmt" "syscall" ) -func FromInt(s int) (syscall.Signal, error) { +func FromInt(s int) syscall.Signal { switch s { case 1: - return syscall.SIGHUP, nil + return syscall.SIGHUP case 2: - return syscall.SIGINT, nil + return syscall.SIGINT case 3: - return syscall.SIGQUIT, nil + return syscall.SIGQUIT case 4: - return syscall.SIGILL, nil + return syscall.SIGILL case 5: - return syscall.SIGTRAP, nil + return syscall.SIGTRAP case 6: - return syscall.SIGIOT, nil + return syscall.SIGIOT case 7: - return syscall.SIGBUS, nil + return syscall.SIGBUS case 8: - return syscall.SIGFPE, nil + return syscall.SIGFPE case 9: - return syscall.SIGKILL, nil + return syscall.SIGKILL case 10: - return syscall.SIGUSR1, nil + return syscall.SIGUSR1 case 11: - return syscall.SIGSEGV, nil + return syscall.SIGSEGV case 12: - return syscall.SIGUSR2, nil + return syscall.SIGUSR2 case 13: - return syscall.SIGPIPE, nil + return syscall.SIGPIPE case 14: - return syscall.SIGALRM, nil + return syscall.SIGALRM case 15: - return syscall.SIGTERM, nil + return syscall.SIGTERM case 16: - return syscall.SIGSTKFLT, nil + return syscall.SIGSTKFLT case 17: - return syscall.SIGCHLD, nil + return syscall.SIGCHLD case 18: - return syscall.SIGCONT, nil + return syscall.SIGCONT case 19: - return syscall.SIGSTOP, nil + return syscall.SIGSTOP case 20: - return syscall.SIGTSTP, nil + return syscall.SIGTSTP case 21: - return syscall.SIGTTIN, nil + return syscall.SIGTTIN case 22: - return syscall.SIGTTOU, nil + return syscall.SIGTTOU case 23: - return syscall.SIGURG, nil + return syscall.SIGURG case 24: - return syscall.SIGXCPU, nil + return syscall.SIGXCPU case 25: - return syscall.SIGXFSZ, nil + return syscall.SIGXFSZ case 26: - return syscall.SIGVTALRM, nil + return syscall.SIGVTALRM case 27: - return syscall.SIGPROF, nil + return syscall.SIGPROF case 28: - return syscall.SIGWINCH, nil + return syscall.SIGWINCH case 29: - return syscall.SIGIO, nil + return syscall.SIGIO case 30: - return syscall.SIGPWR, nil + return syscall.SIGPWR } - return 0, fmt.Errorf("convert int to signal (%d)", s) + return 0 } -func FromString(s string) (syscall.Signal, error) { +func FromString(s string) syscall.Signal { switch s { case "SIGHUP", "HUP", "1": - return syscall.SIGHUP, nil + return syscall.SIGHUP case "SIGINT", "INT", "2": - return syscall.SIGINT, nil + return syscall.SIGINT case "SIGQUIT", "QUIT", "3": - return syscall.SIGQUIT, nil + return syscall.SIGQUIT case "SIGILL", "ILL", "4": - return syscall.SIGILL, nil + return syscall.SIGILL case "SIGTRAP", "TRAP", "5": - return syscall.SIGTRAP, nil + return syscall.SIGTRAP case "SIGIOT", "IOT", "6": - return syscall.SIGIOT, nil + return syscall.SIGIOT case "SIGBUS", "BUS", "7": - return syscall.SIGBUS, nil + return syscall.SIGBUS case "SIGFPE", "FPE", "8": - return syscall.SIGFPE, nil + return syscall.SIGFPE case "SIGKILL", "KILL", "9": - return syscall.SIGKILL, nil + return syscall.SIGKILL case "SIGUSR1", "USR1", "10": - return syscall.SIGUSR1, nil + return syscall.SIGUSR1 case "SIGSEGV", "SEGV", "11": - return syscall.SIGSEGV, nil + return syscall.SIGSEGV case "SIGUSR2", "USR2", "12": - return syscall.SIGUSR2, nil + return syscall.SIGUSR2 case "SIGPIPE", "PIPE", "13": - return syscall.SIGPIPE, nil + return syscall.SIGPIPE case "SIGALRM", "ALRM", "14": - return syscall.SIGALRM, nil + return syscall.SIGALRM case "SIGTERM", "TERM", "15": - return syscall.SIGTERM, nil + return syscall.SIGTERM case "SIGSTKFLT", "STKFLT", "16": - return syscall.SIGSTKFLT, nil + return syscall.SIGSTKFLT case "SIGCHLD", "CHLD", "17": - return syscall.SIGCHLD, nil + return syscall.SIGCHLD case "SIGCONT", "CONT", "18": - return syscall.SIGCONT, nil + return syscall.SIGCONT case "SIGSTOP", "STOP", "19": - return syscall.SIGSTOP, nil + return syscall.SIGSTOP case "SIGTSTP", "TSTP", "20": - return syscall.SIGTSTP, nil + return syscall.SIGTSTP case "SIGTTIN", "TTIN", "21": - return syscall.SIGTTIN, nil + return syscall.SIGTTIN case "SIGTTOU", "TTOU", "22": - return syscall.SIGTTOU, nil + return syscall.SIGTTOU case "SIGURG", "URG", "23": - return syscall.SIGURG, nil + return syscall.SIGURG case "SIGXCPU", "XCPU", "24": - return syscall.SIGXCPU, nil + return syscall.SIGXCPU case "SIGXFSZ", "XFSZ", "25": - return syscall.SIGXFSZ, nil + return syscall.SIGXFSZ case "SIGVTALRM", "VTALRM", "26": - return syscall.SIGVTALRM, nil + return syscall.SIGVTALRM case "SIGPROF", "PROF", "27": - return syscall.SIGPROF, nil + return syscall.SIGPROF case "SIGWINCH", "WINCH", "28": - return syscall.SIGWINCH, nil + return syscall.SIGWINCH case "SIGIO", "IO", "29": - return syscall.SIGIO, nil + return syscall.SIGIO case "SIGPWR", "PWR", "30": - return syscall.SIGPWR, nil + return syscall.SIGPWR } - return syscall.Signal(0), fmt.Errorf("convert string to signal (%s)", s) + return syscall.Signal(0) }