Skip to content

Commit

Permalink
support runv kill container
Browse files Browse the repository at this point in the history
runv -id container kill signum

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
  • Loading branch information
gao-feng committed Nov 19, 2015
1 parent c34de2e commit fe8ee49
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 0 deletions.
2 changes: 2 additions & 0 deletions hypervisor/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const (
COMMAND_RELEASE
COMMAND_NEWCONTAINER
COMMAND_EXEC
COMMAND_KILL
COMMAND_WRITEFILE
COMMAND_READFILE
COMMAND_ATTACH
Expand Down Expand Up @@ -75,6 +76,7 @@ const (
INIT_WRITEFILE
INIT_READFILE
INIT_NEWCONTAINER
INIT_KILLCONTAINER
)

const (
Expand Down
7 changes: 7 additions & 0 deletions hypervisor/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net"
"os"
"sync"
"syscall"
)

type VmEvent interface {
Expand Down Expand Up @@ -60,6 +61,11 @@ type ExecCommand struct {
Streams *TtyIO `json:"-"`
}

type KillCommand struct {
Container string `json:"container"`
Signal syscall.Signal `json:"signal"`
}

type WriteFileCommand struct {
Container string `json:"container"`
File string `json:"file"`
Expand Down Expand Up @@ -224,6 +230,7 @@ func (qe *StopPodCommand) Event() int { return COMMAND_STOP_POD }
func (qe *ReplacePodCommand) Event() int { return COMMAND_REPLACE_POD }
func (qe *NewContainerCommand) Event() int { return COMMAND_NEWCONTAINER }
func (qe *ExecCommand) Event() int { return COMMAND_EXEC }
func (qe *KillCommand) Event() int { return COMMAND_KILL }
func (qe *WriteFileCommand) Event() int { return COMMAND_WRITEFILE }
func (qe *ReadFileCommand) Event() int { return COMMAND_READFILE }
func (qe *AttachCommand) Event() int { return COMMAND_ATTACH }
Expand Down
41 changes: 41 additions & 0 deletions hypervisor/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io"
"syscall"
"time"

"encoding/json"
Expand Down Expand Up @@ -436,6 +437,46 @@ func (vm *Vm) ReadFile(container, target string) ([]byte, error) {
return nil, fmt.Errorf("Read container %s file %s failed: %s", container, target, cause)
}

func (vm *Vm) KillContainer(container string, signal syscall.Signal) error {
killCmd := &KillCommand{
Container: container,
Signal: signal,
}

Event, err := vm.GetRequestChan()
if err != nil {
return err
}
defer vm.ReleaseRequestChan(Event)

Status, err := vm.GetResponseChan()
if err != nil {
return nil
}
defer vm.ReleaseResponseChan(Status)

Event <- killCmd
vm.ReleaseRequestChan(Event)

for {
Response, ok := <-Status
if !ok {
return fmt.Errorf("kill container %v failed: get response failed", container)
}

glog.V(1).Infof("Got response: %d: %s", Response.Code, Response.Cause)
if Response.Reply.(*KillCommand) == killCmd {
if Response.Cause != "" {
return fmt.Errorf("kill container %v failed: %s", container, Response.Cause)
}

break
}
}

return nil
}

func (vm *Vm) Exec(Stdin io.ReadCloser, Stdout io.WriteCloser, cmd, tag, container string) error {
var command []string
Callback := make(chan *types.VmResponse, 1)
Expand Down
18 changes: 18 additions & 0 deletions hypervisor/vm_states.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,21 @@ func (ctx *VmContext) execCmd(cmd *ExecCommand) {
}
}

func (ctx *VmContext) killCmd(cmd *KillCommand) {
killCmd, err := json.Marshal(*cmd)
if err != nil {
ctx.Hub <- &InitFailedEvent{
Reason: "Generated wrong kill profile " + err.Error(),
}
return
}
ctx.vm <- &DecodedMessage{
Code: INIT_KILLCONTAINER,
Message: killCmd,
Event: cmd,
}
}

func (ctx *VmContext) attachCmd(cmd *AttachCommand) {
idx := ctx.Lookup(cmd.Container)
if cmd.Container != "" && idx < 0 {
Expand Down Expand Up @@ -402,6 +417,7 @@ func unexpectedEventHandler(ctx *VmContext, ev VmEvent, state string) {
COMMAND_STOP_POD,
COMMAND_REPLACE_POD,
COMMAND_EXEC,
COMMAND_KILL,
COMMAND_WRITEFILE,
COMMAND_READFILE,
COMMAND_SHUTDOWN,
Expand Down Expand Up @@ -560,6 +576,8 @@ func stateRunning(ctx *VmContext, ev VmEvent) {
ctx.reportSuccess("", nil)
case COMMAND_EXEC:
ctx.execCmd(ev.(*ExecCommand))
case COMMAND_KILL:
ctx.killCmd(ev.(*KillCommand))
case COMMAND_ATTACH:
ctx.attachCmd(ev.(*AttachCommand))
case COMMAND_NEWCONTAINER:
Expand Down
117 changes: 117 additions & 0 deletions kill.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package main

import (
"encoding/json"
"fmt"
"net"
"os"
"path"
"strconv"
"strings"
"syscall"

"github.com/codegangsta/cli"
"github.com/hyperhq/runv/hypervisor"
)

var signalMap = map[string]syscall.Signal{
"ABRT": syscall.SIGABRT,
"ALRM": syscall.SIGALRM,
"BUS": syscall.SIGBUS,
"CHLD": syscall.SIGCHLD,
"CLD": syscall.SIGCLD,
"CONT": syscall.SIGCONT,
"FPE": syscall.SIGFPE,
"HUP": syscall.SIGHUP,
"ILL": syscall.SIGILL,
"INT": syscall.SIGINT,
"IO": syscall.SIGIO,
"IOT": syscall.SIGIOT,
"KILL": syscall.SIGKILL,
"PIPE": syscall.SIGPIPE,
"POLL": syscall.SIGPOLL,
"PROF": syscall.SIGPROF,
"PWR": syscall.SIGPWR,
"QUIT": syscall.SIGQUIT,
"SEGV": syscall.SIGSEGV,
"STKFLT": syscall.SIGSTKFLT,
"STOP": syscall.SIGSTOP,
"SYS": syscall.SIGSYS,
"TERM": syscall.SIGTERM,
"TRAP": syscall.SIGTRAP,
"TSTP": syscall.SIGTSTP,
"TTIN": syscall.SIGTTIN,
"TTOU": syscall.SIGTTOU,
"UNUSED": syscall.SIGUNUSED,
"URG": syscall.SIGURG,
"USR1": syscall.SIGUSR1,
"USR2": syscall.SIGUSR2,
"VTALRM": syscall.SIGVTALRM,
"WINCH": syscall.SIGWINCH,
"XCPU": syscall.SIGXCPU,
"XFSZ": syscall.SIGXFSZ,
}

type killContainerCmd struct {
Name string
Root string
Signal syscall.Signal
}

func requestDaemonKillContainer(root, container string, signal syscall.Signal) error {
conn, err := net.Dial("unix", path.Join(root, container, "runv.sock"))
if err != nil {
return err
}

killCmd := &killContainerCmd{Name: container, Root: root, Signal: signal}
cmd, err := json.Marshal(killCmd)
if err != nil {
return err
}

m := &hypervisor.DecodedMessage{
Code: RUNV_KILLCONTAINER,
Message: []byte(cmd),
}

data := hypervisor.NewVmMessage(m)
conn.Write(data[:])

return nil
}

var killCommand = cli.Command{
Name: "kill",
Usage: "kill sends the specified signal (default: SIGTERM) to the container's init process",
Action: func(context *cli.Context) {
sigstr := context.Args().First()
if sigstr == "" {
sigstr = "SIGTERM"
}

signal, err := parseSignal(sigstr)
if err != nil {
fmt.Printf("kill container failed %v\n", err)
os.Exit(-1)
}

err = requestDaemonKillContainer(context.GlobalString("root"), context.GlobalString("id"), signal)
if err != nil {
fmt.Printf("kill container failed %v\n", err)
os.Exit(-1)
}
},
}

func parseSignal(rawSignal string) (syscall.Signal, error) {
s, err := strconv.Atoi(rawSignal)
if err == nil {
return syscall.Signal(s), nil
}
signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
if !ok {
return -1, fmt.Errorf("unknown signal %q", rawSignal)
}
return signal, nil
}
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func main() {
startCommand,
specCommand,
execCommand,
killCommand,
daemonCommand,
}
if err := app.Run(os.Args); err != nil {
Expand Down
11 changes: 11 additions & 0 deletions runv.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const (
RUNV_ACK
RUNV_EXECCMD
RUNV_WINSIZE
RUNV_KILLCONTAINER
)

const shortLen = 12
Expand Down Expand Up @@ -470,6 +471,16 @@ func HandleRunvRequest(context *nsContext, info *hypervisor.ContainerInfo, conn
//fmt.Printf("client exec winsize request %v\n", winSize)
context.vm.Tty(winSize.Tag, winSize.Height, winSize.Width)
}
case RUNV_KILLCONTAINER:
{
killCmd := &killContainerCmd{}
err = json.Unmarshal(msg.Message, killCmd)
if err != nil {
fmt.Printf("parse runv kill container command failed: %v\n", err)
return
}
context.vm.KillContainer(info.Id, killCmd.Signal)
}
default:
fmt.Printf("unknown cient request\n")
}
Expand Down

0 comments on commit fe8ee49

Please sign in to comment.