@@ -96,6 +96,7 @@ async function runWithConcurrency(tasks: Array<() => Promise<void>>, limit: numb
9696async function streamDirToHost (
9797 srcDir : string ,
9898 excludePatterns : string [ ] ,
99+ name : string ,
99100 conn : SSHKeyConnection ,
100101 destBase : string ,
101102 compress : boolean ,
@@ -109,7 +110,7 @@ async function streamDirToHost(
109110 const result = await done ;
110111 if ( result . exitCode !== 0 ) {
111112 throw new DeployError (
112- `upload: tar extraction failed at ${ destBase } on ${ conn . host } : ${ result . stderr . trim ( ) || `exit ${ result . exitCode } ` } ` ,
113+ `upload: tar extraction failed at ${ destBase } on ${ name } : ${ result . stderr . trim ( ) || `exit ${ result . exitCode } ` } ` ,
113114 ErrorCode . DEPLOY_FAILED ,
114115 ) ;
115116 }
@@ -155,7 +156,7 @@ export async function uploadFiles(ctx: DeployContext): Promise<UploadRollbackPla
155156
156157 // Step 1: backup existing remote dir + ensure dest exists (all hosts in parallel)
157158 await Promise . all ( plan . hosts . map ( async hostState => {
158- const { conn } = hostState ;
159+ const { name , conn } = hostState ;
159160 const backupPath = `${ backupBaseDir } /${ destBase . replace ( / ^ \/ / , '' ) } .tar.gz` ;
160161
161162 await sshExec ( conn , `mkdir -p '${ dirname ( backupPath ) } '` ) ;
@@ -173,7 +174,7 @@ export async function uploadFiles(ctx: DeployContext): Promise<UploadRollbackPla
173174 const mkdirResult = await sshExec ( conn , `mkdir -p '${ destBase } '` ) ;
174175 if ( mkdirResult . exitCode !== 0 ) {
175176 throw new DeployError (
176- `upload: cannot create ${ destBase } on ${ conn . host } : ${ mkdirResult . stderr . trim ( ) || `exit ${ mkdirResult . exitCode } ` } ` ,
177+ `upload: cannot create ${ destBase } on ${ name } : ${ mkdirResult . stderr . trim ( ) || `exit ${ mkdirResult . exitCode } ` } ` ,
177178 ErrorCode . DEPLOY_FAILED ,
178179 `The deploy user must own the destination directory. Run once on the server as root:\n mkdir -p '${ destBase } ' && chown ${ conn . user } : '${ destBase } '` ,
179180 ) ;
@@ -195,7 +196,7 @@ export async function uploadFiles(ctx: DeployContext): Promise<UploadRollbackPla
195196 const spinner = createSpinner ( ) ;
196197 spinner . start ( `upload: ${ upload . src } / -> ${ name } :${ destBase } /${ compressFlag } ` ) ;
197198 let lastTick = 0 ;
198- await streamDirToHost ( srcAbs , excludePatterns , conn , destBase , compress ,
199+ await streamDirToHost ( srcAbs , excludePatterns , name , conn , destBase , compress ,
199200 ( bytesProcessed ) => {
200201 const now = Date . now ( ) ;
201202 if ( now - lastTick < 250 ) return ;
@@ -212,7 +213,7 @@ export async function uploadFiles(ctx: DeployContext): Promise<UploadRollbackPla
212213 // Multiple hosts: stream independently to each host in parallel — no RAM buffer
213214 printDim ( `upload: ${ upload . src } / -> ${ destBase } /${ compressFlag } [${ plan . hosts . length } hosts]` ) ;
214215 await Promise . all ( plan . hosts . map ( async ( { name, conn } ) => {
215- await streamDirToHost ( srcAbs , excludePatterns , conn , destBase , compress ) ;
216+ await streamDirToHost ( srcAbs , excludePatterns , name , conn , destBase , compress ) ;
216217 printDim ( ` upload: -> ${ name } :${ destBase } / done` ) ;
217218 if ( upload . permissions ) await sshExec ( conn , `chmod -R ${ upload . permissions } '${ destBase } '` ) ;
218219 if ( upload . owner ) await sshExec ( conn , `chown -R ${ upload . owner } '${ destBase } '` ) ;
@@ -235,7 +236,7 @@ export async function uploadFiles(ctx: DeployContext): Promise<UploadRollbackPla
235236 ) ) ;
236237
237238 const tasks = plan . hosts . map ( hostState => async ( ) => {
238- const { conn } = hostState ;
239+ const { name , conn } = hostState ;
239240
240241 const backupResult = await sshExec ( conn ,
241242 `if test -f '${ destPath } '; then cp '${ destPath } ' '${ backupPath } ' && echo existed; else echo missing; fi` ,
@@ -252,20 +253,20 @@ export async function uploadFiles(ctx: DeployContext): Promise<UploadRollbackPla
252253 if ( result . exitCode !== 0 ) {
253254 const detail = result . stderr . trim ( ) || result . stdout . trim ( ) || `exit code ${ result . exitCode } ` ;
254255 throw new DeployError (
255- `upload: failed to transfer ${ upload . src } to ${ conn . host } : ${ detail } ` ,
256+ `upload: failed to transfer ${ upload . src } to ${ name } : ${ detail } ` ,
256257 ErrorCode . DEPLOY_FAILED ,
257- `Ensure ${ conn . user } has write access to ${ dirname ( destPath ) } on ${ conn . host } . Run once as root:\n mkdir -p '${ dirname ( destPath ) } ' && chown ${ conn . user } : '${ dirname ( destPath ) } '` ,
258+ `Ensure ${ conn . user } has write access to ${ dirname ( destPath ) } on ${ name } . Run once as root:\n mkdir -p '${ dirname ( destPath ) } ' && chown ${ conn . user } : '${ dirname ( destPath ) } '` ,
258259 ) ;
259260 }
260261
261262 if ( upload . permissions ) {
262263 const r = await sshExec ( conn , `chmod ${ upload . permissions } '${ destPath } '` ) ;
263- if ( r . exitCode !== 0 ) throw new DeployError ( `upload: chmod failed on ${ destPath } (${ conn . host } )` , ErrorCode . DEPLOY_FAILED ) ;
264+ if ( r . exitCode !== 0 ) throw new DeployError ( `upload: chmod failed on ${ destPath } (${ name } )` , ErrorCode . DEPLOY_FAILED ) ;
264265 }
265266 if ( upload . owner ) {
266267 const r = await sshExec ( conn , `chown ${ upload . owner } '${ destPath } '` ) ;
267268 if ( r . exitCode !== 0 ) throw new DeployError (
268- `upload: chown failed on ${ destPath } (${ conn . host } )` ,
269+ `upload: chown failed on ${ destPath } (${ name } )` ,
269270 ErrorCode . DEPLOY_FAILED ,
270271 `Grant chown rights:\n echo '${ conn . user } ALL=(ALL) NOPASSWD: /bin/chown * ${ dirname ( destPath ) } /*' >> /etc/sudoers.d/dockflow` ,
271272 ) ;
0 commit comments