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}