import { Sandbox, Volume } from 'e2b'
const [sourceName, destName] = process.argv.slice(2)
if (!sourceName || !destName) {
throw new Error('Usage: copy-volume <source-volume> <dest-volume>')
}
async function findVolumeByName(name: string) {
const volumes = await Volume.list()
return volumes.find((v) => v.name === name) ?? null
}
const sourceInfo = await findVolumeByName(sourceName)
if (!sourceInfo) {
throw new Error(`Source volume "${sourceName}" does not exist`)
}
const sourceVolume = await Volume.connect(sourceInfo.volumeId)
const destInfo = await findVolumeByName(destName)
const destVolume = destInfo
? await Volume.connect(destInfo.volumeId)
: await Volume.create(destName)
function voltype(token: string): string {
// JWT payloads are base64url and often omit padding, so normalize before decoding
let segment = token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/')
segment += '='.repeat((4 - (segment.length % 4)) % 4)
const payload = JSON.parse(atob(segment))
return payload.voltype
}
console.log(`Source volume type: ${voltype(sourceVolume.token)}`)
console.log(`Destination volume type: ${voltype(destVolume.token)}`)
const sandbox = await Sandbox.create({
volumeMounts: {
'/mnt/source': sourceVolume,
'/mnt/dest': destVolume,
},
})
try {
const install = await sandbox.commands.run(
'sudo apt-get update && sudo apt-get install -y rsync',
)
if (install.exitCode !== 0) {
throw new Error(`rsync install failed: ${install.stderr}`)
}
const result = await sandbox.commands.run('rsync -a /mnt/source/ /mnt/dest/')
if (result.exitCode !== 0) {
throw new Error(`Copy failed: ${result.stderr}`)
}
const listing = await sandbox.commands.run('ls -la /mnt/dest')
console.log(listing.stdout)
} finally {
await sandbox.kill()
}