87 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// +build !windows
 | 
						|
 | 
						|
package proc
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"io"
 | 
						|
	"os"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/containerd/containerd/errdefs"
 | 
						|
	shimapi "github.com/containerd/containerd/linux/shim/v1"
 | 
						|
	runc "github.com/containerd/go-runc"
 | 
						|
	"github.com/pkg/errors"
 | 
						|
	"golang.org/x/sys/unix"
 | 
						|
)
 | 
						|
 | 
						|
// TODO(mlaventure): move to runc package?
 | 
						|
func getLastRuntimeError(r *runc.Runc) (string, error) {
 | 
						|
	if r.Log == "" {
 | 
						|
		return "", nil
 | 
						|
	}
 | 
						|
 | 
						|
	f, err := os.OpenFile(r.Log, os.O_RDONLY, 0400)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
 | 
						|
	var (
 | 
						|
		errMsg string
 | 
						|
		log    struct {
 | 
						|
			Level string
 | 
						|
			Msg   string
 | 
						|
			Time  time.Time
 | 
						|
		}
 | 
						|
	)
 | 
						|
 | 
						|
	dec := json.NewDecoder(f)
 | 
						|
	for err = nil; err == nil; {
 | 
						|
		if err = dec.Decode(&log); err != nil && err != io.EOF {
 | 
						|
			return "", err
 | 
						|
		}
 | 
						|
		if log.Level == "error" {
 | 
						|
			errMsg = strings.TrimSpace(log.Msg)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return errMsg, nil
 | 
						|
}
 | 
						|
 | 
						|
// criuError returns only the first line of the error message from criu
 | 
						|
// it tries to add an invalid dump log location when returning the message
 | 
						|
func criuError(err error) string {
 | 
						|
	parts := strings.Split(err.Error(), "\n")
 | 
						|
	return parts[0]
 | 
						|
}
 | 
						|
 | 
						|
func copyFile(to, from string) error {
 | 
						|
	ff, err := os.Open(from)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	defer ff.Close()
 | 
						|
	tt, err := os.Create(to)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	defer tt.Close()
 | 
						|
	_, err = io.Copy(tt, ff)
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
func checkKillError(err error) error {
 | 
						|
	if err == nil {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	if strings.Contains(err.Error(), "os: process already finished") || err == unix.ESRCH {
 | 
						|
		return errors.Wrapf(errdefs.ErrNotFound, "process already finished")
 | 
						|
	}
 | 
						|
	return errors.Wrapf(err, "unknown error after kill")
 | 
						|
}
 | 
						|
 | 
						|
func hasNoIO(r *shimapi.CreateTaskRequest) bool {
 | 
						|
	return r.Stdin == "" && r.Stdout == "" && r.Stderr == ""
 | 
						|
}
 |