diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index a1158dc853918..793684c1b3796 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -115,8 +115,6 @@ The plugin integrates with the core system via lifecycle events: `setup` | [PluginConfigDescriptor](./kibana-plugin-core-server.pluginconfigdescriptor.md) | Describes a plugin configuration properties. | | [PluginInitializerContext](./kibana-plugin-core-server.plugininitializercontext.md) | Context that's available to plugins during initialization stage. | | [PluginManifest](./kibana-plugin-core-server.pluginmanifest.md) | Describes the set of required and optional properties plugin can define in its mandatory JSON manifest file. | -| [PluginsServiceSetup](./kibana-plugin-core-server.pluginsservicesetup.md) | | -| [PluginsServiceStart](./kibana-plugin-core-server.pluginsservicestart.md) | | | [RequestHandlerContext](./kibana-plugin-core-server.requesthandlercontext.md) | Plugin specific context passed to a route handler.Provides the following clients and services: - [rendering](./kibana-plugin-core-server.iscopedrenderingclient.md) - Rendering client which uses the data of the incoming request - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.dataClient](./kibana-plugin-core-server.scopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [elasticsearch.adminClient](./kibana-plugin-core-server.scopedclusterclient.md) - Elasticsearch admin client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request | | [RouteConfig](./kibana-plugin-core-server.routeconfig.md) | Route specific configuration. | | [RouteConfigOptions](./kibana-plugin-core-server.routeconfigoptions.md) | Additional route options. | diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginsservicesetup.contracts.md b/docs/development/core/server/kibana-plugin-core-server.pluginsservicesetup.contracts.md deleted file mode 100644 index 5e0543dbaa2d4..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.pluginsservicesetup.contracts.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [PluginsServiceSetup](./kibana-plugin-core-server.pluginsservicesetup.md) > [contracts](./kibana-plugin-core-server.pluginsservicesetup.contracts.md) - -## PluginsServiceSetup.contracts property - -Signature: - -```typescript -contracts: Map; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginsservicesetup.md b/docs/development/core/server/kibana-plugin-core-server.pluginsservicesetup.md deleted file mode 100644 index 5bfa65f36bda3..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.pluginsservicesetup.md +++ /dev/null @@ -1,20 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [PluginsServiceSetup](./kibana-plugin-core-server.pluginsservicesetup.md) - -## PluginsServiceSetup interface - - -Signature: - -```typescript -export interface PluginsServiceSetup -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [contracts](./kibana-plugin-core-server.pluginsservicesetup.contracts.md) | Map<PluginName, unknown> | | -| [uiPlugins](./kibana-plugin-core-server.pluginsservicesetup.uiplugins.md) | {
internal: Map<PluginName, InternalPluginInfo>;
public: Map<PluginName, DiscoveredPlugin>;
browserConfigs: Map<PluginName, Observable<unknown>>;
} | | - diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginsservicesetup.uiplugins.md b/docs/development/core/server/kibana-plugin-core-server.pluginsservicesetup.uiplugins.md deleted file mode 100644 index 7168a360c244d..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.pluginsservicesetup.uiplugins.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [PluginsServiceSetup](./kibana-plugin-core-server.pluginsservicesetup.md) > [uiPlugins](./kibana-plugin-core-server.pluginsservicesetup.uiplugins.md) - -## PluginsServiceSetup.uiPlugins property - -Signature: - -```typescript -uiPlugins: { - internal: Map; - public: Map; - browserConfigs: Map>; - }; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginsservicestart.contracts.md b/docs/development/core/server/kibana-plugin-core-server.pluginsservicestart.contracts.md deleted file mode 100644 index 5c680d9d2d504..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.pluginsservicestart.contracts.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [PluginsServiceStart](./kibana-plugin-core-server.pluginsservicestart.md) > [contracts](./kibana-plugin-core-server.pluginsservicestart.contracts.md) - -## PluginsServiceStart.contracts property - -Signature: - -```typescript -contracts: Map; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.pluginsservicestart.md b/docs/development/core/server/kibana-plugin-core-server.pluginsservicestart.md deleted file mode 100644 index cb450ded47c5b..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.pluginsservicestart.md +++ /dev/null @@ -1,19 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [PluginsServiceStart](./kibana-plugin-core-server.pluginsservicestart.md) - -## PluginsServiceStart interface - - -Signature: - -```typescript -export interface PluginsServiceStart -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [contracts](./kibana-plugin-core-server.pluginsservicestart.contracts.md) | Map<PluginName, unknown> | | - diff --git a/src/core/server/legacy/legacy_service.test.ts b/src/core/server/legacy/legacy_service.test.ts index 94e86c39289bc..ef31be559b30b 100644 --- a/src/core/server/legacy/legacy_service.test.ts +++ b/src/core/server/legacy/legacy_service.test.ts @@ -87,6 +87,7 @@ beforeEach(() => { }, savedObjects: savedObjectsServiceMock.createInternalSetupContract(), plugins: { + initialized: true, contracts: new Map([['plugin-id', 'plugin-value']]), uiPlugins: { public: new Map([['plugin-id', {} as DiscoveredPlugin]]), diff --git a/src/core/server/plugins/plugins_service.mock.ts b/src/core/server/plugins/plugins_service.mock.ts index 5a52ebccbd472..29e5b83b2e4c7 100644 --- a/src/core/server/plugins/plugins_service.mock.ts +++ b/src/core/server/plugins/plugins_service.mock.ts @@ -28,6 +28,7 @@ const createSetupContractMock = (): PluginsServiceSetup => ({ internal: new Map(), public: new Map(), }, + initialized: true, }); const createStartContractMock = () => ({ contracts: new Map() }); const createServiceMock = (): PluginsServiceMock => ({ diff --git a/src/core/server/plugins/plugins_service.test.ts b/src/core/server/plugins/plugins_service.test.ts index df618b2c0a706..4f69a2b4156be 100644 --- a/src/core/server/plugins/plugins_service.test.ts +++ b/src/core/server/plugins/plugins_service.test.ts @@ -516,28 +516,29 @@ describe('PluginsService', () => { }); describe('#setup()', () => { - describe('uiPlugins.internal', () => { - it('includes disabled plugins', async () => { - mockDiscover.mockReturnValue({ - error$: from([]), - plugin$: from([ - createPlugin('plugin-1', { - path: 'path-1', - version: 'some-version', - configPath: 'plugin1', - }), - createPlugin('plugin-2', { - path: 'path-2', - version: 'some-version', - configPath: 'plugin2', - }), - ]), - }); + beforeEach(() => { + mockDiscover.mockReturnValue({ + error$: from([]), + plugin$: from([ + createPlugin('plugin-1', { + path: 'path-1', + version: 'some-version', + configPath: 'plugin1', + }), + createPlugin('plugin-2', { + path: 'path-2', + version: 'some-version', + configPath: 'plugin2', + }), + ]), + }); - mockPluginSystem.uiPlugins.mockReturnValue(new Map()); + mockPluginSystem.uiPlugins.mockReturnValue(new Map()); + }); + describe('uiPlugins.internal', () => { + it('includes disabled plugins', async () => { config$.next({ plugins: { initialize: true }, plugin1: { enabled: false } }); - await pluginsService.discover(); const { uiPlugins } = await pluginsService.setup({} as any); expect(uiPlugins.internal).toMatchInlineSnapshot(` @@ -552,6 +553,24 @@ describe('PluginsService', () => { `); }); }); + + describe('plugin initialization', () => { + it('does initialize if plugins.initialize is true', async () => { + config$.next({ plugins: { initialize: true } }); + await pluginsService.discover(); + const { initialized } = await pluginsService.setup({} as any); + expect(mockPluginSystem.setupPlugins).toHaveBeenCalled(); + expect(initialized).toBe(true); + }); + + it('does not initialize if plugins.initialize is false', async () => { + config$.next({ plugins: { initialize: false } }); + await pluginsService.discover(); + const { initialized } = await pluginsService.setup({} as any); + expect(mockPluginSystem.setupPlugins).not.toHaveBeenCalled(); + expect(initialized).toBe(false); + }); + }); }); describe('#stop()', () => { diff --git a/src/core/server/plugins/plugins_service.ts b/src/core/server/plugins/plugins_service.ts index 427cc19a8614f..9987d1633c502 100644 --- a/src/core/server/plugins/plugins_service.ts +++ b/src/core/server/plugins/plugins_service.ts @@ -33,8 +33,11 @@ import { InternalCoreSetup, InternalCoreStart } from '../internal_types'; import { IConfigService } from '../config'; import { pick } from '../../utils'; -/** @public */ +/** @internal */ export interface PluginsServiceSetup { + /** Indicates whether or not plugins were initialized. */ + initialized: boolean; + /** Setup contracts returned by plugins. */ contracts: Map; uiPlugins: { /** @@ -55,8 +58,9 @@ export interface PluginsServiceSetup { }; } -/** @public */ +/** @internal */ export interface PluginsServiceStart { + /** Start contracts returned by plugins. */ contracts: Map; } @@ -103,14 +107,16 @@ export class PluginsService implements CoreService(); - if (!config.initialize || this.coreContext.env.isDevClusterMaster) { - this.log.info('Plugin initialization disabled.'); - } else { + const initialize = config.initialize && !this.coreContext.env.isDevClusterMaster; + if (initialize) { contracts = await this.pluginsSystem.setupPlugins(deps); + } else { + this.log.info('Plugin initialization disabled.'); } const uiPlugins = this.pluginsSystem.uiPlugins(); return { + initialized: initialize, contracts, uiPlugins: { internal: this.uiPluginInternalInfo, diff --git a/src/core/server/saved_objects/saved_objects_service.test.ts b/src/core/server/saved_objects/saved_objects_service.test.ts index 58b9abfbcdb3a..018117776dcc8 100644 --- a/src/core/server/saved_objects/saved_objects_service.test.ts +++ b/src/core/server/saved_objects/saved_objects_service.test.ts @@ -171,14 +171,12 @@ describe('SavedObjectsService', () => { return expect(KibanaMigratorMock.mock.calls[0][0].callCluster()).resolves.toMatch('success'); }); - it('skips KibanaMigrator migrations when --optimize=true', async () => { - const coreContext = createCoreContext({ - env: ({ cliArgs: { optimize: true }, packageInfo: { version: 'x.x.x' } } as unknown) as Env, - }); + it('skips KibanaMigrator migrations when pluginsInitialized=false', async () => { + const coreContext = createCoreContext({ skipMigration: false }); const soService = new SavedObjectsService(coreContext); await soService.setup(createSetupDeps()); - await soService.start({}); + await soService.start({ pluginsInitialized: false }); expect(migratorInstanceMock.runMigrations).not.toHaveBeenCalled(); }); diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index 175eac3c1bd95..aa440c6454569 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -269,7 +269,9 @@ interface WrappedClientFactoryWrapper { /** @internal */ // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface SavedObjectsStartDeps {} +export interface SavedObjectsStartDeps { + pluginsInitialized?: boolean; +} export class SavedObjectsService implements CoreService { @@ -349,7 +351,7 @@ export class SavedObjectsService } public async start( - core: SavedObjectsStartDeps, + { pluginsInitialized = true }: SavedObjectsStartDeps, migrationsRetryDelay?: number ): Promise { if (!this.setupDeps || !this.config) { @@ -376,9 +378,11 @@ export class SavedObjectsService * However, our build system optimize step and some tests depend on the * HTTP server running without an Elasticsearch server being available. * So, when the `migrations.skip` is true, we skip migrations altogether. + * + * We also cannot safely run migrations if plugins are not initialized since + * not plugin migrations won't be registered. */ - const cliArgs = this.coreContext.env.cliArgs; - const skipMigrations = cliArgs.optimize || this.config.migration.skip; + const skipMigrations = this.config.migration.skip || !pluginsInitialized; if (skipMigrations) { this.logger.warn( diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 6d4181e5e1ab3..232d34e484382 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1426,10 +1426,10 @@ export type PluginName = string; // @public (undocumented) export type PluginOpaqueId = symbol; -// @public (undocumented) +// @internal (undocumented) export interface PluginsServiceSetup { - // (undocumented) contracts: Map; + initialized: boolean; // (undocumented) uiPlugins: { internal: Map; @@ -1438,9 +1438,8 @@ export interface PluginsServiceSetup { }; } -// @public (undocumented) +// @internal (undocumented) export interface PluginsServiceStart { - // (undocumented) contracts: Map; } @@ -2348,7 +2347,7 @@ export const validBodyOutput: readonly ["data", "stream"]; // src/core/server/legacy/types.ts:164:3 - (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts // src/core/server/legacy/types.ts:165:3 - (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts // src/core/server/legacy/types.ts:166:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts -// src/core/server/plugins/plugins_service.ts:44:5 - (ae-forgotten-export) The symbol "InternalPluginInfo" needs to be exported by the entry point index.d.ts +// src/core/server/plugins/plugins_service.ts:47:5 - (ae-forgotten-export) The symbol "InternalPluginInfo" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:226:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:226:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:228:3 - (ae-forgotten-export) The symbol "PathConfigType" needs to be exported by the entry point index.d.ts diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 09a1328f346d8..222be572b75e4 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -72,6 +72,7 @@ export class Server { private readonly metrics: MetricsService; private readonly coreApp: CoreApp; + private pluginsInitialized?: boolean; private coreStart?: InternalCoreStart; constructor( @@ -156,6 +157,7 @@ export class Server { }; const pluginsSetup = await this.plugins.setup(coreSetup); + this.pluginsInitialized = pluginsSetup.initialized; const renderingSetup = await this.rendering.setup({ http: httpSetup, @@ -176,7 +178,9 @@ export class Server { public async start() { this.log.debug('starting server'); - const savedObjectsStart = await this.savedObjects.start({}); + const savedObjectsStart = await this.savedObjects.start({ + pluginsInitialized: this.pluginsInitialized, + }); const capabilitiesStart = this.capabilities.start(); const uiSettingsStart = await this.uiSettings.start(); const elasticsearchStart = await this.elasticsearch.start();