github.com/AbhinandanKurakure/podman/v3@v3.4.10/test/e2e/libpod_suite_remote_test.go (about)

     1  // +build remote
     2  
     3  package integration
     4  
     5  import (
     6  	"bytes"
     7  	"errors"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"os"
    11  	"os/exec"
    12  	"path/filepath"
    13  	"strconv"
    14  	"strings"
    15  	"syscall"
    16  	"time"
    17  
    18  	"github.com/containers/podman/v3/pkg/rootless"
    19  	"github.com/onsi/ginkgo"
    20  )
    21  
    22  func IsRemote() bool {
    23  	return true
    24  }
    25  
    26  func SkipIfRemote(reason string) {
    27  	if len(reason) < 5 {
    28  		panic("SkipIfRemote must specify a reason to skip")
    29  	}
    30  	ginkgo.Skip("[remote]: " + reason)
    31  }
    32  
    33  // Podman is the exec call to podman on the filesystem
    34  func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration {
    35  	var remoteArgs = []string{"--remote", "--url", p.RemoteSocket}
    36  	remoteArgs = append(remoteArgs, args...)
    37  	podmanSession := p.PodmanBase(remoteArgs, false, false)
    38  	return &PodmanSessionIntegration{podmanSession}
    39  }
    40  
    41  // PodmanSystemdScope runs the podman command in a new systemd scope
    42  func (p *PodmanTestIntegration) PodmanSystemdScope(args []string) *PodmanSessionIntegration {
    43  	var remoteArgs = []string{"--remote", "--url", p.RemoteSocket}
    44  	remoteArgs = append(remoteArgs, args...)
    45  
    46  	wrapper := []string{"systemd-run", "--scope"}
    47  	if rootless.IsRootless() {
    48  		wrapper = []string{"systemd-run", "--scope", "--user"}
    49  	}
    50  
    51  	podmanSession := p.PodmanAsUserBase(remoteArgs, 0, 0, "", nil, false, false, wrapper, nil)
    52  	return &PodmanSessionIntegration{podmanSession}
    53  }
    54  
    55  // PodmanExtraFiles is the exec call to podman on the filesystem and passes down extra files
    56  func (p *PodmanTestIntegration) PodmanExtraFiles(args []string, extraFiles []*os.File) *PodmanSessionIntegration {
    57  	var remoteArgs = []string{"--remote", "--url", p.RemoteSocket}
    58  	remoteArgs = append(remoteArgs, args...)
    59  	podmanSession := p.PodmanAsUserBase(remoteArgs, 0, 0, "", nil, false, false, nil, extraFiles)
    60  	return &PodmanSessionIntegration{podmanSession}
    61  }
    62  
    63  func (p *PodmanTestIntegration) setDefaultRegistriesConfigEnv() {
    64  	defaultFile := filepath.Join(INTEGRATION_ROOT, "test/registries.conf")
    65  	os.Setenv("CONTAINERS_REGISTRIES_CONF", defaultFile)
    66  }
    67  
    68  func (p *PodmanTestIntegration) setRegistriesConfigEnv(b []byte) {
    69  	outfile := filepath.Join(p.TempDir, "registries.conf")
    70  	os.Setenv("CONTAINERS_REGISTRIES_CONF", outfile)
    71  	ioutil.WriteFile(outfile, b, 0644)
    72  }
    73  
    74  func resetRegistriesConfigEnv() {
    75  	os.Setenv("CONTAINERS_REGISTRIES_CONF", "")
    76  }
    77  func PodmanTestCreate(tempDir string) *PodmanTestIntegration {
    78  	pti := PodmanTestCreateUtil(tempDir, true)
    79  	pti.StartRemoteService()
    80  	return pti
    81  }
    82  
    83  func (p *PodmanTestIntegration) StartRemoteService() {
    84  	if os.Geteuid() == 0 {
    85  		os.MkdirAll("/run/podman", 0755)
    86  	}
    87  
    88  	args := []string{}
    89  	if _, found := os.LookupEnv("DEBUG_SERVICE"); found {
    90  		args = append(args, "--log-level", "debug")
    91  	}
    92  	remoteSocket := p.RemoteSocket
    93  	args = append(args, "system", "service", "--time", "0", remoteSocket)
    94  	podmanOptions := getRemoteOptions(p, args)
    95  	cacheOptions := []string{"--storage-opt",
    96  		fmt.Sprintf("%s.imagestore=%s", p.PodmanTest.ImageCacheFS, p.PodmanTest.ImageCacheDir)}
    97  	podmanOptions = append(cacheOptions, podmanOptions...)
    98  	command := exec.Command(p.PodmanBinary, podmanOptions...)
    99  	command.Stdout = os.Stdout
   100  	command.Stderr = os.Stderr
   101  	fmt.Printf("Running: %s %s\n", p.PodmanBinary, strings.Join(podmanOptions, " "))
   102  	command.Start()
   103  	command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
   104  	p.RemoteCommand = command
   105  	p.RemoteSession = command.Process
   106  	err := p.DelayForService()
   107  	p.RemoteStartErr = err
   108  }
   109  
   110  func (p *PodmanTestIntegration) StopRemoteService() {
   111  	var out bytes.Buffer
   112  	var pids []int
   113  	remoteSession := p.RemoteSession
   114  
   115  	if !rootless.IsRootless() {
   116  		if err := remoteSession.Kill(); err != nil {
   117  			fmt.Fprintf(os.Stderr, "error on remote stop-kill %q", err)
   118  		}
   119  		if _, err := remoteSession.Wait(); err != nil {
   120  			fmt.Fprintf(os.Stderr, "error on remote stop-wait %q", err)
   121  		}
   122  
   123  	} else {
   124  		parentPid := fmt.Sprintf("%d", p.RemoteSession.Pid)
   125  		pgrep := exec.Command("pgrep", "-P", parentPid)
   126  		fmt.Printf("running: pgrep %s\n", parentPid)
   127  		pgrep.Stdout = &out
   128  		err := pgrep.Run()
   129  		if err != nil {
   130  			fmt.Fprint(os.Stderr, "unable to find remote pid")
   131  		}
   132  
   133  		for _, s := range strings.Split(out.String(), "\n") {
   134  			if len(s) == 0 {
   135  				continue
   136  			}
   137  			p, err := strconv.Atoi(s)
   138  			if err != nil {
   139  				fmt.Fprintf(os.Stderr, "unable to convert %s to int", s)
   140  			}
   141  			if p != 0 {
   142  				pids = append(pids, p)
   143  			}
   144  		}
   145  
   146  		pids = append(pids, p.RemoteSession.Pid)
   147  		for _, pid := range pids {
   148  			syscall.Kill(pid, syscall.SIGKILL)
   149  		}
   150  	}
   151  	socket := strings.Split(p.RemoteSocket, ":")[1]
   152  	if err := os.Remove(socket); err != nil {
   153  		fmt.Println(err)
   154  	}
   155  }
   156  
   157  //MakeOptions assembles all the podman main options
   158  func getRemoteOptions(p *PodmanTestIntegration, args []string) []string {
   159  	podmanOptions := strings.Split(fmt.Sprintf("--root %s --runroot %s --runtime %s --conmon %s --cni-config-dir %s --cgroup-manager %s",
   160  		p.CrioRoot, p.RunRoot, p.OCIRuntime, p.ConmonBinary, p.CNIConfigDir, p.CgroupManager), " ")
   161  	if os.Getenv("HOOK_OPTION") != "" {
   162  		podmanOptions = append(podmanOptions, os.Getenv("HOOK_OPTION"))
   163  	}
   164  	podmanOptions = append(podmanOptions, strings.Split(p.StorageOptions, " ")...)
   165  	podmanOptions = append(podmanOptions, args...)
   166  	return podmanOptions
   167  }
   168  
   169  // SeedImages restores all the artifacts into the main store for remote tests
   170  func (p *PodmanTestIntegration) SeedImages() error {
   171  	return nil
   172  }
   173  
   174  // RestoreArtifact puts the cached image into our test store
   175  func (p *PodmanTestIntegration) RestoreArtifact(image string) error {
   176  	fmt.Printf("Restoring %s...\n", image)
   177  	dest := strings.Split(image, "/")
   178  	destName := fmt.Sprintf("/tmp/%s.tar", strings.Replace(strings.Join(strings.Split(dest[len(dest)-1], "/"), ""), ":", "-", -1))
   179  	args := []string{"load", "-q", "-i", destName}
   180  	podmanOptions := getRemoteOptions(p, args)
   181  	command := exec.Command(p.PodmanBinary, podmanOptions...)
   182  	fmt.Printf("Running: %s %s\n", p.PodmanBinary, strings.Join(podmanOptions, " "))
   183  	command.Start()
   184  	command.Wait()
   185  	return nil
   186  }
   187  
   188  func (p *PodmanTestIntegration) DelayForService() error {
   189  	for i := 0; i < 5; i++ {
   190  		session := p.Podman([]string{"info"})
   191  		session.WaitWithDefaultTimeout()
   192  		if session.ExitCode() == 0 {
   193  			return nil
   194  		} else if i == 4 {
   195  			break
   196  		}
   197  		time.Sleep(2 * time.Second)
   198  	}
   199  	return errors.New("Service not detected")
   200  }