- Backups
-
-
-
- Create Backup
- Back up your Embassy and all its services
-
-
- Last Backup: {{ patch.data['server-info']['last-backup'] ? (patch.data['server-info']['last-backup'] | date: 'short') : 'never' }}
-
-
-
-
-
{{ cat.key }}
diff --git a/ui/src/app/pages/server-routes/server-show/server-show.page.ts b/ui/src/app/pages/server-routes/server-show/server-show.page.ts
index 860dd4f07..1d0416f56 100644
--- a/ui/src/app/pages/server-routes/server-show/server-show.page.ts
+++ b/ui/src/app/pages/server-routes/server-show/server-show.page.ts
@@ -105,6 +105,22 @@ export class ServerShowPage {
private setButtons (): void {
this.settings = {
+ 'Backups': [
+ {
+ title: 'Create Backup',
+ description: 'Back up your Embassy and all its services',
+ icon: 'save-outline',
+ action: () => this.navCtrl.navigateForward(['backup'], { relativeTo: this.route }),
+ detail: true,
+ },
+ {
+ title: 'Restore From Backup',
+ description: 'Restore one or more services from a prior backup',
+ icon: 'color-wand-outline',
+ action: () => this.navCtrl.navigateForward(['restore'], { relativeTo: this.route }),
+ detail: true,
+ },
+ ],
'Insights': [
{
title: 'About',
diff --git a/ui/src/app/services/api/api.fixures.ts b/ui/src/app/services/api/api.fixures.ts
index 2214ad8b1..c251cbe2d 100644
--- a/ui/src/app/services/api/api.fixures.ts
+++ b/ui/src/app/services/api/api.fixures.ts
@@ -990,6 +990,7 @@ export module Mock {
},
],
capacity: 1000000000000,
+ internal: true,
},
{
logicalname: '/dev/sdb',
@@ -1015,6 +1016,7 @@ export module Mock {
},
],
capacity: 10000000000,
+ internal: false,
},
]
@@ -1023,10 +1025,17 @@ export module Mock {
timestamp: new Date().toISOString(),
'package-backups': {
bitcoind: {
+ title: 'Bitcoin Core',
version: '0.21.0',
'os-version': '0.3.0',
timestamp: new Date().toISOString(),
},
+ 'btc-rpc-proxy': {
+ title: 'Bitcoin Proxy',
+ version: '0.2.2',
+ 'os-version': '0.3.0',
+ timestamp: new Date().toISOString(),
+ },
},
}
@@ -1614,11 +1623,9 @@ export module Mock {
installed: {
'last-backup': null,
status: {
- configured: true,
+ configured: false,
main: {
- status: PackageMainStatus.Running,
- started: new Date().toISOString(),
- health: { },
+ status: PackageMainStatus.Stopped,
},
'dependency-errors': { },
},
diff --git a/ui/src/app/services/api/api.types.ts b/ui/src/app/services/api/api.types.ts
index 6806b5206..f19145bed 100644
--- a/ui/src/app/services/api/api.types.ts
+++ b/ui/src/app/services/api/api.types.ts
@@ -157,8 +157,8 @@ export module RR {
export type SetPackageConfigReq = WithExpire // package.config.set
export type SetPackageConfigRes = WithRevision
- export type RestorePackageReq = WithExpire<{ id: string, logicalname: string, password: string }> // package.backup.restore
- export type RestorePackageRes = WithRevision
+ export type RestorePackagesReq = WithExpire<{ ids: string[], logicalname: string, password: string }> // package.backup.restore
+ export type RestorePackagesRes = WithRevision
export type ExecutePackageActionReq = { id: string, 'action-id': string, input?: object } // package.action
export type ExecutePackageActionRes = ActionResponse
@@ -300,6 +300,7 @@ export interface DriveInfo {
model: string | null
partitions: PartitionInfo[]
capacity: number
+ internal: boolean
}
export interface PartitionInfo {
@@ -319,14 +320,17 @@ export interface BackupInfo {
version: string,
timestamp: string,
'package-backups': {
- [id: string]: {
- version: string
- 'os-version': string
- timestamp: string
- }
+ [id: string]: PackageBackupInfo
}
}
+export interface PackageBackupInfo {
+ title: string
+ version: string
+ 'os-version': string
+ timestamp: string
+}
+
export interface ServerSpecs {
[key: string]: string | number
}
diff --git a/ui/src/app/services/api/embassy-api.service.ts b/ui/src/app/services/api/embassy-api.service.ts
index 458b6b4de..8037c7864 100644
--- a/ui/src/app/services/api/embassy-api.service.ts
+++ b/ui/src/app/services/api/embassy-api.service.ts
@@ -154,9 +154,9 @@ export abstract class ApiService implements Source, Http {
() => this.setPackageConfigRaw(params),
)()
- protected abstract restorePackageRaw (params: RR.RestorePackageReq): Promise
- restorePackage = (params: RR.RestorePackageReq) => this.syncResponse(
- () => this.restorePackageRaw(params),
+ protected abstract restorePackagesRaw (params: RR.RestorePackagesReq): Promise
+ restorePackages = (params: RR.RestorePackagesReq) => this.syncResponse(
+ () => this.restorePackagesRaw(params),
)()
abstract executePackageAction (params: RR.ExecutePackageActionReq): Promise
diff --git a/ui/src/app/services/api/embassy-live-api.service.ts b/ui/src/app/services/api/embassy-live-api.service.ts
index fda5742ae..40d98c128 100644
--- a/ui/src/app/services/api/embassy-live-api.service.ts
+++ b/ui/src/app/services/api/embassy-live-api.service.ts
@@ -236,8 +236,8 @@ export class LiveApiService extends ApiService {
return this.http.rpcRequest({ method: 'package.config.set', params })
}
- async restorePackageRaw (params: RR.RestorePackageReq): Promise {
- return this.http.rpcRequest({ method: 'package.restore', params })
+ async restorePackagesRaw (params: RR.RestorePackagesReq): Promise {
+ return this.http.rpcRequest({ method: 'package.backup.restore', params })
}
async executePackageAction (params: RR.ExecutePackageActionReq): Promise {
diff --git a/ui/src/app/services/api/embassy-mock-api.service.ts b/ui/src/app/services/api/embassy-mock-api.service.ts
index 831b75c02..10805e560 100644
--- a/ui/src/app/services/api/embassy-mock-api.service.ts
+++ b/ui/src/app/services/api/embassy-mock-api.service.ts
@@ -8,6 +8,7 @@ import { parsePropertiesPermissive } from 'src/app/util/properties.util'
import { Mock } from './api.fixures'
import { HttpService } from '../http.service'
import markdown from 'raw-loader!src/assets/markdown/md-sample.md'
+import { Operation } from 'fast-json-patch'
@Injectable()
export class MockApiService extends ApiService {
@@ -413,28 +414,38 @@ export class MockApiService extends ApiService {
return this.http.rpcRequest>({ method: 'db.patch', params: { patch } })
}
- async restorePackageRaw (params: RR.RestorePackageReq): Promise {
+ async restorePackagesRaw (params: RR.RestorePackagesReq): Promise {
await pauseFor(2000)
- const path = `/package-data/${params.id}/installed/status/main/status`
- const patch = [
- {
- op: PatchOp.REPLACE,
- path,
- value: PackageMainStatus.Restoring,
- },
- ]
- const res = await this.http.rpcRequest>({ method: 'db.patch', params: { patch } })
- setTimeout(() => {
- const patch = [
- {
- op: PatchOp.REPLACE,
- path,
- value: PackageMainStatus.Stopped,
- },
- ]
- this.http.rpcRequest>({ method: 'db.patch', params: { patch } })
- }, this.revertTime)
- return res
+ const patch: Operation[] = params.ids.map(id => {
+
+ const initialProgress: InstallProgress = {
+ size: 120,
+ downloaded: 120,
+ 'download-complete': true,
+ validated: 0,
+ 'validation-complete': false,
+ unpacked: 0,
+ 'unpack-complete': false,
+ }
+
+ const pkg: PackageDataEntry = {
+ ...Mock.LocalPkgs[id],
+ state: PackageState.Restoring,
+ 'install-progress': initialProgress,
+ installed: undefined,
+ }
+
+ setTimeout(async () => {
+ this.updateProgress(id, initialProgress)
+ }, 2000)
+
+ return {
+ op: 'add',
+ path: `/package-data/${id}`,
+ value: pkg,
+ }
+ })
+ return this.http.rpcRequest>({ method: 'db.patch', params: { patch } })
}
async executePackageAction (params: RR.ExecutePackageActionReq): Promise {
diff --git a/ui/src/app/services/patch-db/data-model.ts b/ui/src/app/services/patch-db/data-model.ts
index c306c9557..903a6e78b 100644
--- a/ui/src/app/services/patch-db/data-model.ts
+++ b/ui/src/app/services/patch-db/data-model.ts
@@ -95,6 +95,7 @@ export enum PackageState {
Installed = 'installed',
Updating = 'updating',
Removing = 'removing',
+ Restoring = 'restoring',
}
export interface Manifest {
@@ -235,7 +236,7 @@ export interface Status {
'dependency-errors': { [id: string]: DependencyError | null }
}
-export type MainStatus = MainStatusStopped | MainStatusStopping | MainStatusRunning | MainStatusBackingUp | MainStatusRestoring
+export type MainStatus = MainStatusStopped | MainStatusStopping | MainStatusRunning | MainStatusBackingUp
export interface MainStatusStopped {
status: PackageMainStatus.Stopped
@@ -256,17 +257,11 @@ export interface MainStatusBackingUp {
started: string | null // UTC date string
}
-export interface MainStatusRestoring {
- status: PackageMainStatus.Restoring
- running: boolean
-}
-
export enum PackageMainStatus {
Running = 'running',
Stopping = 'stopping',
Stopped = 'stopped',
BackingUp = 'backing-up',
- Restoring = 'restoring',
}
export type HealthCheckResult = HealthCheckResultStarting |
diff --git a/ui/src/app/services/pkg-status-rendering.service.ts b/ui/src/app/services/pkg-status-rendering.service.ts
index 7267dd439..219b91fa1 100644
--- a/ui/src/app/services/pkg-status-rendering.service.ts
+++ b/ui/src/app/services/pkg-status-rendering.service.ts
@@ -71,12 +71,12 @@ export enum PrimaryStatus {
Installing = 'installing',
Updating = 'updating',
Removing = 'removing',
+ Restoring = 'restoring',
// status
Running = 'running',
Stopping = 'stopping',
Stopped = 'stopped',
BackingUp = 'backing-up',
- Restoring = 'restoring',
// config
NeedsConfig = 'needs-config',
}
@@ -98,10 +98,10 @@ export const PrimaryRendering: { [key: string]: StatusRendering } = {
[PrimaryStatus.Installing]: { display: 'Installing', color: 'primary', showDots: true },
[PrimaryStatus.Updating]: { display: 'Updating', color: 'primary', showDots: true },
[PrimaryStatus.Removing]: { display: 'Removing', color: 'danger', showDots: true },
+ [PrimaryStatus.Restoring]: { display: 'Restoring', color: 'primary', showDots: true },
[PrimaryStatus.Stopping]: { display: 'Stopping', color: 'dark-shade', showDots: true },
[PrimaryStatus.Stopped]: { display: 'Stopped', color: 'dark-shade', showDots: false },
[PrimaryStatus.BackingUp]: { display: 'Backing Up', color: 'primary', showDots: true },
- [PrimaryStatus.Restoring]: { display: 'Restoring', color: 'primary', showDots: true },
[PrimaryStatus.Running]: { display: 'Running', color: 'success', showDots: false },
[PrimaryStatus.NeedsConfig]: { display: 'Needs Config', color: 'warning' },
}
diff --git a/ui/src/global.scss b/ui/src/global.scss
index 8148f1e50..598ff6f98 100644
--- a/ui/src/global.scss
+++ b/ui/src/global.scss
@@ -289,18 +289,9 @@ ion-loading {
}
.dots {
- vertical-align: middle;
- margin-left: 8px;
-}
-
-.dots-small {
- width: 12px !important;
- height: 12px !important;
-}
-
-.dots-medium {
- width: 16px !important;
- height: 16px !important;
+ vertical-align: top;
+ margin-left: 2px;
+ margin-right: 2px;
}
h2 {