1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
18 "git.arvados.org/arvados.git/sdk/go/arvados"
22 // Run a postgresql server in a private data directory. Set up a db
23 // user, database, and TCP listener that match the supervisor's
24 // configured database connection info.
25 type runPostgreSQL struct{}
27 func (runPostgreSQL) String() string {
31 func (runPostgreSQL) Run(ctx context.Context, fail func(error), super *Supervisor) error {
32 err := super.wait(ctx, createCertificates{})
37 buf := bytes.NewBuffer(nil)
38 err = super.RunProgram(ctx, super.tempdir, buf, nil, "pg_config", "--bindir")
42 bindir := strings.TrimSpace(buf.String())
44 datadir := filepath.Join(super.tempdir, "pgdata")
45 err = os.Mkdir(datadir, 0755)
49 err = super.RunProgram(ctx, super.tempdir, nil, nil, filepath.Join(bindir, "initdb"), "-D", datadir)
54 err = super.RunProgram(ctx, super.tempdir, nil, nil, "cp", "server.crt", "server.key", datadir)
59 port := super.cluster.PostgreSQL.Connection["port"]
61 super.waitShutdown.Add(1)
63 defer super.waitShutdown.Done()
64 fail(super.RunProgram(ctx, super.tempdir, nil, nil, filepath.Join(bindir, "postgres"),
66 "-D", datadir, // data dir
67 "-k", datadir, // socket dir
68 "-p", super.cluster.PostgreSQL.Connection["port"],
76 if exec.CommandContext(ctx, "pg_isready", "--timeout=10", "--host="+super.cluster.PostgreSQL.Connection["host"], "--port="+port).Run() == nil {
79 time.Sleep(time.Second / 2)
81 db, err := sql.Open("postgres", arvados.PostgreSQLConnection{
87 return fmt.Errorf("db open failed: %s", err)
90 conn, err := db.Conn(ctx)
92 return fmt.Errorf("db conn failed: %s", err)
95 _, err = conn.ExecContext(ctx, `CREATE USER `+pq.QuoteIdentifier(super.cluster.PostgreSQL.Connection["user"])+` WITH SUPERUSER ENCRYPTED PASSWORD `+pq.QuoteLiteral(super.cluster.PostgreSQL.Connection["password"]))
97 return fmt.Errorf("createuser failed: %s", err)
99 _, err = conn.ExecContext(ctx, `CREATE DATABASE `+pq.QuoteIdentifier(super.cluster.PostgreSQL.Connection["dbname"]))
101 return fmt.Errorf("createdb failed: %s", err)