functions/Export-DiskImageToContainerImage.ps1
# <copyright file="Export-DiskImageToContainerImage.ps1" company="Endjin Limited"> # Copyright (c) Endjin Limited. All rights reserved. # </copyright> function Export-DiskImageToContainerImage { <# .SYNOPSIS Packages a Linux raw disk image inside a container image as a single file. .DESCRIPTION Copies the specified Linux raw disk image into a new container image. This can be useful as a means of versioning and distributing such disk images as part of a process for managing Firecracker virtual machine disk image templates. .PARAMETER SourceDiskImagePath The path to the disk image file that will be added to the container image. .PARAMETER DestinationContainerImageName The repository, name and tag of the container image that will be built. .PARAMETER Configuration When specified as 'Release', the built image be based on the 'scratch' image (i.e. empty) to optimise its size. When not specified as 'Release' (e.g. 'Debug' or blank), the built image be based on the 'busybox' image, to provide a minimal shell environment to support diagnosing issues with the container image. .EXAMPLE Export-DiskImageToContainerImage -SourceDiskImagePath "C:\Images\mydiskimage.img" ` -ContainerImageName "mycontainerimage:latest" This command create a docker image containing the single file: `/mydiskimage.img`. .EXAMPLE Export-DiskImageToContainerImage -SourceDiskImagePath "C:\Images\mydiskimage.img" ` -ContainerImageName "mycontainerimage:latest" ` -Configuration "Debug" This command create a docker image that includes the file `/mydiskimage.img` as well as a minimal shell environment. .NOTES This function requires Docker to be installed and running on the host system. #> [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string] $SourceDiskImagePath, [Parameter(Mandatory=$true)] [string] $DestinationContainerImageName, [Parameter()] [string] $Configuration = "Release" ) if ($IsWindows) { throw "This function is only supported on Linux-like operating systems" } @( "docker" ) | ForEach-Object { if (!(Get-Command $_ -ErrorAction Ignore)) { throw "The '$_' command is required to run this function" } } # Ensure errors from external tools are propagated to the script - this overridden # value will fall out of scope when the function completes $PSNativeCommandUseErrorActionPreference = $true $basePath = Split-Path -Parent $SourceDiskImagePath $baseName = Split-Path -LeafBase $SourceDiskImagePath # - Use 'busybox' for non-Release builds to make it easier to inspect the contents # of the container image, as it provides a minimal shell # - Use 'scratch' for Release builds to optimise for image size $diskImageBase = ($Configuration -ne "Release") ? "busybox" : "scratch" $tempDockerfile = @" FROM $diskImageBase COPY $baseName.img /rootfs.img "@ $tempDockerfileName = "Dockerfile.diskimage" $tempDockerFilePath = Join-Path ([IO.Path]::GetTempPath()) $tempDockerfileName Set-Content -Path $tempDockerFilePath -Value $tempDockerfile try { $tagVersion = ($ContainerImageVersionOverride -eq "") ? $GitVersion.SemVer : $ContainerImageVersionOverride Write-Host "Building '$DestinationContainerImageName-rootfs' with Docker" $diskImageContainerTag = "$DestinationContainerImageName-rootfs:$tagVersion" & docker build -t $diskImageContainerTag ` -f $tempDockerFilePath ` $basePath | Write-Host } finally { Remove-Item $tempDockerFilePath -Force } return $diskImageContainerTag } |