001package io.ebean.docker.commands;
002
003import io.ebean.docker.commands.process.ProcessHandler;
004import io.ebean.docker.container.Container;
005
006import java.util.ArrayList;
007import java.util.List;
008import java.util.Properties;
009
010/**
011 * Commands for controlling a cockroachDB docker container.
012 */
013public class CockroachContainer extends BaseDbContainer implements Container {
014
015  /**
016   * Create Postgres container with configuration from properties.
017   */
018  public static CockroachContainer create(String version, Properties properties) {
019    return new CockroachContainer(new CockroachConfig(version, properties));
020  }
021
022  /**
023   * Create with configuration.
024   */
025  public CockroachContainer(CockroachConfig config) {
026    super(config);
027  }
028
029  @Override
030  protected boolean isDatabaseAdminReady() {
031    return execute("database_name", showDatabases());
032  }
033
034  @Override
035  protected boolean isFastStartDatabaseExists() {
036    return databaseExists();
037  }
038
039  @Override
040  protected void createDbPreConnectivity() {
041    if (!databaseExists()) {
042      createDatabase();
043    }
044  }
045
046  @Override
047  protected void dropCreateDbPreConnectivity() {
048    dropDatabaseIfExists();
049    createDatabase();
050  }
051
052  /**
053   * Return true if the database exists.
054   */
055  private boolean databaseExists() {
056    final List<String> outLines = ProcessHandler.process(showDatabases()).getOutLines();
057    return stdoutContains(outLines, dbConfig.getDbName());
058  }
059
060  protected boolean createDatabase() {
061    if (execute("CREATE DATABASE", procCreateDb(), "Failed to create database with owner")) {
062      //runDbSqlFile(dbName, dbUser, initSqlFile);
063      //runDbSqlFile(dbName, dbUser, seedSqlFile);
064      return true;
065    }
066    return false;
067  }
068
069  protected boolean dropDatabaseIfExists() {
070    ProcessBuilder pb = sqlProcess("drop database if exists " + dbConfig.getDbName());
071    return execute("DROP DATABASE", pb, "Failed to drop database");
072  }
073
074  /**
075   * Wait for the 'database system is ready'
076   */
077  public boolean isDatabaseReady() {
078    try {
079      Thread.sleep(200);
080    } catch (InterruptedException e) {
081      Thread.currentThread().interrupt();
082    }
083    return true;
084  }
085
086  private ProcessBuilder procCreateDb() {
087    return sqlProcess("create database " + dbConfig.getDbName());
088  }
089
090  private ProcessBuilder showDatabases() {
091    return sqlProcess("show databases");
092  }
093
094  private ProcessBuilder sqlProcess(String sql) {
095    List<String> args = new ArrayList<>();
096    args.add(config.docker);
097    args.add("exec");
098    args.add("-i");
099    args.add(config.containerName());
100    args.add("./cockroach");
101    args.add("sql");
102    args.add("--insecure");
103    args.add("-e");
104    args.add(sql);
105    return createProcessBuilder(args);
106  }
107
108  @Override
109  protected ProcessBuilder runProcess() {
110
111//    docker run -d \
112//    --name=roach1 \
113//    --hostname=roach1 \
114//    --net=roachnet \
115//    -p 26257:26257 -p 8080:8080  \
116//    -v "${PWD}/cockroach-data/roach1:/cockroach/cockroach-data"  \
117//    cockroachdb/cockroach:v19.1.4 start --insecure
118//
119    List<String> args = new ArrayList<>();
120    args.add(config.docker);
121    args.add("run");
122    args.add("-d");
123    args.add("--name");
124    args.add(config.containerName());
125    args.add("--hostname=roach1");
126//    args.add("--net=roachnet");
127//    args.add("--listen-addr=localhost");
128    args.add("-p");
129    args.add(config.getPort() + ":" + config.getInternalPort());
130    args.add("-p");
131    args.add(config.getAdminPort() + ":" + config.getAdminInternalPort());
132
133    args.add(config.getImage());
134    args.add("start");
135    args.add("--insecure");
136
137    return createProcessBuilder(args);
138  }
139
140}