mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-01 21:13:09 +00:00
Feature/setup migrate (#1841)
* add migrate component * finish out migrate page and adjust recover options * fix typo * rename migrate -> transfer, adjust copy and typos, update transfer component logic * add alert for old drive data when transferring * comments for clarity * auto adjust swiper slide height * cleanup uneeded imports from transfer module * pr feedback suggestions * remove 02x from setup wiz * clean up copy/styling for recover flow * add support for migrating from old drive * add RecoverySource lifted type Co-authored-by: Matt Hill <matthewonthemoon@gmail.com> Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
@@ -5,7 +5,6 @@ export abstract class ApiService {
|
||||
abstract getStatus(): Promise<GetStatusRes> // setup.status
|
||||
abstract getPubKey(): Promise<void> // setup.get-pubkey
|
||||
abstract getDrives(): Promise<DiskListResponse> // setup.disk.list
|
||||
abstract set02XDrive(logicalname: string): Promise<void> // setup.recovery.v2.set
|
||||
abstract getRecoveryStatus(): Promise<RecoveryStatusRes> // setup.recovery.status
|
||||
abstract verifyCifs(cifs: CifsRecoverySource): Promise<EmbassyOSRecoveryInfo> // setup.cifs.verify
|
||||
abstract importDrive(importInfo: ImportDriveReq): Promise<SetupEmbassyRes> // setup.attach
|
||||
@@ -39,7 +38,7 @@ export type ImportDriveReq = {
|
||||
export type SetupEmbassyReq = {
|
||||
'embassy-logicalname': string
|
||||
'embassy-password': Encrypted
|
||||
'recovery-source': CifsRecoverySource | DiskRecoverySource | null
|
||||
'recovery-source': RecoverySource | null
|
||||
'recovery-password': Encrypted | null
|
||||
}
|
||||
|
||||
@@ -81,6 +80,17 @@ export type DiskRecoverySource = {
|
||||
logicalname: string // partition logicalname
|
||||
}
|
||||
|
||||
export type BackupRecoverySource = {
|
||||
type: 'backup'
|
||||
target: CifsRecoverySource | DiskRecoverySource
|
||||
}
|
||||
export type RecoverySource = BackupRecoverySource | DiskMigrateSource
|
||||
|
||||
export type DiskMigrateSource = {
|
||||
type: 'migrate'
|
||||
guid: string
|
||||
}
|
||||
|
||||
export type CifsRecoverySource = {
|
||||
type: 'cifs'
|
||||
hostname: string
|
||||
@@ -95,7 +105,7 @@ export type DiskInfo = {
|
||||
model: string | null
|
||||
partitions: PartitionInfo[]
|
||||
capacity: number
|
||||
guid: string | null // cant back up if guid exists
|
||||
guid: string | null // cant back up if guid exists, but needed if migrating
|
||||
}
|
||||
|
||||
export type RecoveryStatusRes = {
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
ApiService,
|
||||
CifsRecoverySource,
|
||||
DiskListResponse,
|
||||
DiskMigrateSource,
|
||||
DiskRecoverySource,
|
||||
EmbassyOSRecoveryInfo,
|
||||
GetStatusRes,
|
||||
@@ -58,13 +59,6 @@ export class LiveApiService extends ApiService {
|
||||
})
|
||||
}
|
||||
|
||||
async set02XDrive(logicalname: string) {
|
||||
return this.rpcRequest<void>({
|
||||
method: 'setup.recovery.v2.set',
|
||||
params: { logicalname },
|
||||
})
|
||||
}
|
||||
|
||||
async getRecoveryStatus() {
|
||||
return this.rpcRequest<RecoveryStatusRes>({
|
||||
method: 'setup.recovery.status',
|
||||
@@ -93,10 +87,12 @@ export class LiveApiService extends ApiService {
|
||||
}
|
||||
|
||||
async setupEmbassy(setupInfo: SetupEmbassyReq) {
|
||||
if (isCifsSource(setupInfo['recovery-source'])) {
|
||||
setupInfo['recovery-source'].path = setupInfo[
|
||||
'recovery-source'
|
||||
].path.replace('/\\/g', '/')
|
||||
if (setupInfo['recovery-source']?.type === 'backup') {
|
||||
if (isCifsSource(setupInfo['recovery-source'].target)) {
|
||||
setupInfo['recovery-source'].target.path = setupInfo[
|
||||
'recovery-source'
|
||||
].target.path.replace('/\\/g', '/')
|
||||
}
|
||||
}
|
||||
|
||||
const res = await this.rpcRequest<SetupEmbassyRes>({
|
||||
|
||||
@@ -54,7 +54,30 @@ export class MockApiService extends ApiService {
|
||||
'embassy-os': {
|
||||
version: '0.2.17',
|
||||
full: true,
|
||||
'password-hash': null,
|
||||
'password-hash':
|
||||
'$argon2d$v=19$m=1024,t=1,p=1$YXNkZmFzZGZhc2RmYXNkZg$Ceev1I901G6UwU+hY0sHrFZ56D+o+LNJ',
|
||||
'wrapped-key': null,
|
||||
},
|
||||
},
|
||||
],
|
||||
capacity: 123456789123,
|
||||
guid: 'uuid-uuid-uuid-uuid',
|
||||
},
|
||||
{
|
||||
logicalname: 'dcba',
|
||||
vendor: 'Samsung',
|
||||
model: 'T5',
|
||||
partitions: [
|
||||
{
|
||||
logicalname: 'pbcba',
|
||||
label: null,
|
||||
capacity: 73264762332,
|
||||
used: null,
|
||||
'embassy-os': {
|
||||
version: '0.3.1',
|
||||
full: true,
|
||||
'password-hash':
|
||||
'$argon2d$v=19$m=1024,t=1,p=1$YXNkZmFzZGZhc2RmYXNkZg$Ceev1I901G6UwU+hY0sHrFZ56D+o+LNJ',
|
||||
'wrapped-key': null,
|
||||
},
|
||||
},
|
||||
@@ -65,11 +88,6 @@ export class MockApiService extends ApiService {
|
||||
]
|
||||
}
|
||||
|
||||
async set02XDrive() {
|
||||
await pauseFor(1000)
|
||||
return
|
||||
}
|
||||
|
||||
async getRecoveryStatus() {
|
||||
tries = Math.min(tries + 1, 4)
|
||||
return {
|
||||
@@ -134,105 +152,3 @@ const setupRes = {
|
||||
'lan-address': 'https://embassy-abcdefgh.local',
|
||||
'root-ca': encodeBase64(rootCA),
|
||||
}
|
||||
|
||||
const disks = [
|
||||
{
|
||||
vendor: 'Samsung',
|
||||
model: 'SATA',
|
||||
logicalname: '/dev/sda',
|
||||
guid: 'theguid',
|
||||
partitions: [
|
||||
{
|
||||
logicalname: 'sda1',
|
||||
label: 'label 1',
|
||||
capacity: 100000,
|
||||
used: 200.1255312,
|
||||
'embassy-os': null,
|
||||
},
|
||||
{
|
||||
logicalname: 'sda2',
|
||||
label: 'label 2',
|
||||
capacity: 50000,
|
||||
used: 200.1255312,
|
||||
'embassy-os': null,
|
||||
},
|
||||
],
|
||||
capacity: 150000,
|
||||
},
|
||||
{
|
||||
vendor: 'Samsung',
|
||||
model: null,
|
||||
logicalname: 'dev/sdb',
|
||||
partitions: [],
|
||||
capacity: 34359738369,
|
||||
guid: null,
|
||||
},
|
||||
{
|
||||
vendor: 'Crucial',
|
||||
model: 'MX500',
|
||||
logicalname: 'dev/sdc',
|
||||
guid: null,
|
||||
partitions: [
|
||||
{
|
||||
logicalname: 'sdc1',
|
||||
label: 'label 1',
|
||||
capacity: 0,
|
||||
used: null,
|
||||
'embassy-os': {
|
||||
version: '0.3.3',
|
||||
full: true,
|
||||
'password-hash': 'asdfasdfasdf',
|
||||
'wrapped-key': '',
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalname: 'sdc1MOCKTESTER',
|
||||
label: 'label 1',
|
||||
capacity: 0,
|
||||
used: null,
|
||||
'embassy-os': {
|
||||
version: '0.3.6',
|
||||
full: true,
|
||||
// password is 'asdfasdf'
|
||||
'password-hash':
|
||||
'$argon2d$v=19$m=1024,t=1,p=1$YXNkZmFzZGZhc2RmYXNkZg$Ceev1I901G6UwU+hY0sHrFZ56D+o+LNJ',
|
||||
'wrapped-key': '',
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalname: 'sdc1',
|
||||
label: 'label 1',
|
||||
capacity: 0,
|
||||
used: null,
|
||||
'embassy-os': {
|
||||
version: '0.3.3',
|
||||
full: false,
|
||||
'password-hash': 'asdfasdfasdf',
|
||||
'wrapped-key': '',
|
||||
},
|
||||
},
|
||||
],
|
||||
capacity: 100000,
|
||||
},
|
||||
{
|
||||
vendor: 'Sandisk',
|
||||
model: null,
|
||||
logicalname: '/dev/sdd',
|
||||
guid: null,
|
||||
partitions: [
|
||||
{
|
||||
logicalname: 'sdd1',
|
||||
label: null,
|
||||
capacity: 10000,
|
||||
used: null,
|
||||
'embassy-os': {
|
||||
version: '0.2.7',
|
||||
full: true,
|
||||
'password-hash': 'asdfasdfasdf',
|
||||
'wrapped-key': '',
|
||||
},
|
||||
},
|
||||
],
|
||||
capacity: 10000,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { BehaviorSubject } from 'rxjs'
|
||||
import {
|
||||
ApiService,
|
||||
CifsRecoverySource,
|
||||
DiskRecoverySource,
|
||||
} from './api/api.service'
|
||||
import { ApiService, RecoverySource } from './api/api.service'
|
||||
import { pauseFor, ErrorToastService } from '@start9labs/shared'
|
||||
|
||||
@Injectable({
|
||||
@@ -14,7 +10,7 @@ export class StateService {
|
||||
polling = false
|
||||
embassyLoaded = false
|
||||
|
||||
recoverySource?: CifsRecoverySource | DiskRecoverySource
|
||||
recoverySource?: RecoverySource
|
||||
recoveryPassword?: string
|
||||
|
||||
dataTransferProgress?: {
|
||||
|
||||
Reference in New Issue
Block a user