github.com/criyle/go-sandbox@v0.10.3/container/host_cmd_linux.go (about)

     1  package container
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"syscall"
     7  	"time"
     8  
     9  	"github.com/criyle/go-sandbox/pkg/unixsocket"
    10  )
    11  
    12  // Ping send ping message to container, wait for 3 second before timeout
    13  func (c *container) Ping() error {
    14  	c.mu.Lock()
    15  	defer c.mu.Unlock()
    16  
    17  	// avoid infinite wait (max 3s)
    18  	const pingWait = 3 * time.Second
    19  	c.socket.SetDeadline(time.Now().Add(pingWait))
    20  	defer c.socket.SetDeadline(time.Time{})
    21  
    22  	// send ping
    23  	cmd := cmd{
    24  		Cmd: cmdPing,
    25  	}
    26  	if err := c.sendCmd(cmd, unixsocket.Msg{}); err != nil {
    27  		return fmt.Errorf("ping: %v", err)
    28  	}
    29  	// receive no error
    30  	return c.recvAckReply("ping")
    31  }
    32  
    33  // conf send configuration to container (used by builder only)
    34  func (c *container) conf(conf *containerConfig) error {
    35  	c.mu.Lock()
    36  	defer c.mu.Unlock()
    37  
    38  	cmd := cmd{
    39  		Cmd:     cmdConf,
    40  		ConfCmd: &confCmd{Conf: *conf},
    41  	}
    42  	if err := c.sendCmd(cmd, unixsocket.Msg{}); err != nil {
    43  		return fmt.Errorf("conf: %v", err)
    44  	}
    45  	return c.recvAckReply("conf")
    46  }
    47  
    48  // Open open files in container
    49  func (c *container) Open(p []OpenCmd) ([]*os.File, error) {
    50  	c.mu.Lock()
    51  	defer c.mu.Unlock()
    52  
    53  	syscall.ForkLock.RLock()
    54  	defer syscall.ForkLock.RUnlock()
    55  
    56  	// send copyin
    57  	cmd := cmd{
    58  		Cmd:     cmdOpen,
    59  		OpenCmd: p,
    60  	}
    61  	if err := c.sendCmd(cmd, unixsocket.Msg{}); err != nil {
    62  		return nil, fmt.Errorf("open: %v", err)
    63  	}
    64  	reply, msg, err := c.recvReply()
    65  	if err != nil {
    66  		return nil, fmt.Errorf("open: %v", err)
    67  	}
    68  	if reply.Error != nil {
    69  		return nil, fmt.Errorf("open: %v", reply.Error)
    70  	}
    71  	if len(msg.Fds) != len(p) {
    72  		closeFds(msg.Fds)
    73  		return nil, fmt.Errorf("open: unexpected number of fd %v / %v", len(msg.Fds), len(p))
    74  	}
    75  
    76  	ret := make([]*os.File, 0, len(p))
    77  	for i, fd := range msg.Fds {
    78  		syscall.CloseOnExec(fd)
    79  		f := os.NewFile(uintptr(fd), p[i].Path)
    80  		if f == nil {
    81  			closeFds(msg.Fds)
    82  			return nil, fmt.Errorf("open: failed NewFile %v", fd)
    83  		}
    84  		ret = append(ret, f)
    85  	}
    86  	return ret, nil
    87  }
    88  
    89  // Delete remove file from container
    90  func (c *container) Delete(p string) error {
    91  	c.mu.Lock()
    92  	defer c.mu.Unlock()
    93  
    94  	cmd := cmd{
    95  		Cmd:       cmdDelete,
    96  		DeleteCmd: &deleteCmd{Path: p},
    97  	}
    98  	if err := c.sendCmd(cmd, unixsocket.Msg{}); err != nil {
    99  		return fmt.Errorf("delete: %v", err)
   100  	}
   101  	return c.recvAckReply("delete")
   102  }
   103  
   104  // Reset remove all from /tmp and /w
   105  func (c *container) Reset() error {
   106  	c.mu.Lock()
   107  	defer c.mu.Unlock()
   108  
   109  	cmd := cmd{
   110  		Cmd: cmdReset,
   111  	}
   112  	if err := c.sendCmd(cmd, unixsocket.Msg{}); err != nil {
   113  		return fmt.Errorf("reset: %v", err)
   114  	}
   115  	return c.recvAckReply("reset")
   116  }