* Writes files to the volume using a temporary Alpine container. * * @param files - Map of filename to content
(files: Record<string, string | Buffer>)
| 161 | * @param files - Map of filename to content |
| 162 | */ |
| 163 | private async writeFiles(files: Record<string, string | Buffer>): Promise<void> { |
| 164 | if (!this.volumeName) { |
| 165 | throw new ConfigurationError('Volume not initialized', { |
| 166 | details: { tenantId: this.tenantId, runId: this.runId }, |
| 167 | }); |
| 168 | } |
| 169 | |
| 170 | for (const [filename, content] of Object.entries(files)) { |
| 171 | // Strict validation to prevent path traversal and shell injection |
| 172 | this.validateFilename(filename); |
| 173 | |
| 174 | const contentString = typeof content === 'string' ? content : content.toString('utf-8'); |
| 175 | |
| 176 | // Use docker run with stdin to write the file |
| 177 | await this.writeFileToVolume(filename, contentString); |
| 178 | } |
| 179 | |
| 180 | // Make the volume directory writable by all users (including nonroot containers) |
| 181 | // This is safe because volumes are isolated per-run |
| 182 | await this.setVolumePermissions(); |
| 183 | } |
| 184 | |
| 185 | /** |
| 186 | * Sets permissions on the volume directory to allow nonroot containers to write. |
no test coverage detected