@verdnatura/myt 1.8.6 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -52
- package/assets/myt.default.yml +7 -0
- package/assets/structure.sql +1 -1
- package/{server/Dockerfile.client → docker/client/Dockerfile} +3 -3
- package/docker/server/Dockerfile +37 -0
- package/docker/server/Dockerfile.base +6 -0
- package/docker/server/Dockerfile.myt +35 -0
- package/docker/server/docker-init.sh +36 -0
- package/{server → docker/server}/docker-start.sh +1 -1
- package/lib/command.js +14 -6
- package/lib/docker.js +60 -34
- package/lib/dumper.js +11 -9
- package/lib/exporter-engine.js +4 -4
- package/lib/server.js +2 -8
- package/myt-apply.js +203 -0
- package/myt-build.js +283 -0
- package/myt-clean.js +15 -11
- package/myt-create.js +19 -11
- package/myt-dump.js +41 -36
- package/myt-fixtures.js +6 -6
- package/myt-init.js +5 -3
- package/myt-pull.js +12 -11
- package/myt-push.js +99 -96
- package/myt-run.js +28 -144
- package/myt-start.js +4 -4
- package/myt-version.js +13 -13
- package/myt.js +285 -149
- package/package.json +4 -3
- package/prebuilts/README.md +15 -0
- package/prebuilts/nodegit-v0.28.0-alpha.36-node-v127-linux-x64.tar.gz +0 -0
- package/template/.dockerignore +5 -0
- package/template/myt.config.yml +1 -4
- package/template/package.json +1 -1
- package/template/realms/.keep +0 -0
- package/template/remotes/docker.ini +1 -1
- package/template/remotes/local.ini +1 -1
- package/template/remotes/socket.ini +3 -0
- package/template/structure/.dump/structure.sql +32 -0
- package/server/Dockerfile.base +0 -1
- package/server/Dockerfile.dump +0 -16
- package/server/Dockerfile.server +0 -16
- package/server/docker-import.sh +0 -10
- package/server/docker-init.sh +0 -24
- /package/{server → docker/client}/docker-dump.sh +0 -0
- /package/{server → docker/client}/docker-fixtures.sh +0 -0
- /package/{server → docker/server}/docker.cnf +0 -0
- /package/template/{dump/Dockerfile.base → docker/Dockerfile} +0 -0
- /package/template/{dump/fixtures.after.sql → fixtures/after.sql} +0 -0
- /package/template/{dump/fixtures.before.sql → fixtures/before.sql} +0 -0
- /package/template/{dump/dump.after.sql → structure/after.sql} +0 -0
- /package/template/{dump/dump.before.sql → structure/before.sql} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Myt - MySQL version control
|
|
1
|
+
# Myt - MariaDB and MySQL version control
|
|
2
2
|
|
|
3
|
-
Utilities to ease the maintenance of
|
|
3
|
+
Utilities to ease the maintenance of MariaDB or MySQL database versioning using
|
|
4
4
|
a Git repository.
|
|
5
5
|
|
|
6
6
|
This project is just to bring an idea to life and is still in an early stage of
|
|
@@ -9,7 +9,7 @@ development, so any help is welcomed! Feel free to contribute.
|
|
|
9
9
|
## Requirements
|
|
10
10
|
|
|
11
11
|
* Git
|
|
12
|
-
* Docker (Optional, used to manage local server)
|
|
12
|
+
* Docker >= 23 with BuildKit (Optional, used to manage local server)
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
@@ -57,11 +57,36 @@ Local server management commands:
|
|
|
57
57
|
|
|
58
58
|
* **dump**: Export database structure and fixtures.
|
|
59
59
|
* **fixtures**: Export local database fixtures.
|
|
60
|
+
* **build**: Builds local database server image.
|
|
61
|
+
* **apply**: Applies structure, fixtures and changes to database.
|
|
60
62
|
* **run**: Build and start local database server container.
|
|
61
63
|
* **start**: Start local database server container.
|
|
62
64
|
|
|
63
65
|
Each command can have its own specific commandline options.
|
|
64
66
|
|
|
67
|
+
### Usage as library
|
|
68
|
+
|
|
69
|
+
It is also possible to use myt as a JavaScript library, not only from the
|
|
70
|
+
command line. Below is a reference example.
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
const Myt = require('@verdnatura/myt/myt');
|
|
74
|
+
const Run = require('@verdnatura/myt/myt-run');
|
|
75
|
+
|
|
76
|
+
async function main() {
|
|
77
|
+
const myt = new Myt();
|
|
78
|
+
await myt.init({
|
|
79
|
+
workspace: path.join(__dirname, '..')
|
|
80
|
+
});
|
|
81
|
+
const server = await myt.run(Run, {
|
|
82
|
+
random: true,
|
|
83
|
+
persist: process.platform != 'linux'
|
|
84
|
+
});
|
|
85
|
+
console.log(server.dbConfig);
|
|
86
|
+
await myt.deinit();
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
65
90
|
## Basic information
|
|
66
91
|
|
|
67
92
|
First of all you have to initialize the workspace.
|
|
@@ -143,38 +168,6 @@ Don't place your PL/SQL objects here, use the routines folder!
|
|
|
143
168
|
`- 00-sameNumbers.sql
|
|
144
169
|
```
|
|
145
170
|
|
|
146
|
-
### Environment-Specific Versioning with Realms
|
|
147
|
-
|
|
148
|
-
#### Overview
|
|
149
|
-
|
|
150
|
-
We have introduced a new feature that allows users to apply version-specific changes based on their configured environment, or "realm". This ensures that certain changes are only applied when the user is operating within a specific realm, providing an additional layer of customization and control.
|
|
151
|
-
|
|
152
|
-
#### Configuration
|
|
153
|
-
|
|
154
|
-
To make use of this feature, you need to configure your realm in the `versionConfig` table. Set your realm by inserting or updating a record in this table. The `realm` field should contain the identifier of your environment.
|
|
155
|
-
|
|
156
|
-
#### File Naming Convention
|
|
157
|
-
|
|
158
|
-
To designate a file as realm-specific, include a `.your_realm.` segment before the file extension. For example, if your realm is set to 'ab', the file should be named like this: `filename.ab.sql`.
|
|
159
|
-
|
|
160
|
-
#### How It Works
|
|
161
|
-
|
|
162
|
-
1. **Set your Realm**: Configure your realm in the `versionConfig` table.
|
|
163
|
-
|
|
164
|
-
2. **Add Files**: Place your realm-specific files in the `versions` folder. Make sure to follow the naming convention.
|
|
165
|
-
|
|
166
|
-
3. **Version Order**: Files are applied in the existing version order. In addition to that, the realm is validated.
|
|
167
|
-
|
|
168
|
-
4. **Apply Changes**: Run the usual versioning commands. The realm-specific files will only be applied if your configured realm matches the realm in the file name.
|
|
169
|
-
|
|
170
|
-
#### Important Notes
|
|
171
|
-
|
|
172
|
-
- If no realm is configured, realm-specific files will be ignored.
|
|
173
|
-
|
|
174
|
-
- If you have a realm configured but the realm-specific files belong to a different realm, those files will also be ignored.
|
|
175
|
-
|
|
176
|
-
This feature allows for greater flexibility when working in different environments, making it easier to manage realm-specific changes in a shared repository.
|
|
177
|
-
|
|
178
171
|
### Local server
|
|
179
172
|
|
|
180
173
|
The local server is created as a MariaDB Docker container using the base dump
|
|
@@ -185,29 +178,46 @@ routines.
|
|
|
185
178
|
|
|
186
179
|
You can create your local fixture and structure files.
|
|
187
180
|
|
|
188
|
-
* *
|
|
189
|
-
* *
|
|
190
|
-
* *
|
|
191
|
-
* *
|
|
192
|
-
* *
|
|
181
|
+
* *structure/before.sql*
|
|
182
|
+
* *structure/after.sql*
|
|
183
|
+
* *fixtures/before.sql*
|
|
184
|
+
* *fixtures/after.sql*
|
|
185
|
+
* *fixtures/local.sql*
|
|
193
186
|
|
|
194
187
|
### Realms
|
|
195
188
|
|
|
196
|
-
|
|
189
|
+
Realms allows users to apply version-specific changes based on their configured
|
|
190
|
+
environment, or "realm". This ensures that certain changes are only applied
|
|
191
|
+
when the user is operating within a specific realm, providing an additional
|
|
192
|
+
layer of customization and control.
|
|
193
|
+
|
|
194
|
+
Realm folders structure.
|
|
197
195
|
|
|
198
196
|
```text
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
`-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
`- 03-flash.sql
|
|
197
|
+
realms
|
|
198
|
+
|- marvel
|
|
199
|
+
| `- 00-spiderman.sql
|
|
200
|
+
| `- 01-hulk.sql
|
|
201
|
+
`- dc
|
|
202
|
+
`- 00-superman.sql
|
|
203
|
+
`- 01-batman.sql
|
|
204
|
+
`- 02-wonder_woman.sql
|
|
205
|
+
`- 03-flash.sql
|
|
209
206
|
```
|
|
210
207
|
|
|
208
|
+
#### Configuration
|
|
209
|
+
|
|
210
|
+
To make use of this feature, you need to configure your realm in the
|
|
211
|
+
`versionConfig` table. Set your realm by inserting or updating a record in
|
|
212
|
+
this table. The `realm` field should contain the identifier of your
|
|
213
|
+
environment.
|
|
214
|
+
|
|
215
|
+
#### Realm-specific version files
|
|
216
|
+
|
|
217
|
+
To designate a version file as realm-specific, include a `.your_realm.` segment
|
|
218
|
+
before the file extension. For example, if your realm is set to 'foo', the file
|
|
219
|
+
should be named like this: `filename.foo.sql`.
|
|
220
|
+
|
|
211
221
|
## Versioning commands
|
|
212
222
|
|
|
213
223
|
### init
|
|
@@ -290,13 +300,31 @@ specified *local* is used.
|
|
|
290
300
|
$ myt fixtures [<remote>]
|
|
291
301
|
```
|
|
292
302
|
|
|
303
|
+
### build
|
|
304
|
+
|
|
305
|
+
Builds local database server image. It only rebuilds the image when sources
|
|
306
|
+
have been modified.
|
|
307
|
+
|
|
308
|
+
```text
|
|
309
|
+
$ myt build [-n|--name] [-t|--tag] [-f|--force] [-m|--realm <string>]
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### apply
|
|
313
|
+
|
|
314
|
+
Applies structure, fixtures and changes to database. Primarily used by the
|
|
315
|
+
build command to rebuild the local database.
|
|
316
|
+
|
|
317
|
+
```text
|
|
318
|
+
$ myt apply [-s|--structure] [-c|--changes] [-m|--realm <string>] [-l|--load <string>]
|
|
319
|
+
```
|
|
320
|
+
|
|
293
321
|
### run
|
|
294
322
|
|
|
295
323
|
Builds and starts local database server container. It only rebuilds the image
|
|
296
324
|
when dump have been modified.
|
|
297
325
|
|
|
298
326
|
```text
|
|
299
|
-
$ myt run [<realm>|-m|--realm <string>] [-c|--ci] [-r|--random] [-p|--persist] [-n|--network <string>] [-i|--ip]
|
|
327
|
+
$ myt run [<realm>|-m|--realm <string>] [-c|--ci] [-r|--random] [-p|--persist] [-k|--keep] [-n|--network <string>] [-i|--ip]
|
|
300
328
|
```
|
|
301
329
|
|
|
302
330
|
### start
|
package/assets/myt.default.yml
CHANGED
|
@@ -7,9 +7,12 @@ mockFunctions:
|
|
|
7
7
|
- mockUtcTime
|
|
8
8
|
sumViews: true
|
|
9
9
|
defaultDefiner: root@localhost
|
|
10
|
+
protectedRemotes:
|
|
11
|
+
- production
|
|
10
12
|
localRemotes:
|
|
11
13
|
- local
|
|
12
14
|
- docker
|
|
15
|
+
- socket
|
|
13
16
|
deprecMarkRegex: __$
|
|
14
17
|
deprecCommentRegex: ^@deprecated [0-9]{4}-[0-9]{2}-[0-9]{2}
|
|
15
18
|
deprecDateRegex: '[0-9]{4}-[0-9]{2}-[0-9]{2}'
|
|
@@ -28,6 +31,10 @@ privileges:
|
|
|
28
31
|
- procs_priv
|
|
29
32
|
where: >-
|
|
30
33
|
`Host` = ''
|
|
34
|
+
dbImageTag: mariadb:10.11.16-jammy
|
|
35
|
+
rootPassword: root
|
|
36
|
+
triggersImport: after
|
|
37
|
+
gitShortLen: 12
|
|
31
38
|
schemas:
|
|
32
39
|
- myt
|
|
33
40
|
fixtures:
|
package/assets/structure.sql
CHANGED
|
@@ -23,7 +23,7 @@ CREATE TABLE `versionLog` (
|
|
|
23
23
|
ALTER TABLE `versionLog`
|
|
24
24
|
ADD PRIMARY KEY (`code`,`number`,`file`);
|
|
25
25
|
|
|
26
|
-
CREATE TABLE `
|
|
26
|
+
CREATE TABLE `versionConfig` (
|
|
27
27
|
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
28
28
|
`realm` VARCHAR(16) NULL DEFAULT NULL COMMENT 'Data set on which the project runs'
|
|
29
29
|
) ENGINE=InnoDB;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
FROM debian:
|
|
1
|
+
FROM debian:11.11-slim
|
|
2
2
|
|
|
3
3
|
ARG DEBIAN_FRONTEND=noninteractive
|
|
4
4
|
RUN apt-get update \
|
|
@@ -8,7 +8,7 @@ RUN apt-get update \
|
|
|
8
8
|
&& rm -rf /var/lib/apt/lists/*
|
|
9
9
|
|
|
10
10
|
COPY \
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
docker-dump.sh \
|
|
12
|
+
docker-fixtures.sh \
|
|
13
13
|
/usr/local/bin/
|
|
14
14
|
WORKDIR /workspace
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
ARG MYT_TAG=myt/app
|
|
2
|
+
ARG BASE_TAG=myt/base
|
|
3
|
+
|
|
4
|
+
FROM ${MYT_TAG} AS dump
|
|
5
|
+
|
|
6
|
+
ARG ROOT_PASS
|
|
7
|
+
ENV ROOT_PASS=${ROOT_PASS}
|
|
8
|
+
|
|
9
|
+
RUN mkdir -p /mysql-template \
|
|
10
|
+
&& chown mysql:mysql /mysql-template
|
|
11
|
+
|
|
12
|
+
WORKDIR /workspace
|
|
13
|
+
|
|
14
|
+
COPY myt.config.yml .
|
|
15
|
+
COPY remotes/socket.ini ./remotes/
|
|
16
|
+
COPY structure structure
|
|
17
|
+
COPY fixtures fixtures
|
|
18
|
+
COPY versions versions
|
|
19
|
+
COPY routines routines
|
|
20
|
+
COPY realms realms
|
|
21
|
+
|
|
22
|
+
ARG MYT_REALM
|
|
23
|
+
ARG MYT_COMMIT
|
|
24
|
+
RUN --mount=type=tmpfs,target=/var/lib/mysql \
|
|
25
|
+
chown mysql:mysql /var/lib/mysql \
|
|
26
|
+
&& gosu mysql docker-init.sh
|
|
27
|
+
|
|
28
|
+
FROM ${BASE_TAG}
|
|
29
|
+
|
|
30
|
+
COPY --from=dump --chown=mysql:mysql \
|
|
31
|
+
/mysql-template /mysql-template
|
|
32
|
+
|
|
33
|
+
ENTRYPOINT ["docker-start.sh"]
|
|
34
|
+
CMD ["mariadbd"]
|
|
35
|
+
|
|
36
|
+
HEALTHCHECK --interval=2s --timeout=10s --retries=200 \
|
|
37
|
+
CMD gosu mysql mariadb-admin ping || exit 1
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
ARG BASE_TAG=myt/base
|
|
2
|
+
FROM ${BASE_TAG}
|
|
3
|
+
|
|
4
|
+
# Myt
|
|
5
|
+
|
|
6
|
+
ARG DEBIAN_FRONTEND=noninteractive
|
|
7
|
+
RUN apt-get update \
|
|
8
|
+
&& apt-get install -y --no-install-recommends \
|
|
9
|
+
curl \
|
|
10
|
+
ca-certificates \
|
|
11
|
+
gnupg2 \
|
|
12
|
+
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
|
13
|
+
&& apt-get install -y --no-install-recommends nodejs \
|
|
14
|
+
&& npm install -g corepack@0.34.6 \
|
|
15
|
+
&& corepack enable \
|
|
16
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
17
|
+
|
|
18
|
+
# RUN apt-get update \
|
|
19
|
+
# && apt-get install -y --no-install-recommends \
|
|
20
|
+
# libkrb5-dev \
|
|
21
|
+
# libssl-dev \
|
|
22
|
+
# build-essential \
|
|
23
|
+
# && rm -rf /var/lib/apt/lists/*
|
|
24
|
+
|
|
25
|
+
WORKDIR /myt
|
|
26
|
+
COPY package.json ./
|
|
27
|
+
RUN pnpm install --prod --ignore-scripts
|
|
28
|
+
|
|
29
|
+
COPY . ./
|
|
30
|
+
RUN npm install -g /myt
|
|
31
|
+
|
|
32
|
+
# Server
|
|
33
|
+
|
|
34
|
+
ARG SERVER_DIR=docker/server
|
|
35
|
+
COPY ${SERVER_DIR}/docker-init.sh /usr/local/bin/
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
export MYSQL_ROOT_PASSWORD="$ROOT_PASS"
|
|
5
|
+
export MYSQL_ALLOW_EMPTY_PASSWORD='true'
|
|
6
|
+
export MARIADB_MYSQL_LOCALHOST_USER='yes'
|
|
7
|
+
|
|
8
|
+
. /usr/local/bin/docker-entrypoint.sh
|
|
9
|
+
|
|
10
|
+
ARGS=(mariadbd --datadir=/var/lib/mysql)
|
|
11
|
+
|
|
12
|
+
mysql_check_config ${ARGS[@]}
|
|
13
|
+
docker_setup_env ${ARGS[@]}
|
|
14
|
+
docker_create_db_directories
|
|
15
|
+
docker_verify_minimum_env
|
|
16
|
+
docker_init_database_dir ${ARGS[@]}
|
|
17
|
+
|
|
18
|
+
docker_temp_server_start ${ARGS[@]}
|
|
19
|
+
docker_setup_db
|
|
20
|
+
|
|
21
|
+
MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mariadb -u root \
|
|
22
|
+
-e "GRANT ALL PRIVILEGES ON *.* TO mysql@localhost WITH GRANT OPTION"
|
|
23
|
+
|
|
24
|
+
docker_process_init_files /docker-entrypoint-initdb.d/*
|
|
25
|
+
|
|
26
|
+
myt apply \
|
|
27
|
+
--debug \
|
|
28
|
+
--structure \
|
|
29
|
+
--changes \
|
|
30
|
+
--remote socket \
|
|
31
|
+
--docker \
|
|
32
|
+
--load "$MYT_COMMIT" \
|
|
33
|
+
--realm "$MYT_REALM"
|
|
34
|
+
|
|
35
|
+
docker_temp_server_stop
|
|
36
|
+
cp -a /var/lib/mysql/. /mysql-template
|
|
@@ -4,7 +4,7 @@ set -e
|
|
|
4
4
|
# XXX: Workaround to avoid OverlayFS bug on MacOs
|
|
5
5
|
# https://docs.docker.com/storage/storagedriver/overlayfs-driver/#limitations-on-overlayfs-compatibility
|
|
6
6
|
|
|
7
|
-
if [ ! -d /var/lib/mysql/mysql ]; then
|
|
7
|
+
if [[ ! -d /var/lib/mysql/mysql && -d /mysql-template ]]; then
|
|
8
8
|
chown mysql:mysql /var/lib/mysql
|
|
9
9
|
cp -a /mysql-template/. /var/lib/mysql
|
|
10
10
|
fi
|
package/lib/command.js
CHANGED
|
@@ -3,12 +3,16 @@
|
|
|
3
3
|
*/
|
|
4
4
|
module.exports = class MytCommand{
|
|
5
5
|
constructor(myt, opts) {
|
|
6
|
-
this
|
|
7
|
-
|
|
6
|
+
Object.assign(this, {
|
|
7
|
+
myt,
|
|
8
|
+
ctx: myt.ctx,
|
|
9
|
+
cfg: myt.cfg,
|
|
10
|
+
opts: opts || {}
|
|
11
|
+
});
|
|
8
12
|
this.handlers = {};
|
|
9
13
|
}
|
|
10
14
|
|
|
11
|
-
async cli(
|
|
15
|
+
async cli() {
|
|
12
16
|
const reporter = this.constructor.reporter;
|
|
13
17
|
if (reporter)
|
|
14
18
|
for (const event in reporter) {
|
|
@@ -19,11 +23,15 @@ module.exports = class MytCommand{
|
|
|
19
23
|
this.on(event, handler);
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
await this.run(
|
|
26
|
+
return await this.run();
|
|
23
27
|
}
|
|
24
28
|
|
|
25
|
-
async run(
|
|
26
|
-
|
|
29
|
+
async run() {
|
|
30
|
+
return await this._run(this.myt, this.ctx, this.cfg, this.opts);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async _run(myt, ctx, cfg, opts) {
|
|
34
|
+
throw new Error('run method not defined');
|
|
27
35
|
}
|
|
28
36
|
|
|
29
37
|
on(event, handler) {
|
package/lib/docker.js
CHANGED
|
@@ -3,7 +3,7 @@ const execFile = require('child_process').execFile;
|
|
|
3
3
|
const camelToSnake = require('./util').camelToSnake;
|
|
4
4
|
|
|
5
5
|
const docker = {
|
|
6
|
-
async run(image, commandArgs, options, execOptions) {
|
|
6
|
+
async run(image, commandArgs, options, execOptions, debug) {
|
|
7
7
|
const args = commandArgs
|
|
8
8
|
? [image].concat(commandArgs)
|
|
9
9
|
: image;
|
|
@@ -13,19 +13,24 @@ const docker = {
|
|
|
13
13
|
args,
|
|
14
14
|
options,
|
|
15
15
|
execMode,
|
|
16
|
-
execOptions
|
|
16
|
+
execOptions,
|
|
17
|
+
debug
|
|
17
18
|
);
|
|
18
19
|
return options.detach
|
|
19
20
|
? new Container(child.stdout.trim())
|
|
20
21
|
: child;
|
|
21
22
|
},
|
|
22
23
|
|
|
23
|
-
async build(url, options,
|
|
24
|
+
async build(url, options, debug) {
|
|
25
|
+
if (debug === true && options.progress == null)
|
|
26
|
+
options = Object.assign({progress: 'plain'}, options);
|
|
27
|
+
|
|
24
28
|
return await this.command('build',
|
|
25
29
|
url,
|
|
26
30
|
options,
|
|
27
31
|
'spawn',
|
|
28
|
-
|
|
32
|
+
undefined,
|
|
33
|
+
debug
|
|
29
34
|
);
|
|
30
35
|
},
|
|
31
36
|
|
|
@@ -50,51 +55,72 @@ const docker = {
|
|
|
50
55
|
return await ct.inspect(options);
|
|
51
56
|
},
|
|
52
57
|
|
|
53
|
-
async
|
|
58
|
+
async images(tag, options) {
|
|
59
|
+
options = Object.assign({format: 'json'}, options);
|
|
60
|
+
const child = await docker.command('images', tag, options);
|
|
61
|
+
return JSON.parse(child.stdout || null);
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
async command(command, args, options, execMode, execOptions, debug) {
|
|
54
65
|
const execArgs = [command];
|
|
55
66
|
|
|
56
67
|
if (options)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
for (const option in options) {
|
|
69
|
+
const value = options[option];
|
|
70
|
+
const param = `--${camelToSnake(option)}`;
|
|
71
|
+
|
|
72
|
+
if (typeof value == 'boolean') {
|
|
73
|
+
execArgs.push (param)
|
|
74
|
+
} else if (Array.isArray(value)) {
|
|
75
|
+
for (const val of value)
|
|
76
|
+
execArgs.push(param, val)
|
|
77
|
+
} else {
|
|
78
|
+
execArgs.push(param, value);
|
|
61
79
|
}
|
|
80
|
+
}
|
|
62
81
|
|
|
63
82
|
if (Array.isArray(args))
|
|
64
83
|
Array.prototype.push.apply(execArgs, args);
|
|
65
84
|
else if (args)
|
|
66
85
|
execArgs.push(args);
|
|
67
86
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
87
|
+
const dockerBin = 'docker';
|
|
88
|
+
|
|
89
|
+
if (debug === true) {
|
|
90
|
+
const quotedArgs = execArgs
|
|
91
|
+
.map(x => /\s/g.test(x) ? `"${x}"` : x)
|
|
92
|
+
.join(' ');
|
|
93
|
+
console.debug('Command:', `${dockerBin} ${quotedArgs}`.yellow);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (execMode == 'spawn') {
|
|
97
|
+
if (debug === true && !execOptions)
|
|
98
|
+
execOptions = {
|
|
99
|
+
stdio: [
|
|
100
|
+
process.stdin,
|
|
101
|
+
process.stdout,
|
|
102
|
+
process.stderr
|
|
103
|
+
]
|
|
104
|
+
};
|
|
105
|
+
const child = spawn(dockerBin, execArgs, execOptions);
|
|
106
|
+
return await new Promise((resolve, reject) => {
|
|
80
107
|
child.on('exit', code => {
|
|
81
|
-
if (code !== 0)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
.join(' ');
|
|
85
|
-
reject(new Error(`Docker exit code ${code}: 'docker ${quotedArgs}'`));
|
|
86
|
-
} else
|
|
108
|
+
if (code !== 0)
|
|
109
|
+
reject(new Error(`${dockerBin} exit code ${code}`));
|
|
110
|
+
else
|
|
87
111
|
resolve(code);
|
|
88
112
|
});
|
|
89
|
-
}
|
|
90
|
-
|
|
113
|
+
});
|
|
114
|
+
} else {
|
|
115
|
+
return await new Promise((resolve, reject) => {
|
|
116
|
+
execFile(dockerBin, execArgs, (err, stdout, stderr) => {
|
|
91
117
|
if (err)
|
|
92
118
|
reject(err);
|
|
93
119
|
else
|
|
94
120
|
resolve({stdout, stderr});
|
|
95
121
|
});
|
|
96
|
-
}
|
|
97
|
-
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
98
124
|
}
|
|
99
125
|
};
|
|
100
126
|
|
|
@@ -119,13 +145,13 @@ class Container {
|
|
|
119
145
|
|
|
120
146
|
async inspect(options) {
|
|
121
147
|
const child = await docker.command('inspect', this.id, options);
|
|
122
|
-
return JSON.parse(child.stdout);
|
|
148
|
+
return JSON.parse(child.stdout || null);
|
|
123
149
|
}
|
|
124
150
|
|
|
125
|
-
async exec(options, command, commandArgs, execMode, execOptions) {
|
|
151
|
+
async exec(options, command, commandArgs, execMode, execOptions, debug) {
|
|
126
152
|
let args = [this.id, command];
|
|
127
153
|
if (commandArgs) args = args.concat(commandArgs);
|
|
128
|
-
await docker.command('exec', args, options, execMode, execOptions);
|
|
154
|
+
await docker.command('exec', args, options, execMode, execOptions, debug);
|
|
129
155
|
}
|
|
130
156
|
}
|
|
131
157
|
|
package/lib/dumper.js
CHANGED
|
@@ -4,8 +4,10 @@ const path = require('path');
|
|
|
4
4
|
const SqlString = require('sqlstring');
|
|
5
5
|
|
|
6
6
|
module.exports = class Dumper {
|
|
7
|
-
constructor(
|
|
8
|
-
this.
|
|
7
|
+
constructor(myt) {
|
|
8
|
+
this.myt = myt;
|
|
9
|
+
this.cfg = myt.cfg;
|
|
10
|
+
this.ctx = myt.ctx;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
async init(dumpDir, dumpFile) {
|
|
@@ -18,11 +20,10 @@ module.exports = class Dumper {
|
|
|
18
20
|
// "invalid" WriteStream
|
|
19
21
|
const dumpStream = await fs.createWriteStream(dumpPath);
|
|
20
22
|
|
|
21
|
-
const buidDir = path.join(__dirname, '
|
|
23
|
+
const buidDir = path.join(__dirname, '../docker/client');
|
|
22
24
|
await docker.build(buidDir, {
|
|
23
|
-
tag: 'myt/client'
|
|
24
|
-
|
|
25
|
-
}, this.opts.debug);
|
|
25
|
+
tag: 'myt/client'
|
|
26
|
+
}, this.cfg.debug);
|
|
26
27
|
|
|
27
28
|
this.dumpStream = dumpStream;
|
|
28
29
|
}
|
|
@@ -83,7 +84,7 @@ module.exports = class Dumper {
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
async runDump(command, args) {
|
|
86
|
-
const iniPath = path.join('remotes', this.
|
|
87
|
+
const iniPath = path.join('remotes', this.ctx.iniFile);
|
|
87
88
|
const myArgs = [
|
|
88
89
|
`--defaults-file=${iniPath}`
|
|
89
90
|
];
|
|
@@ -97,8 +98,9 @@ module.exports = class Dumper {
|
|
|
97
98
|
const commandArgs = [command].concat(myArgs, args);
|
|
98
99
|
await docker.run('myt/client', commandArgs, {
|
|
99
100
|
addHost: 'host.docker.internal:host-gateway',
|
|
100
|
-
volume: `${this.
|
|
101
|
+
volume: `${this.ctx.mytDir}:/workspace`,
|
|
102
|
+
network: 'host',
|
|
101
103
|
rm: true
|
|
102
|
-
}, execOptions);
|
|
104
|
+
}, execOptions, this.cfg.debug);
|
|
103
105
|
}
|
|
104
106
|
}
|
package/lib/exporter-engine.js
CHANGED
|
@@ -3,10 +3,10 @@ const fs = require('fs-extra');
|
|
|
3
3
|
const Exporter = require('./exporter');
|
|
4
4
|
|
|
5
5
|
module.exports = class ExporterEngine {
|
|
6
|
-
constructor(conn,
|
|
6
|
+
constructor(conn, myt) {
|
|
7
7
|
this.conn = conn;
|
|
8
|
-
this.
|
|
9
|
-
this.pullFile = `${
|
|
8
|
+
this.myt = myt;
|
|
9
|
+
this.pullFile = `${myt.ctx.mytDir}/.pullinfo.json`;
|
|
10
10
|
this.exporters = [];
|
|
11
11
|
this.exporterMap = {};
|
|
12
12
|
}
|
|
@@ -36,7 +36,7 @@ module.exports = class ExporterEngine {
|
|
|
36
36
|
];
|
|
37
37
|
|
|
38
38
|
for (const type of types) {
|
|
39
|
-
const exporter = new Exporter(type, this.
|
|
39
|
+
const exporter = new Exporter(type, this.myt.cfg.replace);
|
|
40
40
|
await exporter.init();
|
|
41
41
|
|
|
42
42
|
this.exporters.push(exporter);
|
package/lib/server.js
CHANGED
|
@@ -17,13 +17,7 @@ module.exports = class Server {
|
|
|
17
17
|
let elapsedTime = 0;
|
|
18
18
|
let maxInterval = 4 * 60 * 1000;
|
|
19
19
|
|
|
20
|
-
const dbConfig = this.dbConfig;
|
|
21
|
-
let myConf = {
|
|
22
|
-
user: dbConfig.user,
|
|
23
|
-
password: dbConfig.password,
|
|
24
|
-
host: dbConfig.host,
|
|
25
|
-
port: dbConfig.port
|
|
26
|
-
};
|
|
20
|
+
const dbConfig = Object.assign({}, this.dbConfig);
|
|
27
21
|
|
|
28
22
|
async function checker() {
|
|
29
23
|
elapsedTime += interval;
|
|
@@ -40,7 +34,7 @@ module.exports = class Server {
|
|
|
40
34
|
if (status === 'exited')
|
|
41
35
|
return reject(new Error('Docker exited, please see the docker logs for more info'));
|
|
42
36
|
|
|
43
|
-
const conn = mysql.createConnection(
|
|
37
|
+
const conn = mysql.createConnection(dbConfig);
|
|
44
38
|
conn.on('error', () => {});
|
|
45
39
|
conn.connect(err => {
|
|
46
40
|
conn.destroy();
|