From f846c14d5342c12cf91792e8f5930e654ca0936a Mon Sep 17 00:00:00 2001 From: Pierre beucher Date: Tue, 25 Feb 2025 14:07:38 +0100 Subject: [PATCH 1/3] refactor: only prompt in CLI classes. No prompt in Core classes --- package.json | 2 +- src/{core => }/cli/command.ts | 4 +- src/{core => cli}/initializer.ts | 40 ++++++++--- src/{cli.ts => cli/main.ts} | 6 +- src/{ => cli}/program.ts | 31 +++++--- src/{core => }/cli/prompter.ts | 63 ++++++++++++++-- src/{core => cli}/updater.ts | 34 +++++++-- src/core/manager.ts | 13 +++- src/core/provisioner.ts | 72 +------------------ src/providers/aws/cli.ts | 10 +-- src/providers/aws/provisioner.ts | 18 ----- src/providers/azure/cli.ts | 8 +-- src/providers/azure/provisioner.ts | 17 ----- src/providers/gcp/cli.ts | 8 +-- src/providers/gcp/provisioner.ts | 17 ----- src/providers/paperspace/cli.ts | 8 +-- src/providers/paperspace/provisioner.ts | 23 ------ .../lib-full-lifecycle/lifecycle.spec.ts | 4 +- test/unit/aws/cli.spec.ts | 2 +- test/unit/azure/cli.spec.ts | 2 +- test/unit/core/cli.spec.ts | 2 +- test/unit/core/initializer.spec.ts | 4 +- test/unit/core/updater.spec.ts | 4 +- test/unit/gcp/cli.spec.ts | 2 +- test/unit/utils.ts | 4 +- 25 files changed, 185 insertions(+), 213 deletions(-) rename src/{core => }/cli/command.ts (98%) rename src/{core => cli}/initializer.ts (80%) rename src/{cli.ts => cli/main.ts} (86%) rename src/{ => cli}/program.ts (90%) rename src/{core => }/cli/prompter.ts (88%) rename src/{core => cli}/updater.ts (73%) diff --git a/package.json b/package.json index d6f8998f..5a47e9e0 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", "bin": { - "cloudypad": "./dist/src/cli.js" + "cloudypad": "./dist/src/cli/main.js" }, "author": "Pierre Beucher ", "license": "ISC", diff --git a/src/core/cli/command.ts b/src/cli/command.ts similarity index 98% rename from src/core/cli/command.ts rename to src/cli/command.ts index d0854390..79031ada 100644 --- a/src/core/cli/command.ts +++ b/src/cli/command.ts @@ -1,6 +1,6 @@ import { Command, Option } from "@commander-js/extra-typings"; -import { PUBLIC_IP_TYPE, PUBLIC_IP_TYPE_DYNAMIC, PUBLIC_IP_TYPE_STATIC } from "../const"; -import { AnalyticsManager } from "../../tools/analytics/manager"; +import { PUBLIC_IP_TYPE, PUBLIC_IP_TYPE_DYNAMIC, PUBLIC_IP_TYPE_STATIC } from "../core/const"; +import { AnalyticsManager } from "../tools/analytics/manager"; // // Common CLI Option each providers can re-use diff --git a/src/core/initializer.ts b/src/cli/initializer.ts similarity index 80% rename from src/core/initializer.ts rename to src/cli/initializer.ts index bf4b9fd9..24d73719 100644 --- a/src/core/initializer.ts +++ b/src/cli/initializer.ts @@ -1,12 +1,13 @@ import { getLogger } from "../log/utils" -import { CLOUDYPAD_PROVIDER } from "./const" -import { CreateCliArgs } from "./cli/command" -import { InputPrompter, UserVoluntaryInterruptionError } from "./cli/prompter" -import { InstanceManagerBuilder } from "./manager-builder" -import { StateInitializer } from "./state/initializer" +import { CLOUDYPAD_PROVIDER } from "../core/const" +import { CreateCliArgs } from "./command" +import { InputPrompter, inputToHumanReadableString, UserVoluntaryInterruptionError } from "./prompter" +import { InstanceManagerBuilder } from "../core/manager-builder" +import { StateInitializer } from "../core/state/initializer" import { confirm } from '@inquirer/prompts' import { AnalyticsManager } from "../tools/analytics/manager" -import { CommonInstanceInput } from "./state/state" +import { CommonInstanceInput } from "../core/state/state" +import { InstanceManager } from "../core/manager" export interface InstancerInitializerArgs { provider: CLOUDYPAD_PROVIDER @@ -90,17 +91,36 @@ export class InteractiveInstanceInitializer { return state } - private async doProvisioning(manager: any, instanceName: string, autoApprove?: boolean) { + private async doProvisioning(manager: InstanceManager, instanceName: string, autoApprove?: boolean) { this.logger.info(`Initializing ${instanceName}: provisioning...`) this.analyticsEvent("create_instance_start_provision") - + + let confirmCreation: boolean + if(autoApprove){ + confirmCreation = autoApprove + } else { + + const inputs = await manager.getInputs() + + confirmCreation = await confirm({ + message: `You are about to provision instance ${instanceName} with the following details:\n` + + ` ${inputToHumanReadableString(inputs)}` + + `\nDo you want to proceed?`, + default: true, + }) + } + + if (!confirmCreation) { + throw new Error(`Provision aborted for instance ${instanceName}.`); + } + await manager.provision({ autoApprove: autoApprove}) this.analyticsEvent("create_instance_finish_provision") this.logger.info(`Initializing ${instanceName}: provision done.}`) } - private async doConfiguration(manager: any, instanceName: string) { + private async doConfiguration(manager: InstanceManager, instanceName: string) { this.analyticsEvent("create_instance_start_configure") this.logger.info(`Initializing ${instanceName}: configuring...}`) @@ -110,7 +130,7 @@ export class InteractiveInstanceInitializer { this.logger.info(`Initializing ${instanceName}: configuration done.}`) } - private async doPairing(manager: any, instanceName: string, skipPairing: boolean, autoApprove: boolean) { + private async doPairing(manager: InstanceManager, instanceName: string, skipPairing: boolean, autoApprove: boolean) { const doPair = skipPairing ? false : autoApprove ? true : await confirm({ message: `Your instance is almost ready ! Do you want to pair Moonlight now?`, diff --git a/src/cli.ts b/src/cli/main.ts similarity index 86% rename from src/cli.ts rename to src/cli/main.ts index 6f3c0d36..6443a0bc 100755 --- a/src/cli.ts +++ b/src/cli/main.ts @@ -8,10 +8,10 @@ // - Initialize analytics client if enabled // -import { ConfigManager } from "./core/config/manager" +import { ConfigManager } from "../core/config/manager" import { buildProgram, shutdownAnalytics, cleanupAndExit, handleErrorAnalytics, logFullError } from "./program" -import { AnalyticsInitializer } from "./tools/analytics/initializer" -import { AnalyticsManager } from "./tools/analytics/manager" +import { AnalyticsInitializer } from "../tools/analytics/initializer" +import { AnalyticsManager } from "../tools/analytics/manager" async function main(){ try { diff --git a/src/program.ts b/src/cli/program.ts similarity index 90% rename from src/program.ts rename to src/cli/program.ts index 9ad0ab0a..7ceaa8f3 100644 --- a/src/program.ts +++ b/src/cli/program.ts @@ -1,13 +1,14 @@ import { Command } from '@commander-js/extra-typings'; -import { getLogger, setLogVerbosity } from './log/utils'; -import { InstanceManagerBuilder } from './core/manager-builder'; -import { GcpCliCommandGenerator } from './providers/gcp/cli'; -import { AzureCliCommandGenerator } from './providers/azure/cli'; -import { AwsCliCommandGenerator } from './providers/aws/cli'; -import { PaperspaceCliCommandGenerator } from './providers/paperspace/cli'; -import { AnalyticsManager } from './tools/analytics/manager'; -import { RUN_COMMAND_CONFIGURE, RUN_COMMAND_DESTROY, RUN_COMMAND_GET, RUN_COMMAND_LIST, RUN_COMMAND_PAIR, RUN_COMMAND_PROVISION, RUN_COMMAND_RESTART, RUN_COMMAND_START, RUN_COMMAND_STOP } from './tools/analytics/events'; -import { CLOUDYPAD_VERSION } from './core/const'; +import { getLogger, setLogVerbosity } from '../log/utils'; +import { InstanceManagerBuilder } from '../core/manager-builder'; +import { GcpCliCommandGenerator } from '../providers/gcp/cli'; +import { AzureCliCommandGenerator } from '../providers/azure/cli'; +import { AwsCliCommandGenerator } from '../providers/aws/cli'; +import { PaperspaceCliCommandGenerator } from '../providers/paperspace/cli'; +import { AnalyticsManager } from '../tools/analytics/manager'; +import { RUN_COMMAND_CONFIGURE, RUN_COMMAND_DESTROY, RUN_COMMAND_GET, RUN_COMMAND_LIST, RUN_COMMAND_PAIR, RUN_COMMAND_PROVISION, RUN_COMMAND_RESTART, RUN_COMMAND_START, RUN_COMMAND_STOP } from '../tools/analytics/events'; +import { CLOUDYPAD_VERSION } from '../core/const'; +import { confirm } from '@inquirer/prompts'; const logger = getLogger("program") @@ -220,6 +221,18 @@ export function buildProgram(){ try { analyticsClient.sendEvent(RUN_COMMAND_DESTROY) + let approveDestroy: boolean | undefined = opts?.yes + if(approveDestroy === undefined){ + approveDestroy = await confirm({ + message: `You are about to destroy instance '${name}'. Please confirm:`, + default: false, + }) + } + + if (!approveDestroy) { + throw new Error('Destroy aborted.') + } + const m = await new InstanceManagerBuilder().buildInstanceManager(name) await m.destroy({ autoApprove: opts.yes}) diff --git a/src/core/cli/prompter.ts b/src/cli/prompter.ts similarity index 88% rename from src/core/cli/prompter.ts rename to src/cli/prompter.ts index 516b7fe1..a47694c9 100644 --- a/src/core/cli/prompter.ts +++ b/src/cli/prompter.ts @@ -5,12 +5,12 @@ import { PartialDeep } from "type-fest" import { input, select, confirm, password } from '@inquirer/prompts'; import { ExitPromptError } from '@inquirer/core'; import lodash from 'lodash' -import { CommonInstanceInput } from "../state/state"; -import { getLogger } from "../../log/utils"; -import { PUBLIC_IP_TYPE, PUBLIC_IP_TYPE_DYNAMIC, PUBLIC_IP_TYPE_STATIC } from '../const'; +import { CommonInstanceInput, CommonProvisionInputV1, CommonProvisionOutputV1 } from "../core/state/state"; +import { getLogger } from "../log/utils"; +import { PUBLIC_IP_TYPE, PUBLIC_IP_TYPE_DYNAMIC, PUBLIC_IP_TYPE_STATIC } from '../core/const'; import { CreateCliArgs } from './command'; -import { StateLoader } from '../state/loader'; -import { CostAlertOptions } from '../provisioner'; +import { StateLoader } from '../core/state/loader'; +import { CostAlertOptions, InstanceProvisionerArgs } from '../core/provisioner'; const { kebabCase } = lodash export interface InputPrompter { @@ -478,4 +478,57 @@ export function costAlertCliArgsIntoConfig(args: { costAlert?: boolean, costLimi return undefined } +} + +/** + * Transform args into a human readable string, eg. + * { ssh: { key: '~/.ssh/id_ed25519', user: 'ubuntu' }, instanceName: 'my-instance' } into + * SSH Key: ~/.ssh/id_ed25519 + * SSH User: ubuntu + * Instance Name: my-instance + * + */ +export function inputToHumanReadableString(args: CommonInstanceInput): string { + + // Shamelessly generated by IA and edited/commented by hand + const humanReadableArgs = (obj?: any, parentKey?: string): string => { + + if(obj === undefined){ + return "" + } + + return Object.keys(obj).map(key => { + + // If parent key is not empty, add a dot between parent key and current key + // Otherwise, use current key (only for first level iteration) + const fullKey = parentKey ? `${parentKey} ${key}` : key; + + // If value is an object, recursively transform it + if (typeof obj[key] === 'object' && obj[key] !== null && obj[key] !== undefined) { + return humanReadableArgs(obj[key], fullKey); + } + + // Tranform original key into human readable key, with MAJ on first letter of each word + let humanReadableKey = fullKey.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()) + + if(humanReadableKey.startsWith("Ssh")){ + humanReadableKey = humanReadableKey.replace("Ssh", "SSH") + } + + if(humanReadableKey.startsWith("Ip")){ + humanReadableKey = humanReadableKey.replace("Ip", "IP") + } + + // Transform value into human readable value (don't transform raw type into string) + const humanReadableValue = + typeof obj[key] === 'boolean' ? obj[key] ? 'Yes' : 'No' : + obj[key] === undefined || obj[key] === null ? 'None' : + String(obj[key]) + return `${humanReadableKey}: ${humanReadableValue}`; + }).join('\n '); + }; + + const provision = humanReadableArgs(args.configuration) + const configuration = humanReadableArgs(args.provision) + return `${provision}\n ${configuration}` } \ No newline at end of file diff --git a/src/core/updater.ts b/src/cli/updater.ts similarity index 73% rename from src/core/updater.ts rename to src/cli/updater.ts index d47885f3..de72a474 100644 --- a/src/core/updater.ts +++ b/src/cli/updater.ts @@ -1,12 +1,13 @@ import { PartialDeep } from "type-fest" -import { InstanceStateV1 } from "./state/state" -import { StateWriter } from "./state/writer" +import { InstanceStateV1 } from "../core/state/state" +import { StateWriter } from "../core/state/writer" import { getLogger, Logger } from "../log/utils" -import { InstanceManagerBuilder } from "./manager-builder" -import { StateLoader } from "./state/loader" -import { UpdateCliArgs } from "./cli/command" -import { GenericStateParser } from "./state/parser" -import { AbstractInputPrompter } from "./cli/prompter" +import { InstanceManagerBuilder } from "../core/manager-builder" +import { StateLoader } from "../core/state/loader" +import { UpdateCliArgs } from "./command" +import { GenericStateParser } from "../core/state/parser" +import { AbstractInputPrompter, inputToHumanReadableString } from "./prompter" +import { confirm } from "@inquirer/prompts" import * as lodash from "lodash" export interface InstanceUpdaterArgs { @@ -82,6 +83,25 @@ export class InstanceUpdater getInstanceDetails(): Promise getStateJSON(): string - + getInputs(): Promise } export interface InstanceManagerArgs { @@ -233,4 +233,13 @@ export class GenericInstanceManager implements Insta public getStateJSON(){ return JSON.stringify(this.stateWriter.cloneState(), null, 2) } + + async getInputs(): Promise { + const state = this.stateWriter.cloneState() + return { + instanceName: state.name, + provision: state.provision.input, + configuration: state.configuration.input + } + } } \ No newline at end of file diff --git a/src/core/provisioner.ts b/src/core/provisioner.ts index 97ec5fbd..335bddd5 100644 --- a/src/core/provisioner.ts +++ b/src/core/provisioner.ts @@ -1,7 +1,6 @@ import { getLogger, Logger } from "../log/utils" import { CLOUDYPAD_SUNSHINE_PORTS, CLOUDYPAD_WOLF_PORTS, SimplePortDefinition } from "./const" import { CommonProvisionInputV1, CommonProvisionOutputV1, CommonConfigurationInputV1 } from "./state/state" -import { confirm } from '@inquirer/prompts' export interface InstanceProvisionOptions { autoApprove?: boolean @@ -59,25 +58,11 @@ export abstract class AbstractInstanceProvisioner { - this.logger.info(`Provisioning instance ${this.args.instanceName}`); - return await this.doProvision(opts); + this.logger.info(`Provisioning instance ${this.args.instanceName}`) + return await this.doProvision(opts) } async destroy(opts?: DestroyOptions): Promise { - this.logger.info(`Destroying instance: ${this.args.instanceName}`) - - let autoApprove = opts?.autoApprove - if(opts?.autoApprove === undefined){ - autoApprove = await confirm({ - message: `You are about to destroy instance '${this.args.instanceName}'. Please confirm:`, - default: false, - }) - } - - if (!autoApprove) { - throw new Error('Destroy aborted.') - } - this.logger.info(`Destroying instance ${this.args.instanceName}...`) await this.doDestroy() @@ -89,59 +74,6 @@ export abstract class AbstractInstanceProvisioner; protected abstract doDestroy(): Promise; - /** - * Transform args into a human readable string, eg. - * { ssh: { key: '~/.ssh/id_ed25519', user: 'ubuntu' }, instanceName: 'my-instance' } into - * SSH Key: ~/.ssh/id_ed25519 - * SSH User: ubuntu - * Instance Name: my-instance - * - */ - protected inputToHumanReadableString(args: InstanceProvisionerArgs): string { - - // Shamelessly generated by IA and edited/commented by hand - const humanReadableArgs = (obj?: any, parentKey?: string): string => { - - if(obj === undefined){ - return "" - } - - return Object.keys(obj).map(key => { - - // If parent key is not empty, add a dot between parent key and current key - // Otherwise, use current key (only for first level iteration) - const fullKey = parentKey ? `${parentKey} ${key}` : key; - - // If value is an object, recursively transform it - if (typeof obj[key] === 'object' && obj[key] !== null && obj[key] !== undefined) { - return humanReadableArgs(obj[key], fullKey); - } - - // Tranform original key into human readable key, with MAJ on first letter of each word - let humanReadableKey = fullKey.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()) - - if(humanReadableKey.startsWith("Ssh")){ - humanReadableKey = humanReadableKey.replace("Ssh", "SSH") - } - - if(humanReadableKey.startsWith("Ip")){ - humanReadableKey = humanReadableKey.replace("Ip", "IP") - } - - // Transform value into human readable value (don't transform raw type into string) - const humanReadableValue = - typeof obj[key] === 'boolean' ? obj[key] ? 'Yes' : 'No' : - obj[key] === undefined || obj[key] === null ? 'None' : - String(obj[key]) - return `${humanReadableKey}: ${humanReadableValue}`; - }).join('\n '); - }; - - const provision = humanReadableArgs(this.args.provisionInput) - const configuration = humanReadableArgs(this.args.configurationInput) - return `${provision}\n ${configuration}` - } - /** * Return ports to expose on this instance for its current streaming server */ diff --git a/src/providers/aws/cli.ts b/src/providers/aws/cli.ts index a6ca2db2..dff688d5 100644 --- a/src/providers/aws/cli.ts +++ b/src/providers/aws/cli.ts @@ -2,15 +2,15 @@ import { AwsInstanceInput, AwsInstanceStateV1, AwsStateParser } from "./state" import { CommonInstanceInput } from "../../core/state/state" import { input, select, confirm } from '@inquirer/prompts'; import { AwsClient, EC2_QUOTA_CODE_ALL_G_AND_VT_SPOT_INSTANCES, EC2_QUOTA_CODE_RUNNING_ON_DEMAND_G_AND_VT_INSTANCES } from "../../tools/aws"; -import { AbstractInputPrompter, costAlertCliArgsIntoConfig, PromptOptions } from "../../core/cli/prompter"; +import { AbstractInputPrompter, costAlertCliArgsIntoConfig, PromptOptions } from "../../cli/prompter"; import lodash from 'lodash' -import { CLI_OPTION_COST_NOTIFICATION_EMAIL, CLI_OPTION_COST_ALERT, CLI_OPTION_COST_LIMIT, CLI_OPTION_DISK_SIZE, CLI_OPTION_PUBLIC_IP_TYPE, CLI_OPTION_SPOT, CliCommandGenerator, CreateCliArgs, UpdateCliArgs, CLI_OPTION_STREAMING_SERVER, CLI_OPTION_SUNSHINE_PASSWORD, CLI_OPTION_SUNSHINE_USERNAME, CLI_OPTION_SUNSHINE_IMAGE_REGISTRY, CLI_OPTION_SUNSHINE_IMAGE_TAG } from "../../core/cli/command"; +import { CLI_OPTION_COST_NOTIFICATION_EMAIL, CLI_OPTION_COST_ALERT, CLI_OPTION_COST_LIMIT, CLI_OPTION_DISK_SIZE, CLI_OPTION_PUBLIC_IP_TYPE, CLI_OPTION_SPOT, CliCommandGenerator, CreateCliArgs, UpdateCliArgs, CLI_OPTION_STREAMING_SERVER, CLI_OPTION_SUNSHINE_PASSWORD, CLI_OPTION_SUNSHINE_USERNAME, CLI_OPTION_SUNSHINE_IMAGE_REGISTRY, CLI_OPTION_SUNSHINE_IMAGE_TAG } from "../../cli/command"; import { CLOUDYPAD_PROVIDER_AWS, PUBLIC_IP_TYPE } from "../../core/const"; -import { InteractiveInstanceInitializer } from "../../core/initializer"; +import { InteractiveInstanceInitializer } from "../../cli/initializer"; import { PartialDeep } from "type-fest"; import { RUN_COMMAND_CREATE, RUN_COMMAND_UPDATE } from "../../tools/analytics/events"; -import { InstanceUpdater } from "../../core/updater"; -import { cleanupAndExit, handleErrorAnalytics, logFullError } from "../../program"; +import { InstanceUpdater } from "../../cli/updater"; +import { cleanupAndExit, handleErrorAnalytics, logFullError } from "../../cli/program"; export interface AwsCreateCliArgs extends CreateCliArgs { spot?: boolean diff --git a/src/providers/aws/provisioner.ts b/src/providers/aws/provisioner.ts index f0e34898..e7a5f193 100644 --- a/src/providers/aws/provisioner.ts +++ b/src/providers/aws/provisioner.ts @@ -1,5 +1,4 @@ import { SshKeyLoader } from '../../tools/ssh'; -import { confirm } from '@inquirer/prompts'; import { AwsPulumiClient, PulumiStackConfigAws } from './pulumi'; import { AbstractInstanceProvisioner, InstanceProvisionerArgs, InstanceProvisionOptions } from '../../core/provisioner'; import { AwsClient } from '../../tools/aws'; @@ -19,23 +18,6 @@ export class AwsProvisioner extends AbstractInstanceProvisioner { diff --git a/test/unit/azure/cli.spec.ts b/test/unit/azure/cli.spec.ts index 3729b3af..c254332c 100644 --- a/test/unit/azure/cli.spec.ts +++ b/test/unit/azure/cli.spec.ts @@ -5,7 +5,7 @@ import { DEFAULT_COMMON_CLI_ARGS, DEFAULT_COMMON_INPUT } from '../utils'; import { AzureCreateCliArgs, AzureInputPrompter } from '../../../src/providers/azure/cli'; import { PartialDeep } from 'type-fest'; import lodash from 'lodash' -import { STREAMING_SERVER_SUNSHINE } from '../../../src/core/cli/prompter'; +import { STREAMING_SERVER_SUNSHINE } from '../../../src/cli/prompter'; describe('Azure input prompter', () => { diff --git a/test/unit/core/cli.spec.ts b/test/unit/core/cli.spec.ts index 39c5e03e..9c1bd66c 100644 --- a/test/unit/core/cli.spec.ts +++ b/test/unit/core/cli.spec.ts @@ -1,5 +1,5 @@ import * as assert from 'assert'; -import { costAlertCliArgsIntoConfig } from '../../../src/core/cli/prompter'; +import { costAlertCliArgsIntoConfig } from '../../../src/cli/prompter'; describe('costAlertCliArgsIntoConfig', () => { diff --git a/test/unit/core/initializer.spec.ts b/test/unit/core/initializer.spec.ts index ba6100e0..844e7293 100644 --- a/test/unit/core/initializer.spec.ts +++ b/test/unit/core/initializer.spec.ts @@ -2,9 +2,9 @@ import * as assert from 'assert'; import { GcpInstanceInput } from '../../../src/providers/gcp/state'; import { CLOUDYPAD_PROVIDER_GCP, PUBLIC_IP_TYPE_STATIC } from '../../../src/core/const'; import { DEFAULT_COMMON_INPUT } from '../utils'; -import { InteractiveInstanceInitializer } from '../../../src/core/initializer'; +import { InteractiveInstanceInitializer } from '../../../src/cli/initializer'; import { GcpCreateCliArgs, GcpInputPrompter } from '../../../src/providers/gcp/cli'; -import { STREAMING_SERVER_SUNSHINE } from '../../../src/core/cli/prompter'; +import { STREAMING_SERVER_SUNSHINE } from '../../../src/cli/prompter'; describe('Instance initializer', () => { diff --git a/test/unit/core/updater.spec.ts b/test/unit/core/updater.spec.ts index 57e79c99..ace0638c 100644 --- a/test/unit/core/updater.spec.ts +++ b/test/unit/core/updater.spec.ts @@ -1,14 +1,14 @@ import * as assert from 'assert'; import { DEFAULT_COMMON_INPUT, DUMMY_AWS_PULUMI_OUTPUT, DUMMY_SSH_KEY_PATH, loadDumyAnonymousStateV1 } from '../utils'; import { StateLoader } from '../../../src/core/state/loader'; -import { InstanceUpdater } from '../../../src/core/updater'; +import { InstanceUpdater } from '../../../src/cli/updater'; import { InstanceStateV1 } from '../../../src/core/state/state'; import { StateWriter } from '../../../src/core/state/writer'; import lodash from 'lodash' import { AwsUpdateCliArgs } from '../../../src/providers/aws/cli'; import { AwsInputPrompter } from '../../../src/providers/aws/cli'; import { AwsInstanceStateV1, AwsStateParser } from '../../../src/providers/aws/state'; -import { STREAMING_SERVER_WOLF } from '../../../src/core/cli/prompter'; +import { STREAMING_SERVER_WOLF } from '../../../src/cli/prompter'; describe('InstanceUpdater', () => { diff --git a/test/unit/gcp/cli.spec.ts b/test/unit/gcp/cli.spec.ts index 0a11a5d5..446e0937 100644 --- a/test/unit/gcp/cli.spec.ts +++ b/test/unit/gcp/cli.spec.ts @@ -6,7 +6,7 @@ import { GcpCreateCliArgs, GcpInputPrompter } from '../../../src/providers/gcp/c import lodash from 'lodash' import { PartialDeep } from 'type-fest'; import { StateWriter } from '../../../src/core/state/writer'; -import { STREAMING_SERVER_SUNSHINE } from '../../../src/core/cli/prompter'; +import { STREAMING_SERVER_SUNSHINE } from '../../../src/cli/prompter'; describe('GCP input prompter', () => { diff --git a/test/unit/utils.ts b/test/unit/utils.ts index d239cbea..aa55e4aa 100644 --- a/test/unit/utils.ts +++ b/test/unit/utils.ts @@ -9,8 +9,8 @@ import { PaperspaceMachine } from "../../src/providers/paperspace/client/client" import { PUBLIC_IP_TYPE_STATIC } from "../../src/core/const"; import { tmpdir } from "os"; import { AnonymousStateParser } from "../../src/core/state/parser"; -import { STREAMING_SERVER_SUNSHINE } from '../../src/core/cli/prompter'; -import { CreateCliArgs } from "../../src/core/cli/command"; +import { STREAMING_SERVER_SUNSHINE } from '../../src/cli/prompter'; +import { CreateCliArgs } from "../../src/cli/command"; export const DEFAULT_COMMON_INPUT: CommonInstanceInput = { instanceName: "dummy-instance", From 8b8787d7193c877d32fd97ae824af96a08c5a417 Mon Sep 17 00:00:00 2001 From: Pierre beucher Date: Tue, 25 Feb 2025 15:43:24 +0100 Subject: [PATCH 2/3] chore: bump Ansible deps versions --- ansible/requirements.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ansible/requirements.yml b/ansible/requirements.yml index 5430395d..bb4f553d 100644 --- a/ansible/requirements.yml +++ b/ansible/requirements.yml @@ -1,10 +1,10 @@ roles: - name: geerlingguy.docker - version: "7.3.0" + version: "7.4.5" collections: - name: community.docker - version: "3.10.4" + version: "4.3.1" - name: community.general - version: "9.1.0" + version: "10.3.0" - name: ansible.posix version: "2.0.0" \ No newline at end of file From ea375d13024c60e3a55ffc89d9fdf203c618d84b Mon Sep 17 00:00:00 2001 From: Pierre beucher Date: Tue, 25 Feb 2025 15:44:03 +0100 Subject: [PATCH 3/3] chore: cleanup Scaleway buggy apt sources --- ansible/roles/prepare-install/tasks/main.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ansible/roles/prepare-install/tasks/main.yml b/ansible/roles/prepare-install/tasks/main.yml index 5bcb48fb..af06f249 100644 --- a/ansible/roles/prepare-install/tasks/main.yml +++ b/ansible/roles/prepare-install/tasks/main.yml @@ -2,8 +2,15 @@ # On Paperspace with Ubuntu 22.04, the apt source for Paperspace is buggy (invalid GPG key) # causing subsequent failure on apt cache update # removing it here to avoid issues -- name: Remove paperspace apt source (if any) +- name: Remove unwanted apt sources (if any) become: true file: state: absent - path: /etc/apt/sources.list.d/paperspace.list \ No newline at end of file + path: "{{ item }}" + loop: + # Paperspace, out of date, cause apt update failure + - /etc/apt/sources.list.d/paperspace.list + + # Scaleway, out of date, cause apt update failure + - /etc/apt/sources.list.d/nvidia-docker.list + - /etc/apt/sources.list.d/cuda.list