mirror of
				https://github.com/containers/podman.git
				synced 2025-11-04 08:56:05 +08:00 
			
		
		
		
	Remove ERROR: Error stutter from logrus messages also. [ NO TESTS NEEDED] This is just code cleanup. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
		
			
				
	
	
		
			71 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Package exec provides utilities for executing Open Container Initiative runtime hooks.
 | 
						|
package exec
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	osexec "os/exec"
 | 
						|
	"time"
 | 
						|
 | 
						|
	rspec "github.com/opencontainers/runtime-spec/specs-go"
 | 
						|
	"github.com/pkg/errors"
 | 
						|
	"github.com/sirupsen/logrus"
 | 
						|
)
 | 
						|
 | 
						|
// DefaultPostKillTimeout is the recommended default post-kill timeout.
 | 
						|
const DefaultPostKillTimeout = time.Duration(10) * time.Second
 | 
						|
 | 
						|
// Run executes the hook and waits for it to complete or for the
 | 
						|
// context or hook-specified timeout to expire.
 | 
						|
func Run(ctx context.Context, hook *rspec.Hook, state []byte, stdout io.Writer, stderr io.Writer, postKillTimeout time.Duration) (hookErr, err error) {
 | 
						|
	cmd := osexec.Cmd{
 | 
						|
		Path:   hook.Path,
 | 
						|
		Args:   hook.Args,
 | 
						|
		Env:    hook.Env,
 | 
						|
		Stdin:  bytes.NewReader(state),
 | 
						|
		Stdout: stdout,
 | 
						|
		Stderr: stderr,
 | 
						|
	}
 | 
						|
	if cmd.Env == nil {
 | 
						|
		cmd.Env = []string{}
 | 
						|
	}
 | 
						|
 | 
						|
	if hook.Timeout != nil {
 | 
						|
		var cancel context.CancelFunc
 | 
						|
		ctx, cancel = context.WithTimeout(ctx, time.Duration(*hook.Timeout)*time.Second)
 | 
						|
		defer cancel()
 | 
						|
	}
 | 
						|
 | 
						|
	err = cmd.Start()
 | 
						|
	if err != nil {
 | 
						|
		return err, err
 | 
						|
	}
 | 
						|
	exit := make(chan error, 1)
 | 
						|
	go func() {
 | 
						|
		err := cmd.Wait()
 | 
						|
		if err != nil {
 | 
						|
			err = errors.Wrapf(err, "executing %v", cmd.Args)
 | 
						|
		}
 | 
						|
		exit <- err
 | 
						|
	}()
 | 
						|
 | 
						|
	select {
 | 
						|
	case err = <-exit:
 | 
						|
		return err, err
 | 
						|
	case <-ctx.Done():
 | 
						|
		if err := cmd.Process.Kill(); err != nil {
 | 
						|
			logrus.Errorf("Failed to kill pid %v", cmd.Process)
 | 
						|
		}
 | 
						|
		timer := time.NewTimer(postKillTimeout)
 | 
						|
		defer timer.Stop()
 | 
						|
		select {
 | 
						|
		case <-timer.C:
 | 
						|
			err = fmt.Errorf("failed to reap process within %s of the kill signal", postKillTimeout)
 | 
						|
		case err = <-exit:
 | 
						|
		}
 | 
						|
		return err, ctx.Err()
 | 
						|
	}
 | 
						|
}
 |