Skip to content

Commit 517ad89

Browse files
Merge branch '7.x' into backport/7.x/pr-65375
2 parents 77b1343 + c1e699d commit 517ad89

File tree

121 files changed

+1376
-778
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+1376
-778
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import Path from 'path';
21+
import { chmod, writeFile } from 'fs';
22+
import { promisify } from 'util';
23+
24+
import { run } from '../run';
25+
import { REPO_ROOT } from '../repo_root';
26+
import { SCRIPT_SOURCE } from './script_source';
27+
import { getGitDir } from './get_git_dir';
28+
29+
const chmodAsync = promisify(chmod);
30+
const writeFileAsync = promisify(writeFile);
31+
32+
run(
33+
async ({ log }) => {
34+
try {
35+
const gitDir = await getGitDir();
36+
const installPath = Path.resolve(REPO_ROOT, gitDir, 'hooks/pre-commit');
37+
38+
log.info(`Registering Kibana pre-commit git hook...`);
39+
await writeFileAsync(installPath, SCRIPT_SOURCE);
40+
await chmodAsync(installPath, 0o755);
41+
log.success(`Kibana pre-commit git hook was installed successfully.`);
42+
} catch (e) {
43+
log.error(`Kibana pre-commit git hook was not installed as an error occur.`);
44+
throw e;
45+
}
46+
},
47+
{
48+
description: 'Register git hooks in the local repo',
49+
}
50+
);

src/dev/register_git_hook/index.js renamed to packages/kbn-dev-utils/src/precommit_hook/get_git_dir.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,16 @@
1717
* under the License.
1818
*/
1919

20-
export { registerPrecommitGitHook } from './register_git_hook';
20+
import execa from 'execa';
21+
22+
import { REPO_ROOT } from '../repo_root';
23+
24+
// Retrieves the correct location for the .git dir for
25+
// every git setup (including git worktree)
26+
export async function getGitDir() {
27+
return (
28+
await execa('git', ['rev-parse', '--git-common-dir'], {
29+
cwd: REPO_ROOT,
30+
})
31+
).stdout.trim();
32+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import os from 'os';
21+
22+
import normalizePath from 'normalize-path';
23+
24+
const HOME_DIR = normalizePath(os.homedir());
25+
26+
export const SCRIPT_SOURCE = `#!/usr/bin/env bash
27+
#
28+
# ** THIS IS AN AUTO-GENERATED FILE **
29+
# ** PLEASE DO NOT CHANGE IT MANUALLY **
30+
#
31+
# GENERATED BY \`node scripts/register_git_hook\`
32+
# IF YOU WANNA CHANGE SOMETHING IN THIS SCRIPT
33+
# PLEASE RE-RUN 'yarn kbn bootstrap' or 'node scripts/register_git_hook'
34+
35+
# pre-commit script takes zero arguments: https://git-scm.com/docs/githooks#_pre_commit
36+
37+
set -euo pipefail
38+
39+
# Make it possible to terminate pre commit hook
40+
# using ctrl-c so nothing else would happen or be
41+
# sent to the output.
42+
#
43+
# The correct exit code on that situation
44+
# according the linux documentation project is 130
45+
# https://www.tldp.org/LDP/abs/html/exitcodes.html
46+
trap "exit 130" INT
47+
48+
has_node() {
49+
command -v node >/dev/null 2>&1
50+
}
51+
52+
has_nvm() {
53+
command -v nvm >/dev/null 2>&1
54+
}
55+
56+
try_load_node_from_nvm_paths () {
57+
# If nvm is not loaded, load it
58+
has_node || {
59+
NVM_SH="${HOME_DIR}/.nvm/nvm.sh"
60+
61+
if [ "${process.platform}" == "darwin" ] && [ -s "$(brew --prefix nvm)/nvm.sh" ]; then
62+
NVM_SH="$(brew --prefix nvm)/nvm.sh"
63+
fi
64+
65+
export NVM_DIR="${HOME_DIR}/.nvm"
66+
67+
[ -s "$NVM_SH" ] && \. "$NVM_SH"
68+
69+
# If nvm has been loaded correctly, use project .nvmrc
70+
has_nvm && nvm use
71+
}
72+
}
73+
74+
extend_user_path() {
75+
if [ "${process.platform}" == "win32" ]; then
76+
export PATH="$PATH:/c/Program Files/nodejs"
77+
else
78+
export PATH="$PATH:/usr/local/bin:/usr/local"
79+
try_load_node_from_nvm_paths
80+
fi
81+
}
82+
83+
# Extend path with common path locations for node
84+
# in order to make the hook working on git GUI apps
85+
extend_user_path
86+
87+
# Check if we have node js bin in path
88+
has_node || {
89+
echo "Can't found node bin in the PATH. Please update the PATH to proceed."
90+
echo "If your PATH already has the node bin, maybe you are using some git GUI app."
91+
echo "Can't found node bin in the PATH. Please update the PATH to proceed."
92+
echo "If your PATH already has the node bin, maybe you are using some git GUI app not launched from the shell."
93+
echo "In order to proceed, you need to config the PATH used by the application that are launching your git GUI app."
94+
echo "If you are running macOS, you can do that using:"
95+
echo "'sudo launchctl config user path /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'"
96+
97+
exit 1
98+
}
99+
100+
execute_precommit_hook() {
101+
node scripts/precommit_hook || return 1
102+
103+
PRECOMMIT_FILE="./.git/hooks/pre-commit.local"
104+
if [ -x "\${PRECOMMIT_FILE}" ]; then
105+
echo "Executing local precommit hook found in \${PRECOMMIT_FILE}"
106+
"$PRECOMMIT_FILE" || return 1
107+
fi
108+
}
109+
110+
execute_precommit_hook || {
111+
echo "Pre-commit hook failed (add --no-verify to bypass)";
112+
echo ' For eslint failures you can try running \`node scripts/precommit_hook --fix\`';
113+
exit 1;
114+
}
115+
116+
exit 0
117+
`;

packages/kbn-optimizer/src/worker/webpack.config.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ export function getWebpackConfig(bundle: Bundle, worker: WorkerConfig) {
135135
// or which have require() statements that should be ignored because the file is
136136
// already bundled with all its necessary depedencies
137137
noParse: [
138-
/[\///]node_modules[\///]elasticsearch-browser[\///]/,
139-
/[\///]node_modules[\///]lodash[\///]index\.js$/,
140-
/[\///]node_modules[\///]vega-lib[\///]build[\///]vega\.js$/,
138+
/[\/\\]node_modules[\/\\]elasticsearch-browser[\/\\]/,
139+
/[\/\\]node_modules[\/\\]lodash[\/\\]index\.js$/,
140+
/[\/\\]node_modules[\/\\]vega-lib[\/\\]build[\/\\]vega\.js$/,
141141
],
142142

143143
rules: [

scripts/register_git_hook.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717
* under the License.
1818
*/
1919

20-
require('../src/setup_node_env');
21-
require('../src/dev/run_register_git_hook');
20+
require('../src/setup_node_env/prebuilt_dev_only_entry');
21+
require('@kbn/dev-utils/target/precommit_hook/cli');

src/core/server/saved_objects/service/lib/repository.test.js

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { SavedObjectsErrorHelpers } from './errors';
2323
import { SavedObjectsSerializer } from '../../serialization';
2424
import { encodeHitVersion } from '../../version';
2525
import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry';
26+
import { DocumentMigrator } from '../../migrations/core/document_migrator';
2627

2728
jest.mock('./search_dsl/search_dsl', () => ({ getSearchDsl: jest.fn() }));
2829

@@ -115,6 +116,7 @@ describe('SavedObjectsRepository', () => {
115116
const createType = type => ({
116117
name: type,
117118
mappings: { properties: mappings.properties[type].properties },
119+
migrations: { '1.1.1': doc => doc },
118120
});
119121

120122
const registry = new SavedObjectTypeRegistry();
@@ -144,6 +146,13 @@ describe('SavedObjectsRepository', () => {
144146
namespaceType: 'agnostic',
145147
});
146148

149+
const documentMigrator = new DocumentMigrator({
150+
typeRegistry: registry,
151+
kibanaVersion: '2.0.0',
152+
log: {},
153+
validateDoc: jest.fn(),
154+
});
155+
147156
const getMockGetResponse = ({ type, id, references, namespace }) => ({
148157
// NOTE: Elasticsearch returns more fields (_index, _type) but the SavedObjectsRepository method ignores these
149158
found: true,
@@ -207,7 +216,7 @@ describe('SavedObjectsRepository', () => {
207216
beforeEach(() => {
208217
callAdminCluster = jest.fn();
209218
migrator = {
210-
migrateDocument: jest.fn(doc => doc),
219+
migrateDocument: jest.fn().mockImplementation(documentMigrator.migrate),
211220
runMigrations: async () => ({ status: 'skipped' }),
212221
};
213222

@@ -424,9 +433,17 @@ describe('SavedObjectsRepository', () => {
424433

425434
const getMockBulkCreateResponse = (objects, namespace) => {
426435
return {
427-
items: objects.map(({ type, id }) => ({
436+
items: objects.map(({ type, id, attributes, references, migrationVersion }) => ({
428437
create: {
429438
_id: `${namespace ? `${namespace}:` : ''}${type}:${id}`,
439+
_source: {
440+
[type]: attributes,
441+
type,
442+
namespace,
443+
references,
444+
...mockTimestampFields,
445+
migrationVersion: migrationVersion || { [type]: '1.1.1' },
446+
},
430447
...mockVersionProps,
431448
},
432449
})),
@@ -474,7 +491,7 @@ describe('SavedObjectsRepository', () => {
474491

475492
const expectSuccessResult = obj => ({
476493
...obj,
477-
migrationVersion: undefined,
494+
migrationVersion: { [obj.type]: '1.1.1' },
478495
version: mockVersion,
479496
...mockTimestampFields,
480497
});
@@ -619,13 +636,16 @@ describe('SavedObjectsRepository', () => {
619636
};
620637

621638
const bulkCreateError = async (obj, esError, expectedError) => {
622-
const objects = [obj1, obj, obj2];
623-
const response = getMockBulkCreateResponse(objects);
639+
let response;
624640
if (esError) {
641+
response = getMockBulkCreateResponse([obj1, obj, obj2]);
625642
response.items[1].create = { error: esError };
643+
} else {
644+
response = getMockBulkCreateResponse([obj1, obj2]);
626645
}
627646
callAdminCluster.mockResolvedValue(response); // this._writeToCluster('bulk', ...)
628647

648+
const objects = [obj1, obj, obj2];
629649
const result = await savedObjectsRepository.bulkCreate(objects);
630650
expectClusterCalls('bulk');
631651
const objCall = esError ? expectObjArgs(obj) : [];
@@ -781,14 +801,40 @@ describe('SavedObjectsRepository', () => {
781801
id: 'three',
782802
};
783803
const objects = [obj1, obj, obj2];
784-
const response = getMockBulkCreateResponse(objects);
804+
const response = getMockBulkCreateResponse([obj1, obj2]);
785805
callAdminCluster.mockResolvedValue(response); // this._writeToCluster('bulk', ...)
786806
const result = await savedObjectsRepository.bulkCreate(objects);
787807
expect(callAdminCluster).toHaveBeenCalledTimes(1);
788808
expect(result).toEqual({
789809
saved_objects: [expectSuccessResult(obj1), expectError(obj), expectSuccessResult(obj2)],
790810
});
791811
});
812+
813+
it(`a deserialized saved object`, async () => {
814+
// Test for fix to https://github.com/elastic/kibana/issues/65088 where
815+
// we returned raw ID's when an object without an id was created.
816+
const namespace = 'myspace';
817+
const response = getMockBulkCreateResponse([obj1, obj2], namespace);
818+
callAdminCluster.mockResolvedValueOnce(response); // this._writeToCluster('bulk', ...)
819+
820+
// Bulk create one object with id unspecified, and one with id specified
821+
const result = await savedObjectsRepository.bulkCreate([{ ...obj1, id: undefined }, obj2], {
822+
namespace,
823+
});
824+
825+
// Assert that both raw docs from the ES response are deserialized
826+
expect(serializer.rawToSavedObject).toHaveBeenNthCalledWith(1, {
827+
...response.items[0].create,
828+
_id: expect.stringMatching(/^myspace:config:[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/),
829+
});
830+
expect(serializer.rawToSavedObject).toHaveBeenNthCalledWith(2, response.items[1].create);
831+
832+
// Assert that ID's are deserialized to remove the type and namespace
833+
expect(result.saved_objects[0].id).toEqual(
834+
expect.stringMatching(/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/)
835+
);
836+
expect(result.saved_objects[1].id).toEqual(obj2.id);
837+
});
792838
});
793839
});
794840

@@ -1604,6 +1650,7 @@ describe('SavedObjectsRepository', () => {
16041650
version: mockVersion,
16051651
attributes,
16061652
references,
1653+
migrationVersion: { [type]: '1.1.1' },
16071654
});
16081655
});
16091656
});

0 commit comments

Comments
 (0)