Exemple #1
0
func runvRequest(root, name string, code uint32, msg interface{}) (net.Conn, error) {
	conn, err := utils.UnixSocketConnect(filepath.Join(root, name, "runv.sock"))
	if err != nil {
		return nil, err
	}

	cmd, err := json.Marshal(msg)
	if err != nil {
		conn.Close()
		return nil, err
	}

	m := &hypervisor.DecodedMessage{
		Code:    code,
		Message: cmd,
	}

	data := hypervisor.NewVmMessage(m)
	w, err := conn.Write(data[:])
	if w != len(data) {
		err = fmt.Errorf("Not full write") // TODO
	}
	if err != nil {
		conn.Close()
		return nil, err
	}

	return conn, nil
}
Exemple #2
0
func runvAllocAndRespondTag(conn net.Conn) (tag string, err error) {
	tag = pod.RandStr(8, "alphanum")
	m := &hypervisor.DecodedMessage{
		Code:    RUNV_ACK,
		Message: []byte(tag),
	}
	data := hypervisor.NewVmMessage(m)
	conn.Write(data)

	return tag, nil
}
Exemple #3
0
func HandleRunvRequest(context *nsContext, info *hypervisor.ContainerInfo, conn net.Conn) {
	defer context.wg.Done()
	defer conn.Close()

	msg, err := hypervisor.ReadVmMessage(conn.(*net.UnixConn))
	if err != nil {
		fmt.Printf("read runv client data failed: %v\n", err)
		return
	}

	switch msg.Code {
	case RUNV_INITCONTAINER:
		{
			initCmd := &initContainerCmd{}
			err = json.Unmarshal(msg.Message, initCmd)
			if err != nil {
				fmt.Printf("parse runv init container command failed: %v\n", err)
				return
			}
			startVContainer(context, initCmd.Root, initCmd.Name)
		}
	case RUNV_EXECCMD:
		{
			tag, _ := runvAllocAndRespondTag(conn)

			fmt.Printf("client exec cmd request %s\n", msg.Message[:])
			tty := &hypervisor.TtyIO{
				ClientTag: tag,
				Stdin:     conn,
				Stdout:    conn,
				Callback:  make(chan *types.VmResponse, 1),
			}

			context.Lock()
			context.ttyList[tag] = tty
			context.Unlock()
			err = context.vm.Exec(tty, info.Id, string(msg.Message[:]))
			if err != nil {
				fmt.Printf("read runv client data failed: %v\n", err)
			}
		}
	case RUNV_EXITSTATUS:
		{
			var code uint8 = 255

			tagCmd := &ttyTagCmd{}
			err = json.Unmarshal(msg.Message, &tagCmd)
			if err != nil {
				fmt.Printf("parse exit status failed: %v\n", err)
				return
			}

			fmt.Printf("client get exit status: tag %v\n", tagCmd)

			context.Lock()
			if tty, ok := context.ttyList[tagCmd.Tag]; ok {
				code = uint8(tty.ExitCode)
				delete(context.ttyList, tagCmd.Tag)
			}
			context.Unlock()

			m := &hypervisor.DecodedMessage{
				Code:    RUNV_EXITSTATUS,
				Message: []byte{code},
			}

			data := hypervisor.NewVmMessage(m)
			conn.Write(data)
			/* Get exit code of Container, it's time to let container go */
			if tagCmd.Container != "" {
				cleanupVSocket(context, tagCmd.Root, tagCmd.Container)
			}
		}
	case RUNV_WINSIZE:
		{
			var winSize ttyWinSize
			json.Unmarshal(msg.Message, &winSize)
			//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")
	}
}