mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
show health even when not completed and reword restart-shutdown
This commit is contained in:
committed by
Aiden McClelland
parent
c30141c4f0
commit
502fdeea78
@@ -307,7 +307,7 @@ export class AppComponent {
|
|||||||
|
|
||||||
this.updateToast = await this.toastCtrl.create({
|
this.updateToast = await this.toastCtrl.create({
|
||||||
header: 'EOS download complete!',
|
header: 'EOS download complete!',
|
||||||
message: `Restart Embassy for changes to take effect.`,
|
message: 'Restart your Embassy for these updates to take effect. It can take several minutes to come back online.',
|
||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
duration: 0,
|
duration: 0,
|
||||||
cssClass: 'success-toast',
|
cssClass: 'success-toast',
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
<!-- ** !restoring/backing-up ** -->
|
<!-- ** !restoring/backing-up ** -->
|
||||||
<ng-container *ngIf="!([PS.BackingUp, PS.Restoring] | includes : statuses.primary)">
|
<ng-container *ngIf="!([PS.BackingUp, PS.Restoring] | includes : statuses.primary)">
|
||||||
<!-- ** health checks ** -->
|
<!-- ** health checks ** -->
|
||||||
<ng-container *ngIf="!(healthChecks | empty)">
|
<ng-container *ngIf="statuses.primary === PS.Running && !(healthChecks | empty)">
|
||||||
<ion-item-divider>Health Checks</ion-item-divider>
|
<ion-item-divider>Health Checks</ion-item-divider>
|
||||||
<ng-container *ngIf="connectionFailure">
|
<ng-container *ngIf="connectionFailure">
|
||||||
<ion-item *ngFor="let health of healthChecks | keyvalue">
|
<ion-item *ngFor="let health of healthChecks | keyvalue">
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="!connectionFailure">
|
<ng-container *ngIf="!connectionFailure">
|
||||||
<ion-item *ngFor="let health of healthChecks | keyvalue : asIsOrder">
|
<ion-item *ngFor="let health of healthChecks | keyvalue : asIsOrder">
|
||||||
<ng-container *ngIf="$any(health.value).result as result">
|
<ng-container *ngIf="health.value?.result as result; else noResult">
|
||||||
<ion-spinner class="icon-spinner" color="primary" slot="start" *ngIf="[HealthResult.Starting, HealthResult.Loading] | includes : result"></ion-spinner>
|
<ion-spinner class="icon-spinner" color="primary" slot="start" *ngIf="[HealthResult.Starting, HealthResult.Loading] | includes : result"></ion-spinner>
|
||||||
<ion-icon slot="start" *ngIf="result === HealthResult.Success" name="checkmark" color="success"></ion-icon>
|
<ion-icon slot="start" *ngIf="result === HealthResult.Success" name="checkmark" color="success"></ion-icon>
|
||||||
<ion-icon slot="start" *ngIf="result === HealthResult.Failure" name="warning-outline" color="warning"></ion-icon>
|
<ion-icon slot="start" *ngIf="result === HealthResult.Failure" name="warning-outline" color="warning"></ion-icon>
|
||||||
@@ -79,6 +79,13 @@
|
|||||||
<p *ngIf="result === HealthResult.Failure"><ion-text color="warning">{{ $any(health.value).error }}</ion-text></p>
|
<p *ngIf="result === HealthResult.Failure"><ion-text color="warning">{{ $any(health.value).error }}</ion-text></p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<ng-template #noResult>
|
||||||
|
<ion-spinner class="icon-spinner" color="dark" slot="start"></ion-spinner>
|
||||||
|
<ion-label>
|
||||||
|
<h2 style="font-weight: bold;">{{ health.key }}</h2>
|
||||||
|
<p>Awaiting result...</p>
|
||||||
|
</ion-label>
|
||||||
|
</ng-template>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export class AppShowPage {
|
|||||||
} = { } as any
|
} = { } as any
|
||||||
connectionFailure: boolean
|
connectionFailure: boolean
|
||||||
loading = true
|
loading = true
|
||||||
healthChecks: { [id: string]: HealthCheckResult } = { }
|
healthChecks: { [id: string]: HealthCheckResult | null }
|
||||||
installProgress: ProgressData
|
installProgress: ProgressData
|
||||||
|
|
||||||
@ViewChild(IonContent) content: IonContent
|
@ViewChild(IonContent) content: IonContent
|
||||||
@@ -66,6 +66,11 @@ export class AppShowPage {
|
|||||||
async ngOnInit () {
|
async ngOnInit () {
|
||||||
this.pkgId = this.route.snapshot.paramMap.get('pkgId')
|
this.pkgId = this.route.snapshot.paramMap.get('pkgId')
|
||||||
this.pkg = this.patch.data['package-data'][this.pkgId]
|
this.pkg = this.patch.data['package-data'][this.pkgId]
|
||||||
|
this.statuses = renderPkgStatus(this.pkg)
|
||||||
|
this.healthChecks = Object.keys(this.pkg.manifest['health-checks']).reduce((obj, key) => {
|
||||||
|
obj[key] = null
|
||||||
|
return obj
|
||||||
|
}, { })
|
||||||
|
|
||||||
this.subs = [
|
this.subs = [
|
||||||
// 1
|
// 1
|
||||||
@@ -105,9 +110,13 @@ export class AppShowPage {
|
|||||||
)
|
)
|
||||||
.subscribe(main => {
|
.subscribe(main => {
|
||||||
if (main.status === PackageMainStatus.Running) {
|
if (main.status === PackageMainStatus.Running) {
|
||||||
this.healthChecks = { ...main.health }
|
Object.keys(this.healthChecks).forEach(key => {
|
||||||
|
this.healthChecks[key] = main.health[key]
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
this.healthChecks = { }
|
Object.keys(this.healthChecks).forEach(key => {
|
||||||
|
this.healthChecks[key] = null
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<h2 class="notification-message">
|
<h2 class="notification-message">
|
||||||
{{ not.message }}
|
{{ not.message }}
|
||||||
<a *ngIf="not.code === 1" style="text-decoration: none;" (click)="viewBackupReport(not)">
|
<a *ngIf="not.code === 1" style="text-decoration: none; cursor: pointer;" (click)="viewBackupReport(not)">
|
||||||
View Report
|
View Report
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component } from '@angular/core'
|
||||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||||
import { ServerNotification, ServerNotifications } from 'src/app/services/api/api.types'
|
import { ServerNotification, ServerNotifications } from 'src/app/services/api/api.types'
|
||||||
import { AlertController, LoadingController } from '@ionic/angular'
|
import { AlertController, LoadingController, AlertButton } from '@ionic/angular'
|
||||||
import { ActivatedRoute } from '@angular/router'
|
import { ActivatedRoute } from '@angular/router'
|
||||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ export class NotificationsPage {
|
|||||||
const data = notification.data
|
const data = notification.data
|
||||||
|
|
||||||
const embassyFailed = !!data.server.error
|
const embassyFailed = !!data.server.error
|
||||||
const packagesFailed = Object.entries(data.packages).some(([_, val]) => val.error)
|
const packagesFailed = Object.values(data.packages).some(val => val.error)
|
||||||
|
|
||||||
let message: string
|
let message: string
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ export class NotificationsPage {
|
|||||||
message = 'All items were successfully backed up'
|
message = 'All items were successfully backed up'
|
||||||
}
|
}
|
||||||
|
|
||||||
const buttons: any[] = [ // why can't I import AlertButton?
|
const buttons: AlertButton[] = [
|
||||||
{
|
{
|
||||||
text: 'Dismiss',
|
text: 'Dismiss',
|
||||||
role: 'cancel',
|
role: 'cancel',
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export class ServerShowPage {
|
|||||||
async presentAlertRestart () {
|
async presentAlertRestart () {
|
||||||
const alert = await this.alertCtrl.create({
|
const alert = await this.alertCtrl.create({
|
||||||
header: 'Confirm',
|
header: 'Confirm',
|
||||||
message: `Are you sure you want to restart your Embassy?`,
|
message: 'Are you sure you want to restart your Embassy? It can take several minutes to come back online.',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
text: 'Cancel',
|
text: 'Cancel',
|
||||||
@@ -51,7 +51,7 @@ export class ServerShowPage {
|
|||||||
async presentAlertShutdown () {
|
async presentAlertShutdown () {
|
||||||
const alert = await this.alertCtrl.create({
|
const alert = await this.alertCtrl.create({
|
||||||
header: 'Warning',
|
header: 'Warning',
|
||||||
message: `Embassy will remain off. To power back on, you will need to unplug the device and plug it back in.`,
|
message: 'Are you sure you want to power down your Embassy? This can take several minutes, and your Embassy will not come back online automatically. To power on again, You will need to physically unplug your Embassy and plug it back in.',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
text: 'Cancel',
|
text: 'Cancel',
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ export class MockApiService extends ApiService {
|
|||||||
async startPackageRaw (params: RR.StartPackageReq): Promise<RR.StartPackageRes> {
|
async startPackageRaw (params: RR.StartPackageReq): Promise<RR.StartPackageRes> {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
const path = `/package-data/${params.id}/installed/status/main`
|
const path = `/package-data/${params.id}/installed/status/main`
|
||||||
const patch = [
|
const patch1 = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path: path + '/status',
|
path: path + '/status',
|
||||||
@@ -457,7 +457,58 @@ export class MockApiService extends ApiService {
|
|||||||
value: new Date().toISOString(),
|
value: new Date().toISOString(),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
const res = await this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch: patch1 } })
|
||||||
|
|
||||||
|
setTimeout(async () => {
|
||||||
|
const patch2 = [
|
||||||
|
{
|
||||||
|
op: PatchOp.REPLACE,
|
||||||
|
path: path + '/health',
|
||||||
|
value: {
|
||||||
|
'ephemeral-health-check': {
|
||||||
|
result: 'starting',
|
||||||
|
},
|
||||||
|
'unnecessary-health-check': {
|
||||||
|
result: 'disabled',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
await this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch: patch2 } })
|
||||||
|
|
||||||
|
await pauseFor(2000)
|
||||||
|
|
||||||
|
const patch3 = [
|
||||||
|
{
|
||||||
|
op: PatchOp.REPLACE,
|
||||||
|
path: path + '/health',
|
||||||
|
value: {
|
||||||
|
'ephemeral-health-check': {
|
||||||
|
result: 'starting',
|
||||||
|
},
|
||||||
|
'unnecessary-health-check': {
|
||||||
|
result: 'disabled',
|
||||||
|
},
|
||||||
|
'chain-state': {
|
||||||
|
result: 'loading',
|
||||||
|
message: 'Bitcoin is syncing from genesis',
|
||||||
|
},
|
||||||
|
'p2p-interface': {
|
||||||
|
result: 'success',
|
||||||
|
},
|
||||||
|
'rpc-interface': {
|
||||||
|
result: 'failure',
|
||||||
|
error: 'RPC interface unreachable.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
await this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch: patch3 } })
|
||||||
|
}, 4000)
|
||||||
|
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
async dryStopPackage (params: RR.DryStopPackageReq): Promise<RR.DryStopPackageRes> {
|
async dryStopPackage (params: RR.DryStopPackageReq): Promise<RR.DryStopPackageRes> {
|
||||||
@@ -474,20 +525,25 @@ export class MockApiService extends ApiService {
|
|||||||
|
|
||||||
async stopPackageRaw (params: RR.StopPackageReq): Promise<RR.StopPackageRes> {
|
async stopPackageRaw (params: RR.StopPackageReq): Promise<RR.StopPackageRes> {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
const path = `/package-data/${params.id}/installed/status/main/status`
|
const path = `/package-data/${params.id}/installed/status/main`
|
||||||
const patch = [
|
const patch = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path,
|
path: path + '/status',
|
||||||
value: PackageMainStatus.Stopping,
|
value: PackageMainStatus.Stopping,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
op: PatchOp.REPLACE,
|
||||||
|
path: path + '/health',
|
||||||
|
value: { },
|
||||||
|
},
|
||||||
]
|
]
|
||||||
const res = await this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
const res = await this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const patch = [
|
const patch = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path,
|
path: path + '/status',
|
||||||
value: PackageMainStatus.Stopped,
|
value: PackageMainStatus.Stopped,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user