44 * you may not use this file except in compliance with the Elastic License.
55 */
66
7- import { SavedObjectsClientContract } from 'src/core/server' ;
7+ import { SavedObject , SavedObjectsClientContract } from 'src/core/server' ;
88import semver from 'semver' ;
99import { PACKAGES_SAVED_OBJECT_TYPE , MAX_TIME_COMPLETE_INSTALL } from '../../../constants' ;
1010import {
@@ -16,6 +16,7 @@ import {
1616 KibanaAssetReference ,
1717 EsAssetReference ,
1818 ElasticsearchAssetType ,
19+ InstallType ,
1920} from '../../../types' ;
2021import { installIndexPatterns } from '../kibana/index_pattern/install' ;
2122import * as Registry from '../registry' ;
@@ -110,11 +111,13 @@ export async function installPackage({
110111 const latestPackage = await Registry . fetchFindLatestPackage ( pkgName ) ;
111112 // get the currently installed package
112113 const installedPkg = await getInstallationObject ( { savedObjectsClient, pkgName } ) ;
113- const reinstall = pkgVersion === installedPkg ?. attributes . version ;
114- const reupdate = pkgVersion === installedPkg ?. attributes . install_version ;
115114
116- // let the user install if using the force flag or this is a reinstall or reupdate due to intallation interruption
117- if ( semver . lt ( pkgVersion , latestPackage . version ) && ! force && ! reinstall && ! reupdate ) {
115+ const installType = getInstallType ( { pkgVersion, installedPkg } ) ;
116+
117+ // let the user install if using the force flag or needing to reinstall or install a previous version due to failed update
118+ const installOutOfDateVersionOk =
119+ installType === 'reinstall' || installType === 'reupdate' || installType === 'rollback' ;
120+ if ( semver . lt ( pkgVersion , latestPackage . version ) && ! force && ! installOutOfDateVersionOk ) {
118121 throw new PackageOutdatedError ( `${ pkgkey } is out-of-date and cannot be installed or updated` ) ;
119122 }
120123 const paths = await Registry . getArchiveInfo ( pkgName , pkgVersion ) ;
@@ -188,16 +191,26 @@ export async function installPackage({
188191 // update current backing indices of each data stream
189192 await updateCurrentWriteIndices ( callCluster , installedTemplates ) ;
190193
191- // if this is an update, delete the previous version's pipelines
192- if ( installedPkg && ! reinstall ) {
194+ // if this is an update or retrying an update , delete the previous version's pipelines
195+ if ( installType === 'update' || installType === 'reupdate' ) {
193196 await deletePreviousPipelines (
194197 callCluster ,
195198 savedObjectsClient ,
196199 pkgName ,
200+ // @ts -ignore installType conditions already check for existence of installedPkg
197201 installedPkg . attributes . version
198202 ) ;
199203 }
200-
204+ // pipelines from a different version may have installed during a failed update
205+ if ( installType === 'rollback' ) {
206+ await deletePreviousPipelines (
207+ callCluster ,
208+ savedObjectsClient ,
209+ pkgName ,
210+ // @ts -ignore installType conditions already check for existence of installedPkg
211+ installedPkg . attributes . install_version
212+ ) ;
213+ }
201214 const installedTemplateRefs = installedTemplates . map ( ( template ) => ( {
202215 id : template . templateName ,
203216 type : ElasticsearchAssetType . indexTemplate ,
@@ -326,3 +339,23 @@ export async function ensurePackagesCompletedInstall(
326339 await Promise . all ( installingPromises ) ;
327340 return installingPackages ;
328341}
342+
343+ export function getInstallType ( {
344+ pkgVersion,
345+ installedPkg,
346+ } : {
347+ pkgVersion : string ;
348+ installedPkg : SavedObject < Installation > | undefined ;
349+ } ) : InstallType {
350+ const isInstalledPkg = ! ! installedPkg ;
351+ const currentPkgVersion = installedPkg ?. attributes . version ;
352+ const lastStartedInstallVersion = installedPkg ?. attributes . install_version ;
353+ if ( ! isInstalledPkg ) return 'install' ;
354+ if ( pkgVersion === currentPkgVersion && pkgVersion !== lastStartedInstallVersion )
355+ return 'rollback' ;
356+ if ( pkgVersion === currentPkgVersion ) return 'reinstall' ;
357+ if ( pkgVersion === lastStartedInstallVersion && pkgVersion !== currentPkgVersion )
358+ return 'reupdate' ;
359+ if ( pkgVersion !== lastStartedInstallVersion && pkgVersion !== currentPkgVersion ) return 'update' ;
360+ throw new Error ( 'unknown install type' ) ;
361+ }
0 commit comments