DockerMachine.psm1
<#
.Synopsis Create new, list or load existing Docker Machine environments. #> #region Init Module $ErrorActionPreference = "Stop"; $DEFAULT_PORT = '443'; Try { & docker-machine | Out-Null } Catch { throw "docker-machine is not installed" } #endregion #region Private Functions function Get-ConfigTemplate ($targetHost, $envName, $envDir) { # Generate target address $targetHost = $targetHost -replace 'tcp://',''; if ($targetHost.Contains(':')) { $targetAddress = $targetHost; $targetHost = $targetHost.Split(':')[0]; } else { $targetAddress = "${targetHost}:${DEFAULT_PORT}"; } # Return config return @" { "ConfigVersion": 3, "Driver": { "IPAddress": "$targetHost", "MachineName": "$envName", "SSHUser": "", "SSHPort": 0, "SSHKeyPath": "", "SwarmMaster": false, "SwarmHost": "", "SwarmDiscovery": "", "URL": "tcp://${targetAddress}" }, "DriverName": "none", "HostOptions": { "Driver": "", "Memory": 0, "Disk": 0, "EngineOptions": { "ArbitraryFlags": [], "Dns": null, "GraphDir": "", "Env": [], "Ipv6": false, "InsecureRegistry": [], "Labels": [], "LogLevel": "", "StorageDriver": "", "SelinuxEnabled": false, "TlsVerify": true, "RegistryMirror": [], "InstallURL": "https://get.docker.com" }, "SwarmOptions": { "IsSwarm": false, "Address": "", "Discovery": "", "Agent": false, "Master": false, "Host": "tcp://0.0.0.0:3376", "Image": "swarm:latest", "Strategy": "spread", "Heartbeat": 0, "Overcommit": 0, "ArbitraryFlags": [], "ArbitraryJoinFlags": [], "Env": null, "IsExperimental": false }, "AuthOptions": { "CertDir": "$($envDir -replace '\\', '\\')", "CaCertPath": "$($envDir -replace '\\', '\\')\\ca.pem", "CaCertRemotePath": "", "ClientKeyPath": "$($envDir -replace '\\', '\\')\\key.pem", "ServerCertRemotePath": "", "ServerKeyRemotePath": "", "ClientCertPath": "$($envDir -replace '\\', '\\')\\cert.pem", "ServerCertSANs": [], "StorePath": "$($envDir -replace '\\', '\\')" } }, "Name": "$envName" } "@ } #endregion #region Public Functions function New-DockerMachine { <# .Synopsis Create new Docker Machine environment. .Description Creates new Docker Machine environment. .Parameter Name Name of the environment. .Parameter TargetHost Hostname of a Docker host. If no port is specified, default port 443 is used. Specify a custom port like this: "host.example.com:2376" .Parameter ClientBundleFile Client bundle file you downloaded from UCP. .Example # Create new environment 'example'. Commands will be sent to host.example.com:443. Certificates from given client bundle will be used. New-DockerMachine -name example -TargetHost host.example.com -ClientBundleFile .\ucp-bundle-user.zip .Example # Create new environment 'example'. Commands will be sent to host.example.com:2376, not to default port 443. Certificates from given client bundle will be used. New-DockerMachine -name example -TargetHost "host.example.com:2376" -ClientBundleFile .\ucp-bundle-user.zip #> [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")] Param ( [Parameter(Mandatory=$True)][string]$Name, [Parameter(Mandatory=$True)][string]$TargetHost, [ValidateScript({Test-Path $_})][Parameter(Mandatory=$True)][string]$ClientBundleFile ) $dockerMachineDir = Join-Path -Path $env:USERPROFILE -ChildPath ".docker\machine" $dockerMachinesDir = Join-Path -Path $dockerMachineDir -ChildPath "machines" $dockerEnvDir = Join-Path -Path $dockerMachinesDir -ChildPath $Name if (Test-Path -Path $dockerEnvDir -PathType Container) { Write-Warning "The environment `"$Name`" already exists at `"$dockerMachinesDir`". It must be removed first."; Remove-Item -Path $dockerEnvDir -Confirm:$true -Recurse -Force; if (Test-Path -Path $dockerEnvDir -PathType Container) { Write-Warning "Old environment was not removed. Exiting..."; exit 1; } } Write-Output "Creating environment at `"$dockerEnvDir`"" if ($PSCmdlet.ShouldProcess($dockerEnvDir, "Create directory")) { New-Item -ItemType Directory -Path $dockerEnvDir | Out-Null; Push-Location $dockerEnvDir } try { Write-Verbose "Extracting client bundle"; if ($PSCmdlet.ShouldProcess($dockerEnvDir, "Extract files from client bundle")) { Expand-Archive $ClientBundleFile -DestinationPath $dockerEnvDir; if ((Test-Path (Join-Path -Path $dockerEnvDir -ChildPath "ca.pem")) -and (Test-Path (Join-Path -Path $dockerEnvDir -ChildPath "key.pem")) -and (Test-Path (Join-Path -Path $dockerEnvDir -ChildPath "cert.pem"))) { Write-Verbose "Certificates extracted successfully"; } else { throw "Client bundle did not contain the necessary certificates"; } } Write-Verbose "Generating docker config.json" $configTemplate = Get-ConfigTemplate -targetHost $TargetHost -envName $Name -envDir $dockerEnvDir; if ($PSCmdlet.ShouldProcess($dockerEnvDir, "Write config file")) { $configTemplate | Set-Content config.json; } Write-Output "Environment `"$Name`" is now ready." Write-Output "Type `"Use-DockerMachine $Name`" to switch to that environment." Write-Warning "Be careful when interacting with a remote environment." } catch { Pop-Location if ($PSCmdlet.ShouldProcess($dockerEnvDir, "Remove directory")) { Write-Verbose "Cleanup ${$dockerEnvDir}"; Remove-Item -Path $dockerEnvDir -Recurse -Force } throw $_; } finally { Pop-Location } } function Use-DockerMachine { <# .Synopsis Use Docker Machine environment. .Description Use Docker Machine environment. Afterwards you can type Docker commands for this host/swarm. .Parameter Name Name of the environment. .Example # Use environment "test": New-DockerMachine test .Example # Use local Docker host: New-DockerMachine local #> Param( [Parameter(Mandatory=$True)][string]$Name ) if ($Name -eq "local" -or $Name -eq "default") { if (Test-Path Env:\\DOCKER_HOST) { Remove-Item Env:\\DOCKER_TLS_VERIFY; Remove-Item Env:\\DOCKER_HOST; Remove-Item Env:\\DOCKER_CERT_PATH; Remove-Item Env:\\DOCKER_MACHINE_NAME; } } else { [System.Environment]::SetEnvironmentVariable("DOCKER_TLS_VERIFY", "1", "Process"); [System.Environment]::SetEnvironmentVariable("DOCKER_HOST", $(docker-machine url $Name), "Process"); [System.Environment]::SetEnvironmentVariable("DOCKER_CERT_PATH", "$env:userprofile\.docker\machine\machines\$Name", "Process"); [System.Environment]::SetEnvironmentVariable("DOCKER_MACHINE_NAME", $Name, "Process"); [System.Environment]::SetEnvironmentVariable("COMPOSE_CONVERT_WINDOWS_PATHS", "true", "Process"); } } function Get-DockerMachine { <# .Synopsis Get list of Docker Machine environments. .Description Get list of currently configured Docker Machine environments. .Example Get-DockerMachines #> & docker-machine ls -q } function Remove-DockerMachine { <# .Synopsis Remove Docker Machine environment. .Description Remove Docker Machine environment. .Parameter Name Name of the environment. .Example # Remove environment "test": Remove-DockerMachine test #> [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")] Param( [Parameter(Mandatory=$True)][string]$Name ) if ($PSCmdlet.ShouldProcess($Name, "docker-machine rm")) { & docker-machine rm -y $Name; } } #endregion #region Export Module Members Export-ModuleMember -Function ("New-DockerMachine", "Use-DockerMachine", "Get-DockerMachine", "Remove-DockerMachine"); #endregion |