Skip to content

Instantly share code, notes, and snippets.

@stefanschneider
Created September 13, 2016 10:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stefanschneider/2221deecbc03521f97e63547cf157188 to your computer and use it in GitHub Desktop.
Save stefanschneider/2221deecbc03521f97e63547cf157188 to your computer and use it in GitHub Desktop.
// hcs-toy1 project main.go
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"github.com/Microsoft/hcsshim"
"github.com/docker/docker/pkg/stringid"
)
// filterDriver is an HCSShim driver type for the Windows Filter driver.
const filterDriver = 1
var homeDir = "C:\\ProgramData\\docker\\windowsfilter"
// Returns: LayerFolderPaht, VolumePath
func CreateAndActivateContainerLayer(di hcsshim.DriverInfo, containerLayerId, parentLayerPath string) (string, string, error) {
var err error
parentLayerId := GetLayerId(parentLayerPath)
log.Printf("Parent layer %v path has Id %v", parentLayerPath, parentLayerId)
err = hcsshim.CreateSandboxLayer(di, containerLayerId, parentLayerPath, []string{parentLayerPath})
if err != nil {
return "", "", err
}
err = hcsshim.ActivateLayer(di, containerLayerId)
if err != nil {
return "", "", err
}
err = hcsshim.PrepareLayer(di, containerLayerId, []string{parentLayerPath})
if err != nil {
return "", "", err
}
volumeMountPath, err := hcsshim.GetLayerMountPath(di, containerLayerId)
if err != nil {
return "", "", err
}
log.Printf("Container layer volume path %v", volumeMountPath)
return GetLayerPath(di, containerLayerId), volumeMountPath, nil
}
func GetLayerId(layerPath string) string {
return filepath.Base(layerPath)
}
func GetLayerPath(di hcsshim.DriverInfo, layerId string) string {
return filepath.Join(di.HomeDir, layerId)
}
func GetLayerPath2(di hcsshim.DriverInfo, layerId, parentLayerPath string) (string, error) {
parentLayerId := GetLayerId(parentLayerPath)
err := hcsshim.CreateLayer(di, layerId, parentLayerId)
if err != nil {
return "", err
}
err = hcsshim.ActivateLayer(di, layerId)
if err != nil {
return "", err
}
err = hcsshim.PrepareLayer(di, layerId, []string{parentLayerPath})
if err != nil {
return "", err
}
layerFolderPath, err := hcsshim.GetLayerMountPath(di, layerId)
if err != nil {
return "", err
}
log.Printf("Container layer folder path %v", layerFolderPath)
err = hcsshim.UnprepareLayer(di, layerId)
if err != nil {
return "", err
}
err = hcsshim.DeactivateLayer(di, layerId)
if err != nil {
return "", err
}
err = hcsshim.DestroyLayer(di, layerId)
if err != nil {
return "", err
}
return layerFolderPath, nil
}
func main() {
if len(os.Args) != 2 {
fmt.Print(`
This sample create a new container runs ping and then destroys the container.
Usage:
sample.exe <base container Id>
To get the base container id for "microsoft/windowsservercore" use the following PS snippet:
Split-Path -Leaf (docker inspect microsoft/windowsservercore | ConvertFrom-Json).GraphDriver.Data.Dir
`)
os.Exit(1)
}
windowsbaseId := os.Args[1]
guid, err := hcsshim.NameToGuid(windowsbaseId)
panicIf(err)
windowsbaseGuid := guid.ToString()
di := hcsshim.DriverInfo{
HomeDir: homeDir,
Flavour: filterDriver,
}
imgData, err := hcsshim.GetSharedBaseImages()
panicIf(err)
fmt.Println(imgData)
hcsNets, err := hcsshim.HNSListNetworkRequest("GET", "", "")
panicIf(err)
fmt.Println(hcsNets)
virtualNetworkId := ""
for _, n := range hcsNets {
if n.Name == "nat" {
virtualNetworkId = n.Id
}
}
// https://github.com/docker/libnetwork/blob/f9a1590164b878e668eabf889dd79fb6af8eaced/drivers/windows/windows.go#L284
endpointRequest := hcsshim.HNSEndpoint{
VirtualNetwork: virtualNetworkId,
}
// natPolicy1, err := json.Marshal(hcsshim.NatPolicy{
// Type: "NAT",
// ExternalPort: 9187,
// InternalPort: 80,
// Protocol: "TCP",
// })
// panicIf(err)
// endpointRequest.Policies = []json.RawMessage{natPolicy1}
endpointRequestJson, err := json.Marshal(endpointRequest)
panicIf(err)
endpoint, err := hcsshim.HNSEndpointRequest("POST", "", string(endpointRequestJson))
panicIf(err)
fmt.Println(*endpoint)
windowsservercorePath, err := hcsshim.GetLayerMountPath(di, windowsbaseId)
panicIf(err)
fmt.Println(windowsservercorePath)
newContainerId := stringid.GenerateNonCryptoID()
layerFolderPath, volumeMountPath, err := CreateAndActivateContainerLayer(di, newContainerId, windowsservercorePath)
panicIf(err)
containerConfig := hcsshim.ContainerConfig{
SystemType: "Container",
Name: newContainerId,
Owner: "Garden",
LayerFolderPath: layerFolderPath,
VolumePath: volumeMountPath,
Layers: []hcsshim.Layer{
hcsshim.Layer{Path: windowsservercorePath, ID: windowsbaseGuid},
},
IgnoreFlushesDuringBoot: true,
EndpointList: []string{endpoint.Id},
MappedDirectories: []hcsshim.MappedDir{
hcsshim.MappedDir{
HostPath: "C:\\testhcs\\test",
ContainerPath: "C:" + filepath.FromSlash("/tmp/test/f1"),
ReadOnly: true,
},
},
}
c, err := hcsshim.CreateContainer(newContainerId, &containerConfig)
panicIf(err)
fmt.Println(c)
err = c.Start()
panicIf(err)
stats, err := c.Statistics()
panicIf(err)
fmt.Println(stats)
processConfig := hcsshim.ProcessConfig{
CommandLine: "ping 127.0.0.1",
WorkingDirectory: "C:\\",
//CreateStdErrPipe: true,
//CreateStdInPipe: true,
//CreateStdOutPipe: true,
}
p, err := c.CreateProcess(&processConfig)
panicIf(err)
fmt.Println(p)
err = p.Wait()
panicIf(err)
err = c.Shutdown()
warnIf(err)
err = c.Terminate()
warnIf(err)
endpoint, err = hcsshim.HNSEndpointRequest("DELETE", endpoint.Id, "")
warnIf(err)
err = hcsshim.UnprepareLayer(di, newContainerId)
warnIf(err)
err = hcsshim.DeactivateLayer(di, newContainerId)
warnIf(err)
err = hcsshim.DestroyLayer(di, newContainerId)
warnIf(err)
}
func panicIf(err error) {
if err != nil {
panic(err)
}
}
func warnIf(err error) {
if err != nil {
fmt.Errorf("%v", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment