Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.11] fix/142865/path.data config unused (#158426) #172200

Merged
merged 1 commit into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/setup/settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,9 @@ or `*` to select all roles. *Default: `*`*
Choose the default email connector for user notifications. As of `8.6.0`, {kib} is shipping with a new notification mechanism that will send email notifications for various user actions, e.g. assigning a _Case_ to a user. To enable notifications, an email connector must be <<pre-configured-connectors,preconfigured>> in the system via `kibana.yml`, and the notifications plugin must be configured to point to the ID of that connector.

[[path-data]] `path.data`::
The path where {kib} stores persistent data
not saved in {es}. *Default: `data`*
The path where {kib} stores persistent data not saved in {es}.
Can be a relative or absolute path.
Relative paths are resolved starting from the installation directory. *Default: `data`*

`pid.file`::
Specifies the path where {kib} creates the process ID file.
Expand Down
98 changes: 97 additions & 1 deletion packages/kbn-utils/src/path/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
* Side Public License, v 1.
*/

import { join } from 'path';
import { accessSync, constants } from 'fs';
import { getConfigPath, getDataPath, getLogsPath, getConfigDirectory } from '.';
import { rm, mkdtemp, writeFile } from 'fs/promises';
import { getConfigPath, getDataPath, getLogsPath, getConfigDirectory, buildDataPaths } from '.';
import { REPO_ROOT } from '@kbn/repo-info';

expect.addSnapshotSerializer(
Expand Down Expand Up @@ -46,3 +48,97 @@ describe('Default path finder', () => {
expect(() => accessSync(configPath, constants.R_OK)).not.toThrow();
});
});

describe('Custom data path finder', () => {
const originalArgv = process.argv;

beforeEach(() => {
process.argv = originalArgv;
});

it('ignores the path.data flag when no value is provided', () => {
process.argv = ['--foo', 'bar', '--path.data', '--baz', 'xyz'];

expect(buildDataPaths()).toMatchInlineSnapshot(`
Array [
<absolute path>/data,
"/var/lib/kibana",
]
`);
});

describe('overrides path.data when provided as command line argument', () => {
it('with absolute path', () => {
process.argv = ['--foo', 'bar', '--path.data', '/some/data/path', '--baz', 'xyz'];

/*
* Test buildDataPaths since getDataPath returns the first valid directory and
* custom paths do not exist in environment. Custom directories are built during env init.
*/
expect(buildDataPaths()).toMatchInlineSnapshot(`
Array [
"/some/data/path",
<absolute path>/data,
"/var/lib/kibana",
]
`);
});

it('with relative path', () => {
process.argv = ['--foo', 'bar', '--path.data', 'data2', '--baz', 'xyz'];

/*
* Test buildDataPaths since getDataPath returns the first valid directory and
* custom paths do not exist in environment. Custom directories are built during env init.
*/
expect(buildDataPaths()).toMatchInlineSnapshot(`
Array [
<absolute path>/data2,
<absolute path>/data,
"/var/lib/kibana",
]
`);
});
});

describe('overrides path.data when provided by kibana.yml', () => {
let tempDir: string;
let tempConfigFile: string;

beforeAll(async () => {
tempDir = await mkdtemp('config-test');
tempConfigFile = join(tempDir, 'kibana.yml');
});

afterAll(async () => {
await rm(tempDir, { recursive: true });
delete process.env.KBN_PATH_CONF;
});

it('with absolute path', async () => {
process.env.KBN_PATH_CONF = tempDir;
await writeFile(tempConfigFile, `path.data: /path/from/yml`);

expect(buildDataPaths()).toMatchInlineSnapshot(`
Array [
"/path/from/yml",
<absolute path>/data,
"/var/lib/kibana",
]
`);
});

it('with relative path', async () => {
process.env.KBN_PATH_CONF = tempDir;
await writeFile(tempConfigFile, `path.data: data2`);

expect(buildDataPaths()).toMatchInlineSnapshot(`
Array [
<absolute path>/data2,
<absolute path>/data,
"/var/lib/kibana",
]
`);
});
});
});
40 changes: 30 additions & 10 deletions packages/kbn-utils/src/path/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,29 @@
* Side Public License, v 1.
*/

import { join } from 'path';
import { join, resolve } from 'path';
import { accessSync, constants } from 'fs';
import { TypeOf, schema } from '@kbn/config-schema';
import { REPO_ROOT } from '@kbn/repo-info';
import { getConfigFromFiles } from '@kbn/config';
import getopts from 'getopts';

const isString = (v: any): v is string => typeof v === 'string';

const CONFIG_PATHS = [
process.env.KBN_PATH_CONF && join(process.env.KBN_PATH_CONF, 'kibana.yml'),
join(REPO_ROOT, 'config/kibana.yml'),
'/etc/kibana/kibana.yml',
].filter(isString);
const buildConfigPaths = () => {
return [
process.env.KBN_PATH_CONF && resolve(process.env.KBN_PATH_CONF, 'kibana.yml'),
join(REPO_ROOT, 'config/kibana.yml'),
'/etc/kibana/kibana.yml',
].filter(isString);
};

const CONFIG_DIRECTORIES = [
process.env.KBN_PATH_CONF,
join(REPO_ROOT, 'config'),
'/etc/kibana',
].filter(isString);

const DATA_PATHS = [join(REPO_ROOT, 'data'), '/var/lib/kibana'].filter(isString);

const LOGS_PATHS = [join(REPO_ROOT, 'logs'), '/var/log/kibana'].filter(isString);

function findFile(paths: string[]) {
Expand All @@ -41,11 +43,29 @@ function findFile(paths: string[]) {
return availablePath || paths[0];
}

export const buildDataPaths = (): string[] => {
const configDataPath = getConfigFromFiles([getConfigPath()]).path?.data;
const argv = process.argv.slice(2);
const options = getopts(argv, {
string: ['pathData'],
alias: {
pathData: 'path.data',
},
});

return [
!!options.pathData && resolve(REPO_ROOT, options.pathData),
configDataPath && resolve(REPO_ROOT, configDataPath),
join(REPO_ROOT, 'data'),
'/var/lib/kibana',
].filter(isString);
};

/**
* Get the path of kibana.yml
* @internal
*/
export const getConfigPath = () => findFile(CONFIG_PATHS);
export const getConfigPath = () => findFile(buildConfigPaths());

/**
* Get the directory containing configuration files
Expand All @@ -57,7 +77,7 @@ export const getConfigDirectory = () => findFile(CONFIG_DIRECTORIES);
* Get the directory containing runtime data
* @internal
*/
export const getDataPath = () => findFile(DATA_PATHS);
export const getDataPath = () => findFile(buildDataPaths());

/**
* Get the directory containing logs
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-utils/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"kbn_references": [
"@kbn/config-schema",
"@kbn/repo-info",
"@kbn/config",
],
"exclude": [
"target/**/*",
Expand Down
Loading