github.com/quay/claircore@v1.5.28/test/integration/github_actions.go (about)

     1  package integration
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"os/exec"
     9  	"path/filepath"
    10  	"sort"
    11  	"testing"
    12  
    13  	"github.com/jackc/pgx/v4/pgxpool"
    14  )
    15  
    16  func startGithubActions(t testing.TB) func() {
    17  	const config string = `# Installed by claircore's test harness.
    18  fsync = off
    19  `
    20  	const debugConfig = `session_preload_libraries = 'auto_explain'
    21  auto_explain.log_min_duration = 0
    22  auto_explain.log_analyze = true
    23  auto_explain.log_buffers = true
    24  auto_explain.log_wal = true
    25  `
    26  	// GitHub Actions has Postgres installed, so we can just run some commands
    27  	// to set it up:
    28  	return func() {
    29  		// On success, this function leaves [pkgDB] unset, so that the test
    30  		// binary's teardown logic leaves it running as if it's an external
    31  		// database. Which it is, just happening to be one that some test or
    32  		// previous shell command started.
    33  		defer func() {
    34  			if t.Failed() {
    35  				return
    36  			}
    37  			// Just fill out the config and it's all good to go.
    38  			cfg, err := pgxpool.ParseConfig(`host=/var/run/postgresql user=postgres database=postgres sslmode=disable`)
    39  			if err != nil {
    40  				t.Fatal(err)
    41  			}
    42  			pkgConfig = cfg
    43  		}()
    44  		// See if a previous test binary already enabled the service:
    45  		cmd := exec.Command("sudo", "systemctl", "--quiet", "is-active", "postgresql.service")
    46  		// BUG(hank) If some other process starts "postgresql.service", it need
    47  		// to ensure that local passwordless authentication is configured. If
    48  		// processes after a test using this package needs any other
    49  		// authentication setup, be aware that this package overwrites the
    50  		// default "pg_hba.conf" with a minimal, local-only configuration.
    51  		if err := cmd.Run(); err == nil {
    52  			// Looking for exit 0 to indicate we don't need to do anything.
    53  			return
    54  		}
    55  
    56  		// Figure out the destination path.
    57  		ms, _ := filepath.Glob(`/etc/postgresql/*/main/conf.d`)
    58  		sort.Strings(ms)
    59  		confd := ms[0]
    60  		// TODO(hank) This lock is too broad, it covers the entire test when it
    61  		// really only needs to cover this function.
    62  		if !lockDir(t, confd) {
    63  			// If this process couldn't get an exclusive lock, then another
    64  			// process configured everything and this one should be able to just
    65  			// return here.
    66  			return
    67  		}
    68  
    69  		// Lay down the config snippet into a temporary directory.
    70  		f, err := os.Create(filepath.Join(t.TempDir(), "clair.conf"))
    71  		if err != nil {
    72  			t.Fatal(err)
    73  		}
    74  		defer f.Close()
    75  		if _, err := io.WriteString(f, config); err != nil {
    76  			t.Fatal(err)
    77  		}
    78  		if testing.Verbose() {
    79  			if _, err := io.WriteString(f, debugConfig); err != nil {
    80  				t.Fatal(err)
    81  			}
    82  		}
    83  		if exp, ok := os.LookupEnv("PGEXPLAIN_FORMAT"); ok {
    84  			fmt.Fprintf(f, `auto_explain.log_format = %q\n`, exp)
    85  		}
    86  		if err := f.Sync(); err != nil {
    87  			t.Fatal(err)
    88  		}
    89  
    90  		// Use sudo+install because that's just a much easier way to put a file
    91  		// in a specific place with specific permissions.
    92  		var buf bytes.Buffer
    93  		cmd = exec.Command("sudo", "install", "-m", "0644", "-o", "postgres", f.Name(), confd)
    94  		cmd.Stdout = &buf
    95  		cmd.Stderr = &buf
    96  		if err := cmd.Run(); err != nil {
    97  			t.Logf("running %+v: %v", cmd.Args, err)
    98  			t.Logf("output:\n%s", buf.String())
    99  			t.FailNow()
   100  		}
   101  		buf.Reset()
   102  		// Really hose up the database security model:
   103  		cmd = exec.Command("sudo", "sh", "-c", "echo local all all trust >"+filepath.Join(filepath.Dir(confd), "pg_hba.conf"))
   104  		cmd.Stdout = &buf
   105  		cmd.Stderr = &buf
   106  		if err := cmd.Run(); err != nil {
   107  			t.Logf("running %+v: %v", cmd.Args, err)
   108  			t.Logf("output:\n%s", buf.String())
   109  			t.FailNow()
   110  		}
   111  		buf.Reset()
   112  		// Start the database engine.
   113  		cmd = exec.Command("sudo", "systemctl", "start", "postgresql.service")
   114  		cmd.Stdout = &buf
   115  		cmd.Stderr = &buf
   116  		if err := cmd.Run(); err != nil {
   117  			t.Logf("running %+v: %v", cmd.Args, err)
   118  			t.Logf("output:\n%s", buf.String())
   119  			t.FailNow()
   120  		}
   121  	}
   122  }