1- import { CreatePlan , DestroyPlan , Resource , ResourceSettings , SpawnStatus , getPty , z } from 'codify-plugin-lib' ;
1+ import {
2+ CreatePlan ,
3+ DestroyPlan ,
4+ Resource ,
5+ ResourceSettings ,
6+ SpawnStatus ,
7+ getPty ,
8+ z ,
9+ ParameterChange , ModifyPlan
10+ } from 'codify-plugin-lib' ;
211import { OS } from 'codify-schemas' ;
312
413const schema = z . object ( {
@@ -20,10 +29,6 @@ const schema = z.object({
2029 . string ( )
2130 . describe ( 'Sets the display size in format <width>x<height>. For example 1200x800' )
2231 . optional ( ) ,
23- disk : z
24- . string ( )
25- . describe ( 'The location of the disk, which is a path' )
26- . optional ( ) ,
2732 diskSize : z
2833 . number ( )
2934 . describe ( 'The disk size in GB. Disk size can only be increased and not decreased' )
@@ -40,7 +45,10 @@ export class TartVmResource extends Resource<TartVmConfig> {
4045 dependencies : [ 'tart' ] ,
4146 schema,
4247 parameterSettings : {
43- disk : { type : 'directory' } ,
48+ diskSize : { type : 'number' , canModify : true } ,
49+ memory : { type : 'number' , canModify : true } ,
50+ cpu : { type : 'number' , canModify : true } ,
51+ display : { type : 'string' , canModify : true } ,
4452 } ,
4553 } ;
4654 }
@@ -64,10 +72,18 @@ export class TartVmResource extends Resource<TartVmConfig> {
6472 // Parse the JSON output to get the list of VMs
6573 try {
6674 const vmList = JSON . parse ( data ) ;
75+ console . log ( 'VM list:' , vmList ) ;
76+ console . log ( 'Local name:' , parameters . localName ) ;
77+ console . log ( 'Includes VM:' , vmList . some ( ( vm : { Name : string } ) => vm . Name === parameters . localName ) ) ;
78+
6779 if ( ! vmList . some ( ( vm : { Name : string } ) => vm . Name === parameters . localName ) ) {
80+ console . log ( 'Not found! returning null' )
81+
6882 return null ;
6983 }
70- } catch {
84+ } catch ( e ) {
85+ console . error ( 'Error parsing JSON:' , e ) ;
86+
7187 // If JSON parsing fails, return null
7288 return null ;
7389 }
@@ -77,40 +93,24 @@ export class TartVmResource extends Resource<TartVmConfig> {
7793 sourceName : parameters . sourceName ,
7894 }
7995
80- // Get VM configuration using tart get
81- const { status : getStatus , data : getData } = await $ . spawnSafe ( `tart get ${ parameters . localName } ` ) ;
82- if ( getStatus === SpawnStatus . SUCCESS ) {
83- // Parse the output to extract configuration
84- const lines = getData . split ( '\n' ) ;
85-
86- for ( const line of lines ) {
87- if ( line . includes ( 'memory:' ) ) {
88- const match = line . match ( / m e m o r y : \s * ( \d + ) / ) ;
89- if ( match ) {
90- result . memory = Number . parseInt ( match [ 1 ] , 10 ) ;
91- }
92- } else if ( line . includes ( 'cpu:' ) ) {
93- const match = line . match ( / c p u : \s * ( \d + ) / ) ;
94- if ( match ) {
95- result . cpu = Number . parseInt ( match [ 1 ] , 10 ) ;
96- }
97- } else if ( line . includes ( 'display:' ) ) {
98- const match = line . match ( / d i s p l a y : \s * ( \d + x \d + ) / ) ;
99- if ( match ) {
100- result . display = match [ 1 ] ;
101- }
102- } else if ( line . includes ( 'disk:' ) ) {
103- const match = line . match ( / d i s k : \s * ( .+ ) / ) ;
104- if ( match ) {
105- result . disk = match [ 1 ] . trim ( ) ;
106- }
107- } else if ( line . includes ( 'disk-size:' ) ) {
108- const match = line . match ( / d i s k - s i z e : \s * ( \d + ) / ) ;
109- if ( match ) {
110- result . diskSize = Number . parseInt ( match [ 1 ] , 10 ) ;
111- }
112- }
96+ try {
97+ // Get VM configuration using tart get
98+ const { status : getStatus , data : getData } = await $ . spawnSafe ( `tart get ${ parameters . localName } --format json` ) ;
99+ console . log ( 'Get data:' , getData ) ;
100+ console . log ( 'Status:' , getStatus ) ;
101+
102+ if ( getStatus === SpawnStatus . SUCCESS ) {
103+ // Parse the output to extract configuration
104+
105+ const vmInfo = JSON . parse ( getData ) ;
106+ result . memory = vmInfo . Memory ;
107+ result . cpu = vmInfo . CPU ;
108+ result . display = vmInfo . Display ;
109+ result . diskSize = vmInfo . Disk ;
113110 }
111+ } catch {
112+ // If JSON parsing fails, return null
113+ return result ;
114114 }
115115
116116 return result ;
@@ -120,7 +120,7 @@ export class TartVmResource extends Resource<TartVmConfig> {
120120 const $ = getPty ( ) ;
121121
122122 // Determine the VM name
123- const vmName = plan . desiredConfig . localName || this . extractNameFromSource ( plan . desiredConfig . sourceName ) ;
123+ const vmName = plan . desiredConfig . localName ;
124124
125125 if ( ! vmName ) {
126126 throw new Error ( 'Unable to determine VM name. Please provide either "name" or a valid "sourceName"' ) ;
@@ -144,42 +144,53 @@ export class TartVmResource extends Resource<TartVmConfig> {
144144 setCommands . push ( `--display ${ plan . desiredConfig . display } ` ) ;
145145 }
146146
147- if ( plan . desiredConfig . disk ) {
148- setCommands . push ( `--disk ${ plan . desiredConfig . disk } ` ) ;
147+ if ( plan . desiredConfig . diskSize ) {
148+ setCommands . push ( `--disk-size ${ plan . desiredConfig . diskSize } ` ) ;
149+ }
150+
151+ if ( setCommands . length > 0 ) {
152+ await $ . spawn ( `tart set ${ vmName } ${ setCommands . join ( ' ' ) } ` , { interactive : true } ) ;
153+ }
154+ }
155+
156+ async modify ( pc : ParameterChange < TartVmConfig > , plan : ModifyPlan < TartVmConfig > ) : Promise < void > {
157+ const $ = getPty ( ) ;
158+
159+ // Set VM parameters if specified
160+ const setCommands : string [ ] = [ ] ;
161+
162+ if ( plan . desiredConfig . memory ) {
163+ setCommands . push ( `--memory ${ plan . desiredConfig . memory } ` ) ;
164+ }
165+
166+ if ( plan . desiredConfig . cpu ) {
167+ setCommands . push ( `--cpu ${ plan . desiredConfig . cpu } ` ) ;
168+ }
169+
170+ if ( plan . desiredConfig . display ) {
171+ setCommands . push ( `--display ${ plan . desiredConfig . display } ` ) ;
149172 }
150173
151174 if ( plan . desiredConfig . diskSize ) {
152175 setCommands . push ( `--disk-size ${ plan . desiredConfig . diskSize } ` ) ;
153176 }
154177
155178 if ( setCommands . length > 0 ) {
156- await $ . spawn ( `tart set ${ vmName } ${ setCommands . join ( ' ' ) } ` , { interactive : true } ) ;
179+ await $ . spawn ( `tart set ${ plan . desiredConfig . localName } ${ setCommands . join ( ' ' ) } ` , { interactive : true } ) ;
157180 }
158181 }
159182
160183 async destroy ( plan : DestroyPlan < TartVmConfig > ) : Promise < void > {
161184 const $ = getPty ( ) ;
162185
163186 // Determine the VM name
164- const vmName = plan . currentConfig . localName || this . extractNameFromSource ( plan . currentConfig . sourceName ) ;
187+ const vmName = plan . currentConfig . localName ;
165188
166189 if ( ! vmName ) {
167190 throw new Error ( 'Unable to determine VM name' ) ;
168191 }
169192
170193 // Delete the VM
171- await $ . spawn ( `tart delete ${ vmName } ` , { interactive : true } ) ;
172- }
173-
174- private extractNameFromSource ( sourceName : string ) : string {
175- // Extract the name from the source
176- // For example: ghcr.io/user/image:tag -> image:tag or just image
177- const parts = sourceName . split ( '/' ) ;
178- const lastPart = parts . at ( - 1 ) ! ;
179-
180- // Remove the tag if present
181- const nameWithoutTag = lastPart . split ( ':' ) [ 0 ] ;
182-
183- return nameWithoutTag ;
194+ await $ . spawnSafe ( `tart delete ${ vmName } ` , { interactive : true } ) ;
184195 }
185196}
0 commit comments