forked from MozillaFoundation/foundation.mozilla.org
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcopy-db.js
More file actions
127 lines (105 loc) · 3.56 KB
/
copy-db.js
File metadata and controls
127 lines (105 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const fs = require("fs");
const { execSync } = require(`child_process`);
const keepDatabase = process.argv.includes(`--keep`);
const silent = { stdio: [`ignore`, `ignore`, `ignore`] };
const PROD_APP = `foundation-mozilla-org`;
const STAGE_APP = `foundation-mofostaging-net`;
const APP = process.argv.includes(`--prod`) ? PROD_APP : STAGE_APP;
if (APP === STAGE_APP) {
console.log(
`Running db copy for staging, run with --prod to run for production`
);
}
const HEROKU_OUTPUT = run(`heroku config:get DATABASE_URL -a ${APP}`);
const HEROKU_TEXT = HEROKU_OUTPUT.toString().replaceAll(`\n`, ` `);
const URL_START = HEROKU_TEXT.indexOf(`postgres://`);
const DATABASE_URL = HEROKU_TEXT.substring(URL_START).trim();
const ROLE = DATABASE_URL.match(/postgres:\/\/([^:]+):/)[1];
const DUMP_FILE = `${ROLE}.db.archive`;
const DB_FLAGS = `-hpostgres -Ufoundation`;
/**
* Exec a command and return its output as plain string
*/
function run(cmd, ignoreThrows = false, opts = {}) {
try {
return execSync(cmd, opts).toString();
} catch (e) {
if (ignoreThrows) return e.toString();
process.exit(1);
}
}
/**
* Run a command in the postgres docker container
*/
function postgres(cmd, ignoreThrows = false) {
cmd = `docker exec ${IMAGE_NAMES.POSTGRES} ${cmd}`;
return run(cmd, ignoreThrows);
}
function getContainerNames() {
return run(`docker ps`)
.split(`\n`)
.map((v) => v.match(/\s(\S+)$/g))
.filter(Boolean)
.map((v) => v[0].trim())
.reduce((a, v) => {
if (!v) return a;
if (v.includes(`backend`)) a.BACKEND = v;
if (v.includes(`postgres`)) a.POSTGRES = v;
return a;
}, {});
}
function stopContainers() {
const IMAGE_NAMES = getContainerNames();
const backend = IMAGE_NAMES.BACKEND;
if (backend) {
console.log(`Stopping ${backend}`);
run(`docker stop ${backend}`, true, silent);
}
const postgres = IMAGE_NAMES.POSTGRES;
if (postgres) {
console.log(`Stopping ${postgres}`);
run(`docker stop ${postgres}`, true, silent);
}
}
// ======================== //
// Our script starts here //
// ======================== //
console.log(`Making sure no docker containers are running...`);
stopContainers();
console.log(`Starting postgres docker image...`);
run(`docker-compose up -d postgres`, true, silent);
console.log(`Starting backend docker image...`);
run(`docker-compose up -d backend`, true, silent);
console.log(`Getting running image names...`);
const IMAGE_NAMES = getContainerNames();
console.log(`Downloading ${APP} database (this may take a while)...`);
if (!fs.existsSync(DUMP_FILE)) {
postgres(`pg_dump -F c ${DATABASE_URL} > ${DUMP_FILE}`);
}
console.log(`Resetting db...`);
postgres(`dropdb ${DB_FLAGS} --if-exists wagtail --force`);
postgres(`createdb ${DB_FLAGS} wagtail`);
console.log(`Building user roles...`);
[ROLE, `datastudio`, `datagrip-cade`].forEach((role) =>
postgres(`createuser ${DB_FLAGS} -s ${role}`, true)
);
console.log(`Importing snapshot...`);
run(`docker cp ${DUMP_FILE} ${IMAGE_NAMES.POSTGRES}:/`);
postgres(`pg_restore ${DB_FLAGS} -dwagtail ${DUMP_FILE}`);
console.log(`Creating admin:admin superuser account...`);
run(
[
`docker exec ${IMAGE_NAMES.BACKEND}`,
`./dockerpythonvenv/bin/python network-api/manage.py shell -c`,
`"from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', 'admin')"`,
].join(` `),
true,
silent
);
console.log(`Stopping docker images...`);
run(`docker-compose down`, true, silent);
if (!keepDatabase) {
console.log(`Running cleanup`);
fs.unlinkSync(DUMP_FILE);
}
console.log(`All done.`);