Skip to content

Commit

Permalink
introduce error status and pkg rebuild and fix mocks
Browse files Browse the repository at this point in the history
  • Loading branch information
MattDHill committed Sep 26, 2024
1 parent e49854d commit 93156dc
Show file tree
Hide file tree
Showing 16 changed files with 351 additions and 234 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,19 @@
<ion-item-group *ngIf="pkg$ | async as pkg">
<!-- ** standard actions ** -->
<ion-item-divider>Standard Actions</ion-item-divider>
<app-actions-item
[action]="{
name: 'Rebuild Service',
description: 'Rebuilds the service container. It is harmless and only takes a few seconds to complete, but it should only be necessary if a StartOS bug is preventing dependencies, interfaces, or actions from synchronizing.',
visibility: 'enabled'
}"
icon="construct-outline"
(click)="rebuild(pkg.manifest.id)"
></app-actions-item>
<app-actions-item
[action]="{
name: 'Uninstall',
description: 'This will uninstall the service from StartOS and delete all data permanently.',
description: 'Uninstalls this service from StartOS and delete all data permanently.',
visibility: 'enabled'
}"
icon="trash-outline"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { AlertController, NavController } from '@ionic/angular'
import { ErrorService, getPkgId, LoadingService } from '@start9labs/shared'
import { getPkgId } from '@start9labs/shared'
import { T } from '@start9labs/start-sdk'
import { PatchDB } from 'patch-db-client'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ActionService } from 'src/app/services/action.service'
import { StandardActionsService } from 'src/app/services/standard-actions.service'
import { DataModel } from 'src/app/services/patch-db/data-model'
import { getAllPackages, getManifest } from 'src/app/util/get-package-data'
import { hasCurrentDeps } from 'src/app/util/has-deps'
import { getManifest } from 'src/app/util/get-package-data'
import { filter, map } from 'rxjs'

@Component({
Expand All @@ -35,13 +33,9 @@ export class AppActionsPage {

constructor(
private readonly route: ActivatedRoute,
private readonly api: ApiService,
private readonly alertCtrl: AlertController,
private readonly errorService: ErrorService,
private readonly loader: LoadingService,
private readonly navCtrl: NavController,
private readonly patch: PatchDB<DataModel>,
private readonly actionService: ActionService,
private readonly standardActionsService: StandardActionsService,
) {}

async handleAction(
Expand All @@ -55,51 +49,12 @@ export class AppActionsPage {
)
}

async tryUninstall(manifest: T.Manifest): Promise<void> {
let message =
manifest.alerts.uninstall ||
`Uninstalling ${manifest.title} will permanently delete its data`

if (hasCurrentDeps(this.pkgId, await getAllPackages(this.patch))) {
message = `${message}. Services that depend on ${manifest.title} will no longer work properly and may crash`
}

const alert = await this.alertCtrl.create({
header: 'Warning',
message,
buttons: [
{
text: 'Cancel',
role: 'cancel',
},
{
text: 'Uninstall',
handler: () => {
this.uninstall()
},
cssClass: 'enter-click',
},
],
cssClass: 'alert-warning-message',
})

await alert.present()
async rebuild(id: string) {
return this.standardActionsService.rebuild(id)
}

private async uninstall() {
const loader = this.loader.open(`Beginning uninstall...`).subscribe()

try {
await this.api.uninstallPackage({ id: this.pkgId })
this.api
.setDbValue<boolean>(['ackInstructions', this.pkgId], false)
.catch(e => console.error('Failed to mark instructions as unseen', e))
this.navCtrl.navigateRoot('/services')
} catch (e: any) {
this.errorService.handleError(e)
} finally {
loader.unsubscribe()
}
async tryUninstall(manifest: T.Manifest) {
return this.standardActionsService.tryUninstall(manifest)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { AppShowDependenciesComponent } from './components/app-show-dependencies
import { AppShowMenuComponent } from './components/app-show-menu/app-show-menu.component'
import { AppShowHealthChecksComponent } from './components/app-show-health-checks/app-show-health-checks.component'
import { AppShowAdditionalComponent } from './components/app-show-additional/app-show-additional.component'
import { AppShowErrorComponent } from './components/app-show-error/app-show-error.component'
import { HealthColorPipe } from './pipes/health-color.pipe'
import { ToHealthChecksPipe } from './pipes/to-health-checks.pipe'
import { ToButtonsPipe } from './pipes/to-buttons.pipe'
Expand All @@ -43,6 +44,7 @@ const routes: Routes = [
AppShowMenuComponent,
AppShowHealthChecksComponent,
AppShowAdditionalComponent,
AppShowErrorComponent,
],
imports: [
CommonModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
<ion-item-group *ngIf="pkgPlus.status as status">
<!-- ** status ** -->
<app-show-status [pkg]="pkg" [status]="status"></app-show-status>
<!-- ** installed && !backingUp ** -->
<!-- ** installed && !backingUp && !error ** -->
<ng-container
*ngIf="isInstalled(pkg) && status.primary !== 'backingUp'"
*ngIf="isInstalled(pkg) && status.primary !== 'backingUp' && status.primary !== 'error'"
>
<!-- ** health checks ** -->
<app-show-health-checks
Expand All @@ -35,6 +35,11 @@
<!-- ** additional ** -->
<app-show-additional [pkg]="pkg"></app-show-additional>
</ng-container>
<app-show-error
*ngIf="pkg.status.main === 'error'"
[manifest]="pkgPlus.manifest"
[error]="pkg.status"
></app-show-error>
</ion-item-group>
</ng-template>
</ion-content>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface DependencyInfo {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppShowPage {
private readonly pkgId = getPkgId(this.route)
readonly pkgId = getPkgId(this.route)

readonly pkgPlus$ = combineLatest([
this.patch.watch$('packageData'),
Expand All @@ -58,9 +58,11 @@ export class AppShowPage {
}),
map(([allPkgs, depErrors]) => {
const pkg = allPkgs[this.pkgId]
const manifest = getManifest(pkg)
return {
pkg,
dependencies: this.getDepInfo(pkg, allPkgs, depErrors),
manifest,
dependencies: this.getDepInfo(pkg, manifest, allPkgs, depErrors),
status: renderPkgStatus(pkg, depErrors),
}
}),
Expand All @@ -84,11 +86,10 @@ export class AppShowPage {

private getDepInfo(
pkg: PackageDataEntry,
manifest: T.Manifest,
allPkgs: AllPackageData,
depErrors: PkgDependencyErrors,
): DependencyInfo[] {
const manifest = getManifest(pkg)

return Object.keys(pkg.currentDependencies).map(id =>
this.getDepValues(pkg, allPkgs, manifest, id, depErrors),
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<ion-item-divider>Message</ion-item-divider>
<div class="code-block ion-margin">
<code>
<ion-text color="warning">{{ error.message }}</ion-text>
</code>
</div>

<ion-item-divider>Actions</ion-item-divider>
<div class="ion-margin">
<p>
<b>Rebuild Container</b>
is harmless action that and only takes a few seconds to complete. It will
likely resolve this issue.
<b>Uninstall Service</b>
is a dangerous action that will remove the service from StartOS and wipe all
its data.
</p>
<ion-button class="ion-margin-end" (click)="rebuild()">
Rebuild Container
</ion-button>
<ion-button (click)="tryUninstall()" color="danger">
Uninstall Service
</ion-button>
</div>

<ng-container *ngIf="error.debug">
<ion-item-divider>Full Stack Trace</ion-item-divider>
<div class="code-block ion-margin">
<code>{{ error.message }}</code>
</div>
</ng-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { ToastController } from '@ionic/angular'
import { copyToClipboard } from '@start9labs/shared'
import { T } from '@start9labs/start-sdk'
import { StandardActionsService } from 'src/app/services/standard-actions.service'

@Component({
selector: 'app-show-error',
templateUrl: 'app-show-error.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppShowErrorComponent {
@Input()
manifest!: T.Manifest

@Input()
error!: T.MainStatus & { main: 'error' }

constructor(
private readonly toastCtrl: ToastController,
private readonly standardActionsService: StandardActionsService,
) {}

async copy(text: string): Promise<void> {
const success = await copyToClipboard(text)
const message = success
? 'Copied to clipboard!'
: 'Failed to copy to clipboard.'

const toast = await this.toastCtrl.create({
header: message,
position: 'bottom',
duration: 1000,
})
await toast.present()
}

async rebuild() {
return this.standardActionsService.rebuild(this.manifest.id)
}

async tryUninstall() {
return this.standardActionsService.tryUninstall(this.manifest)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@
</ion-label>
</ion-item>

<ng-container *ngIf="isInstalled(pkg) && (connection$ | async)">
<ng-container
*ngIf="
isInstalled(pkg) &&
pkg.status.main !== 'backingUp' &&
pkg.status.main !== 'error' &&
(connection$ | async)
"
>
<ion-grid>
<ion-row style="padding-left: 12px">
<ion-col>
Expand Down
3 changes: 3 additions & 0 deletions web/projects/ui/src/app/services/api/api.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ export module RR {
export type StopPackageReq = { id: string } // package.stop
export type StopPackageRes = null

export type RebuildPackageReq = { id: string } // package.rebuild
export type RebuildPackageRes = null

export type UninstallPackageReq = { id: string } // package.uninstall
export type UninstallPackageRes = null

Expand Down
4 changes: 4 additions & 0 deletions web/projects/ui/src/app/services/api/embassy-api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ export abstract class ApiService {

abstract stopPackage(params: RR.StopPackageReq): Promise<RR.StopPackageRes>

abstract rebuildPackage(
params: RR.RebuildPackageReq,
): Promise<RR.RebuildPackageRes>

abstract uninstallPackage(
params: RR.UninstallPackageReq,
): Promise<RR.UninstallPackageRes>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,12 @@ export class LiveApiService extends ApiService {
return this.rpcRequest({ method: 'package.stop', params })
}

async rebuildPackage(
params: RR.RebuildPackageReq,
): Promise<RR.RebuildPackageRes> {
return this.rpcRequest({ method: 'package.rebuild', params })
}

async uninstallPackage(
params: RR.UninstallPackageReq,
): Promise<RR.UninstallPackageRes> {
Expand Down
Loading

0 comments on commit 93156dc

Please sign in to comment.