Added capability to delete multiple apps

This commit is contained in:
Kasra Bigdeli
2024-04-28 12:07:56 -07:00
parent 1d6240811b
commit 147d03c8f7
4 changed files with 63 additions and 41 deletions

View File

@@ -1,5 +1,6 @@
## [Next Version - available as `edge`]
- New: Ability to delete multiple apps at once
- Improved: Now the redirects include the path
- Improved: SSH key handling to avoid human mistakes

View File

@@ -249,14 +249,24 @@ router.post('/delete/', function (req, res, next) {
const serviceManager =
InjectionExtractor.extractUserFromInjected(res).user.serviceManager
const appName = req.body.appName
const volumes = req.body.volumes || []
const appName: string = req.body.appName
const volumes: string[] = req.body.volumes || []
const appNames: string[] = req.body.appNames || []
const appsToDelete: string[] = appNames.length ? appNames : [appName]
Logger.d(`Deleting app started: ${appName}`)
Promise.resolve()
.then(function () {
return serviceManager.removeApp(appName)
if (appNames.length > 0 && appName) {
throw ApiStatusCodes.createError(
ApiStatusCodes.ILLEGAL_OPERATION,
'Either appName or appNames should be provided'
)
}
})
.then(function () {
return serviceManager.removeApps(appsToDelete)
})
.then(function () {
return Utils.getDelayedPromise(volumes.length ? 12000 : 0)
@@ -265,7 +275,7 @@ router.post('/delete/', function (req, res, next) {
return serviceManager.removeVolsSafe(volumes)
})
.then(function (failedVolsToRemoved) {
Logger.d(`AppName is deleted: ${appName}`)
Logger.d(`Successfully deleted: ${appsToDelete.join(', ')}`)
if (failedVolsToRemoved.length) {
const returnVal = new BaseApi(

View File

@@ -8,12 +8,12 @@ import Logger from '../utils/Logger'
import Utils from '../utils/Utils'
import Authenticator from './Authenticator'
import DockerRegistryHelper from './DockerRegistryHelper'
import ImageMaker, { BuildLogsManager } from './ImageMaker'
import { EventLogger } from './events/EventLogger'
import {
CapRoverEventFactory,
CapRoverEventType,
} from './events/ICapRoverEvent'
import ImageMaker, { BuildLogsManager } from './ImageMaker'
import DomainResolveChecker from './system/DomainResolveChecker'
import LoadBalancerManager from './system/LoadBalancerManager'
import requireFromString = require('require-from-string')
@@ -456,40 +456,51 @@ class ServiceManager {
})
}
removeApp(appName: string) {
Logger.d(`Removing service for: ${appName}`)
removeApps(appNames: string[]) {
Logger.d(`Removing service for: ${appNames.join(', ')}`)
const self = this
const serviceName = this.dataStore
.getAppsDataStore()
.getServiceName(appName)
const dockerApi = this.dockerApi
const dataStore = this.dataStore
const removeAppPromise = function (appName: string) {
const serviceName = self.dataStore
.getAppsDataStore()
.getServiceName(appName)
const dockerApi = self.dockerApi
const dataStore = self.dataStore
return Promise.resolve()
.then(function () {
return self.ensureNotBuilding(appName)
})
.then(function () {
Logger.d(`Check if service is running: ${serviceName}`)
return dockerApi.isServiceRunningByName(serviceName)
})
.then(function (isRunning) {
if (isRunning) {
return dockerApi.removeServiceByName(serviceName)
} else {
Logger.w(
`Cannot delete service... It is not running: ${serviceName}`
)
return true
}
})
.then(function () {
return dataStore.getAppsDataStore().deleteAppDefinition(appName)
})
.then(function () {
return self.reloadLoadBalancer()
})
return Promise.resolve()
.then(function () {
return self.ensureNotBuilding(appName)
})
.then(function () {
Logger.d(`Check if service is running: ${serviceName}`)
return dockerApi.isServiceRunningByName(serviceName)
})
.then(function (isRunning) {
if (isRunning) {
return dockerApi.removeServiceByName(serviceName)
} else {
Logger.w(
`Cannot delete service... It is not running: ${serviceName}`
)
return true
}
})
.then(function () {
return dataStore
.getAppsDataStore()
.deleteAppDefinition(appName)
})
.then(function () {
return self.reloadLoadBalancer()
})
}
const promises = []
for (const appName of appNames) {
promises.push(removeAppPromise(appName))
}
return Promise.all(promises)
}
removeVolsSafe(volumes: string[]) {

View File

@@ -89,14 +89,14 @@ class LoadBalancerManager {
consumeQueueIfAnyInNginxReloadQueue() {
const self = this
const q = self.requestedReloadPromises.pop()
if (!q) {
if (self.reloadInProcess) {
Logger.d('NGINX Reload already in process, Bouncing off...')
return
}
if (self.reloadInProcess) {
Logger.d('NGINX Reload already in process, Bouncing off...')
const q = self.requestedReloadPromises.pop()
if (!q) {
return
}