codefresh 0.78.5 → 0.79.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/.dockerignore +1 -0
- package/Dockerfile +3 -4
- package/check-version.js +1 -1
- package/codefresh-release.yml +268 -61
- package/codefresh.yml +64 -20
- package/e2e/README.md +10 -0
- package/e2e/data/crud.pip.yaml +23 -0
- package/e2e/data/test-run.pip.yaml +23 -0
- package/e2e/e2e.spec.sh +25 -0
- package/e2e/helpers.sh +10 -0
- package/e2e/scenarios/agents.sh +1 -0
- package/e2e/scenarios/annotations.sh +2 -0
- package/e2e/scenarios/boards.sh +3 -0
- package/e2e/scenarios/builds.sh +1 -0
- package/e2e/scenarios/clusters.sh +1 -0
- package/e2e/scenarios/compositions.sh +1 -0
- package/e2e/scenarios/contexts.sh +1 -0
- package/e2e/scenarios/environments.sh +1 -0
- package/e2e/scenarios/helm-repo.sh +1 -0
- package/e2e/scenarios/images.sh +1 -0
- package/e2e/scenarios/pipeline-run.sh +26 -0
- package/e2e/scenarios/pipelines.sh +31 -0
- package/e2e/scenarios/projects.sh +17 -0
- package/e2e/scenarios/registry.sh +1 -0
- package/e2e/scenarios/repository.sh +2 -0
- package/e2e/scenarios/runtime-environment.sh +1 -0
- package/e2e/scenarios/step-types.sh +1 -0
- package/e2e/scenarios/system-runtime-environments.sh +1 -0
- package/e2e/scenarios/teams.sh +1 -0
- package/e2e/scenarios/tokens.sh +1 -0
- package/e2e/scenarios/triggers.sh +3 -0
- package/lib/interface/cli/commands/offline-logs/offload-to-file.cmd.js +12 -14
- package/lib/interface/cli/commands/offline-logs/offload-to-file.spec.js +110 -53
- package/lib/interface/cli/commands/offline-logs/utils.js +131 -126
- package/lib/interface/cli/completion/completion.spec.js +18 -15
- package/lib/interface/cli/completion/tree.json +1 -1
- package/lib/interface/cli/helpers/helpers.sdk.spec.js +0 -9
- package/lib/interface/cli/helpers/logs.js +2 -12
- package/lib/logic/cli-config/Manager.js +4 -5
- package/lib/logic/cli-config/Model.js +4 -5
- package/lib/logic/cli-config/manager.spec.js +10 -13
- package/lib/logic/entities/Agent.js +1 -3
- package/lib/logic/entities/CodefreshRepo.js +1 -1
- package/lib/logic/entities/Entity.js +1 -0
- package/lib/logic/entities/Environment.js +1 -0
- package/lib/logic/entities/GitRepo.js +1 -1
- package/lib/logic/entities/HelmRepo.js +1 -2
- package/lib/logic/entities/Pipeline.js +1 -1
- package/lib/logic/entities/RuntimeEnvironments.js +1 -1
- package/lib/logic/entities/StepType.js +2 -2
- package/lib/logic/entities/StepTypeVersion.js +0 -1
- package/lib/logic/entities/Team.js +2 -2
- package/lib/logic/entities/Token.js +2 -2
- package/lib/logic/entities/Workflow.js +1 -1
- package/lib/logic/index.js +0 -2
- package/package.json +32 -20
- package/yarn.lock +1506 -883
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codefresh get environments
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codefresh get helm-repo
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codefresh get images
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
project=test-run
|
|
2
|
+
pipeline="$project/test-run"
|
|
3
|
+
pipeline_file="$SCRIPT_DIR/data/test-run.pip.yaml"
|
|
4
|
+
|
|
5
|
+
existing_pipeline=`exists pipeline $pipeline`
|
|
6
|
+
existing_project=`exists project $project`
|
|
7
|
+
|
|
8
|
+
if [ -z "$existing_project" ]; then
|
|
9
|
+
echo "Project does not exist: $project"
|
|
10
|
+
echo "Creating project: $project"
|
|
11
|
+
codefresh create project $project
|
|
12
|
+
else
|
|
13
|
+
echo "Project already exists: $project"
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
if [ -z "$existing_pipeline" ]; then
|
|
17
|
+
echo "Pipeline does not exist: $pipeline"
|
|
18
|
+
echo "Creating pipeline: $pipeline"
|
|
19
|
+
codefresh create -f $pipeline_file
|
|
20
|
+
else
|
|
21
|
+
echo "Pipeline already exists: $pipeline"
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
codefresh run $pipeline
|
|
25
|
+
codefresh delete pipeline $pipeline
|
|
26
|
+
codefresh delete project $project
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
project='pipeline-crud'
|
|
2
|
+
pipeline="$project/crud"
|
|
3
|
+
pipeline_file="$SCRIPT_DIR/data/crud.pip.yaml"
|
|
4
|
+
|
|
5
|
+
existing_project=`exists project $project`
|
|
6
|
+
existing_pipeline=`exists pipeline $pipeline`
|
|
7
|
+
|
|
8
|
+
if [ -z "$existing_project" ]; then
|
|
9
|
+
echo "Project does not exist: $project"
|
|
10
|
+
echo "Creating project: $project"
|
|
11
|
+
codefresh create project $project
|
|
12
|
+
else
|
|
13
|
+
echo "Project already exists: $project"
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
if [ -z "$existing_pipeline" ]; then
|
|
17
|
+
echo "Pipeline does not exist: $pipeline"
|
|
18
|
+
echo "Creating pipeline: $pipeline"
|
|
19
|
+
codefresh create -f $pipeline_file
|
|
20
|
+
else
|
|
21
|
+
echo "Pipeline already exists: $pipeline"
|
|
22
|
+
codefresh delete pipeline $pipeline
|
|
23
|
+
codefresh create -f $pipeline_file
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
codefresh get pipelines
|
|
27
|
+
codefresh get pipeline $pipeline
|
|
28
|
+
|
|
29
|
+
codefresh delete pipeline $pipeline
|
|
30
|
+
codefresh delete project $project
|
|
31
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
project='project-crud'
|
|
2
|
+
|
|
3
|
+
existing_project=`exists project $project`
|
|
4
|
+
|
|
5
|
+
if [ -z "$existing_project" ]; then
|
|
6
|
+
echo "Project does not exist: $project"
|
|
7
|
+
echo "Creating project: $project"
|
|
8
|
+
codefresh create project $project
|
|
9
|
+
else
|
|
10
|
+
echo "Project already exists: $project"
|
|
11
|
+
codefresh delete project $project
|
|
12
|
+
codefresh create project $project
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
codefresh get projects
|
|
16
|
+
codefresh get project $project
|
|
17
|
+
codefresh delete project $project
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codefresh get registry
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codefresh get runtime-environments
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codefresh get step-types
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codefresh get system-runtime-environments
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codefresh get teams
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codefresh get tokens
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
1
2
|
const { MongoClient, ObjectId } = require("mongodb");
|
|
2
3
|
const moment = require("moment");
|
|
3
4
|
const Command = require("../../Command");
|
|
@@ -34,7 +35,7 @@ const offloadToFile = async function (
|
|
|
34
35
|
}
|
|
35
36
|
const cutoffDateId = objectIdFromDate(cutoffDateObj.toDate());
|
|
36
37
|
|
|
37
|
-
const minLog = await findMinLog(collectionObj, cutoffDateId
|
|
38
|
+
const minLog = await findMinLog(collectionObj, cutoffDateId);
|
|
38
39
|
|
|
39
40
|
if (!minLog) {
|
|
40
41
|
console.info(
|
|
@@ -61,25 +62,22 @@ const offloadToFile = async function (
|
|
|
61
62
|
const lowerBoundId = objectIdFromDate(lowerBound.toDate());
|
|
62
63
|
const upperBoundId = objectIdFromDate(upperBound.toDate());
|
|
63
64
|
|
|
64
|
-
const
|
|
65
|
+
const logsCursor = await collectionObj
|
|
65
66
|
.find({
|
|
66
67
|
_id: {
|
|
67
68
|
$gte: ObjectId(lowerBoundId),
|
|
68
69
|
$lt: ObjectId(upperBoundId),
|
|
69
70
|
},
|
|
70
|
-
})
|
|
71
|
-
.toArray();
|
|
71
|
+
});
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
writeLogsToFile(upperBound, lowerBound, collection, logsToArchive, path);
|
|
73
|
+
await writeLogsToFile(upperBound, lowerBound, collection, logsCursor, path);
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
75
|
+
await collectionObj.deleteMany({
|
|
76
|
+
_id: {
|
|
77
|
+
$gte: ObjectId(lowerBoundId),
|
|
78
|
+
$lt: ObjectId(upperBoundId),
|
|
79
|
+
},
|
|
80
|
+
});
|
|
83
81
|
}
|
|
84
82
|
};
|
|
85
83
|
|
|
@@ -152,7 +150,7 @@ const command = new Command({
|
|
|
152
150
|
path
|
|
153
151
|
);
|
|
154
152
|
} catch (e) {
|
|
155
|
-
console.
|
|
153
|
+
console.error(e);
|
|
156
154
|
failedCollections.push(collection);
|
|
157
155
|
errors.push(error);
|
|
158
156
|
}
|
|
@@ -1,59 +1,116 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
const moment = require('moment');
|
|
2
3
|
const { writeLogsToFile, checkRemnant } = require('./utils');
|
|
3
|
-
const fs = require('fs')
|
|
4
|
+
const fs = require('fs');
|
|
4
5
|
|
|
5
6
|
describe('offload-to-file', () => {
|
|
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
|
-
|
|
7
|
+
describe('writeLogsToFile', () => {
|
|
8
|
+
it('writes the input data to file', async () => {
|
|
9
|
+
const upperBound = '2021-08-10';
|
|
10
|
+
const lowerBound = '2021-08-01';
|
|
11
|
+
const collection = 'logs';
|
|
12
|
+
const pathMock = 'some/path';
|
|
13
|
+
let writerResult = '';
|
|
14
|
+
const expectedWrite = '[\n{"key1":"val"},\n{"key2":"val"},\n{"key3":"val"},\n{"key4":"val"}\n]';
|
|
15
|
+
class LogsCursor {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.logs = [{ key1: 'val' }, { key2: 'val' }, { key3: 'val' }, { key4: 'val' }];
|
|
18
|
+
this.pointer = 0;
|
|
19
|
+
this.next = jest.fn(() => {
|
|
20
|
+
let currentDoc = null;
|
|
21
|
+
if (this.pointer < this.logs.length) {
|
|
22
|
+
currentDoc = this.logs[this.pointer];
|
|
23
|
+
}
|
|
24
|
+
this.pointer += 1;
|
|
25
|
+
return currentDoc;
|
|
26
|
+
});
|
|
27
|
+
this.isClosed = jest.fn(() => this.pointer > this.logs.length);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const writerMock = {
|
|
31
|
+
write: jest.fn((text) => {
|
|
32
|
+
writerResult = `${writerResult}${text}`;
|
|
33
|
+
}),
|
|
34
|
+
close: jest.fn(),
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
fs.createWriteStream = jest.fn(path => writerMock);
|
|
38
|
+
await writeLogsToFile(upperBound, lowerBound, collection, new LogsCursor(), pathMock);
|
|
39
|
+
expect(fs.createWriteStream.mock.calls.length).toBe(1);
|
|
40
|
+
expect(fs.createWriteStream.mock.calls[0][0]).toContain(pathMock);
|
|
41
|
+
expect(writerMock.write.mock.calls.length).toBe(6);
|
|
42
|
+
expect(writerResult).toBe(expectedWrite);
|
|
43
|
+
expect(writerMock.close.mock.calls.length).toBe(1);
|
|
44
|
+
});
|
|
45
|
+
it('creates the correct file name', async () => {
|
|
46
|
+
const upperBound = '2021-08-10';
|
|
47
|
+
const lowerBound = '2021-08-01';
|
|
48
|
+
const collection = 'logs';
|
|
49
|
+
const expectedPath = 'some/path/2021-08-01-2021-08-09-logs.json';
|
|
50
|
+
const somePath = 'some/path';
|
|
51
|
+
class LogsCursor {
|
|
52
|
+
constructor() {
|
|
53
|
+
this.logs = [{ key1: 'val' }, { key2: 'val' }, { key3: 'val' }, { key4: 'val' }];
|
|
54
|
+
this.pointer = 0;
|
|
55
|
+
this.next = jest.fn(() => {
|
|
56
|
+
let currentDoc = null;
|
|
57
|
+
if (this.pointer < this.logs.length) {
|
|
58
|
+
currentDoc = this.logs[this.pointer];
|
|
59
|
+
}
|
|
60
|
+
this.pointer += 1;
|
|
61
|
+
return currentDoc;
|
|
62
|
+
});
|
|
63
|
+
this.isClosed = jest.fn(() => this.pointer > this.logs.length);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const writerMock = {
|
|
67
|
+
write: jest.fn(text => text),
|
|
68
|
+
close: jest.fn(),
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
fs.createWriteStream = jest.fn(path => writerMock);
|
|
72
|
+
await writeLogsToFile(upperBound, lowerBound, collection, new LogsCursor(), somePath);
|
|
73
|
+
expect(fs.createWriteStream.mock.calls.length).toBe(1);
|
|
74
|
+
expect(fs.createWriteStream.mock.calls[0][0]).toBe(expectedPath);
|
|
75
|
+
});
|
|
76
|
+
it('checks leap year date calculation', async () => {
|
|
77
|
+
const upperBound = '2020-03-01';
|
|
78
|
+
const lowerBound = '2020-02-01';
|
|
79
|
+
const collection = 'logs';
|
|
80
|
+
const expectedPath = 'some/path/2020-02-01-2020-02-29-logs.json';
|
|
81
|
+
const somePath = 'some/path';
|
|
82
|
+
class LogsCursor {
|
|
83
|
+
constructor() {
|
|
84
|
+
this.logs = [{ key1: 'val' }, { key2: 'val' }, { key3: 'val' }, { key4: 'val' }];
|
|
85
|
+
this.pointer = 0;
|
|
86
|
+
this.next = jest.fn(() => {
|
|
87
|
+
let currentDoc = null;
|
|
88
|
+
if (this.pointer < this.logs.length) {
|
|
89
|
+
currentDoc = this.logs[this.pointer];
|
|
90
|
+
}
|
|
91
|
+
this.pointer += 1;
|
|
92
|
+
return currentDoc;
|
|
93
|
+
});
|
|
94
|
+
this.isClosed = jest.fn(() => this.pointer > this.logs.length);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const writerMock = {
|
|
98
|
+
write: jest.fn(text => text),
|
|
99
|
+
close: jest.fn(),
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
fs.createWriteStream = jest.fn(path => writerMock);
|
|
103
|
+
await writeLogsToFile(upperBound, lowerBound, collection, new LogsCursor(), somePath);
|
|
104
|
+
expect(fs.createWriteStream.mock.calls.length).toBe(1);
|
|
105
|
+
expect(fs.createWriteStream.mock.calls[0][0]).toBe(expectedPath);
|
|
106
|
+
});
|
|
49
107
|
});
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
108
|
+
describe('checkRemnant', () => {
|
|
109
|
+
it('checkes days remnant to make sure time range is not going off boundaries', () => {
|
|
110
|
+
const lowerBound = '2020-08-01';
|
|
111
|
+
const cutoffDateObj = moment('2020-08-01').add(1, 'days').startOf('day');
|
|
112
|
+
const result = checkRemnant(lowerBound, cutoffDateObj);
|
|
113
|
+
expect(result).toBe(1);
|
|
114
|
+
});
|
|
57
115
|
});
|
|
58
|
-
});
|
|
59
116
|
});
|
|
@@ -1,159 +1,164 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
const
|
|
1
|
+
/* eslint-disable no-await-in-loop */
|
|
2
|
+
const readline = require('readline');
|
|
3
|
+
const moment = require('moment');
|
|
4
|
+
const { ObjectId } = require('mongodb');
|
|
4
5
|
|
|
5
|
-
const { join } = require(
|
|
6
|
-
const fs = require(
|
|
6
|
+
const { join } = require('path');
|
|
7
|
+
const fs = require('fs');
|
|
7
8
|
|
|
8
|
-
const defaultCollections = [
|
|
9
|
+
const defaultCollections = ['logs', 'metadata'];
|
|
9
10
|
|
|
10
11
|
// converts date to objectId for filter purposes
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
12
|
+
function objectIdFromDate(date) {
|
|
13
|
+
return `${Math.floor(date.getTime() / 1000).toString(16)}0000000000000000`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function createRangeStr(lowerBound, upperBound, collection) {
|
|
17
|
+
const upperBoundDate = moment(upperBound).subtract(1, 'days');
|
|
18
|
+
const fileDateRange = `${moment(lowerBound).format('YYYY-MM-DD')}-${upperBoundDate.format('YYYY-MM-DD')}`;
|
|
19
|
+
return `${fileDateRange}-${collection}`;
|
|
20
|
+
}
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
async function writeLogsToFile(
|
|
23
|
+
upperBound,
|
|
24
|
+
lowerBound,
|
|
25
|
+
collection,
|
|
26
|
+
logsCursor,
|
|
27
|
+
path,
|
|
21
28
|
) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
const fileName = `${createRangeStr(lowerBound, upperBound, collection)}.json`;
|
|
30
|
+
const absPath = join(path, fileName);
|
|
31
|
+
const stream = fs.createWriteStream(absPath);
|
|
32
|
+
let count = 0;
|
|
33
|
+
stream.write('[');
|
|
34
|
+
|
|
35
|
+
let comma = '';
|
|
36
|
+
while (!logsCursor.isClosed()) {
|
|
37
|
+
const doc = await logsCursor.next();
|
|
38
|
+
if (doc) {
|
|
39
|
+
const data = JSON.stringify(doc);
|
|
40
|
+
stream.write(`${comma}\n${data}`);
|
|
41
|
+
comma = ',';
|
|
42
|
+
count += 1;
|
|
43
|
+
} else {
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
28
47
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
)}-${upperBoundDate.format("YYYY-MM-DD")}`;
|
|
34
|
-
return `${fileDateRange}-${collection}`;
|
|
48
|
+
stream.write('\n]');
|
|
49
|
+
stream.close();
|
|
50
|
+
|
|
51
|
+
console.info(`${count} logs from collection '${collection}' were offloaded to '${absPath}'`);
|
|
35
52
|
}
|
|
36
53
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
minLogId.getTimestamp()
|
|
41
|
-
).startOf("day");
|
|
54
|
+
function getMinDate(minLog) {
|
|
55
|
+
const minLogId = ObjectId(minLog._id);
|
|
56
|
+
return moment(minLogId.getTimestamp()).startOf('day');
|
|
42
57
|
}
|
|
43
58
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
///////////////////////////////////////////////////////////////
|
|
48
|
-
const ensureIndex = async function (database, collection) {
|
|
49
|
-
const collectionObj = database.collection(collection);
|
|
50
|
-
const indexName = "accountId_1_jobId_1";
|
|
59
|
+
function checkRemnant(lowerBound, cutoffDateObj) {
|
|
60
|
+
return Math.ceil(cutoffDateObj.diff(lowerBound, 'days'));
|
|
61
|
+
}
|
|
51
62
|
|
|
52
|
-
|
|
63
|
+
async function ensureIndex(database, collection) {
|
|
64
|
+
const collectionObj = database.collection(collection);
|
|
65
|
+
const indexName = 'accountId_1_jobId_1';
|
|
53
66
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
67
|
+
const indexExist = await collectionObj.indexExists(indexName);
|
|
68
|
+
|
|
69
|
+
if (indexExist) {
|
|
70
|
+
console.info(`index '${indexName}' already exists in collection '${collection}'`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
60
73
|
|
|
61
|
-
|
|
74
|
+
const documentsCount = await collectionObj.estimatedDocumentCount();
|
|
62
75
|
|
|
63
|
-
|
|
76
|
+
const queryStr = `There are approximately ${documentsCount} documents on collection '${collection}'.
|
|
64
77
|
do you want to create an index for it? (creating an index for a large collection may take a while,
|
|
65
78
|
but can improve performance on future read operations) [yes/no] `;
|
|
66
79
|
|
|
67
|
-
|
|
80
|
+
const userInput = await this.getUserInput(queryStr);
|
|
68
81
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
if (!userInput) {
|
|
83
|
+
console.info(`skipping collection '${collection}'`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
73
86
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
);
|
|
81
|
-
};
|
|
87
|
+
await collectionObj.createIndex(
|
|
88
|
+
{ accountId: 1, jobId: 1 },
|
|
89
|
+
{ background: true },
|
|
90
|
+
);
|
|
91
|
+
console.info(`index '${indexName}' was created for collection '${collection}'`);
|
|
92
|
+
}
|
|
82
93
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
94
|
+
async function getUserInput(queryStr) {
|
|
95
|
+
const rl = readline.createInterface({
|
|
96
|
+
input: process.stdin,
|
|
97
|
+
output: process.stdout,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const questionAsync = query =>
|
|
101
|
+
new Promise(resolve => rl.question(query, resolve));
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
const userInput = (await questionAsync(queryStr)).toLowerCase();
|
|
105
|
+
|
|
106
|
+
switch (userInput) {
|
|
107
|
+
case 'yes':
|
|
108
|
+
case 'y':
|
|
109
|
+
return true;
|
|
110
|
+
case 'no':
|
|
111
|
+
case 'n':
|
|
112
|
+
return false;
|
|
113
|
+
default:
|
|
114
|
+
console.warn('invalid input');
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
} finally {
|
|
118
|
+
rl.close();
|
|
105
119
|
}
|
|
106
|
-
|
|
107
|
-
rl.close();
|
|
108
|
-
}
|
|
109
|
-
};
|
|
120
|
+
}
|
|
110
121
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return
|
|
115
|
-
})
|
|
116
|
-
return (collectionsList.indexOf(targetCollection) >= 0);
|
|
122
|
+
async function collectionExists(dbObject, targetCollection) {
|
|
123
|
+
const collectionsObjectList = await dbObject.listCollections().toArray();
|
|
124
|
+
const collectionsList = collectionsObjectList.map(object => object.name);
|
|
125
|
+
return (collectionsList.indexOf(targetCollection) >= 0);
|
|
117
126
|
}
|
|
118
127
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
async function findMinLog(collectionObj, UpperBoundDateId) {
|
|
129
|
+
const minLog = await collectionObj
|
|
130
|
+
.find({ _id: { $lt: ObjectId(UpperBoundDateId) } })
|
|
131
|
+
.sort({ _id: 1 })
|
|
132
|
+
.limit(1)
|
|
133
|
+
.toArray();
|
|
125
134
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
135
|
+
if (minLog.length === 0) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
129
138
|
|
|
130
|
-
|
|
139
|
+
return minLog[0];
|
|
131
140
|
}
|
|
132
141
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
"Cursor error. Archiving operation may not be completed.\
|
|
142
|
-
The old logs were not deleted from the source collection."
|
|
143
|
-
);
|
|
144
|
-
}
|
|
142
|
+
function checkCursorState(cursor, collection, targetCollection) {
|
|
143
|
+
if (!cursor.cursorState.killed) {
|
|
144
|
+
console.info(`logs from '${collection}' were archived to '${targetCollection}'`);
|
|
145
|
+
} else {
|
|
146
|
+
// eslint-disable-next-line no-multi-str
|
|
147
|
+
throw new Error('Cursor error. Archiving operation may not be completed.\
|
|
148
|
+
The old logs were not deleted from the source collection.');
|
|
149
|
+
}
|
|
145
150
|
}
|
|
146
151
|
|
|
147
152
|
module.exports = {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
153
|
+
objectIdFromDate,
|
|
154
|
+
writeLogsToFile,
|
|
155
|
+
checkRemnant,
|
|
156
|
+
ensureIndex,
|
|
157
|
+
getUserInput,
|
|
158
|
+
collectionExists,
|
|
159
|
+
findMinLog,
|
|
160
|
+
checkCursorState,
|
|
161
|
+
createRangeStr,
|
|
162
|
+
getMinDate,
|
|
163
|
+
defaultCollections,
|
|
159
164
|
};
|