// Create creates a new layer with the given id.
func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
	if len(storageOpt) != 0 {
		return fmt.Errorf("--storage-opt is not supported for windows")
	}

	rPId, err := d.resolveID(parent)
	if err != nil {
		return err
	}

	parentChain, err := d.getLayerChain(rPId)
	if err != nil {
		return err
	}

	var layerChain []string

	parentIsInit := strings.HasSuffix(rPId, "-init")

	if !parentIsInit && rPId != "" {
		parentPath, err := hcsshim.GetLayerMountPath(d.info, rPId)
		if err != nil {
			return err
		}
		layerChain = []string{parentPath}
	}

	layerChain = append(layerChain, parentChain...)

	if parentIsInit {
		if len(layerChain) == 0 {
			return fmt.Errorf("Cannot create a read/write layer without a parent layer.")
		}
		if err := hcsshim.CreateSandboxLayer(d.info, id, layerChain[0], layerChain); err != nil {
			return err
		}
	} else {
		if err := hcsshim.CreateLayer(d.info, id, rPId); err != nil {
			return err
		}
	}

	if _, err := os.Lstat(d.dir(parent)); err != nil {
		if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil {
			logrus.Warnf("Failed to DestroyLayer %s: %s", id, err2)
		}
		return fmt.Errorf("Cannot create layer with missing parent %s: %s", parent, err)
	}

	if err := d.setLayerChain(id, layerChain); err != nil {
		if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil {
			logrus.Warnf("Failed to DestroyLayer %s: %s", id, err2)
		}
		return err
	}

	return nil
}
Exemple #2
0
// importLayer adds a new layer to the tag and graph store based on the given data.
func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPaths []string) (size int64, err error) {
	layerFolder := d.dir(id)

	tempFolder := layerFolder + "-" + strconv.FormatUint(uint64(random.Rand.Uint32()), 10)
	if err = os.MkdirAll(tempFolder, 0755); err != nil {
		logrus.Errorf("Could not create %s %s", tempFolder, err)
		return
	}
	defer func() {
		_, folderName := filepath.Split(tempFolder)
		if err2 := hcsshim.DestroyLayer(d.info, folderName); err2 != nil {
			logrus.Warnf("Couldn't clean-up tempFolder: %s %s", tempFolder, err2)
		}
	}()

	start := time.Now().UTC()
	logrus.Debugf("Start untar layer")
	if size, err = chrootarchive.ApplyLayer(tempFolder, layerData); err != nil {
		return
	}
	logrus.Debugf("Untar time: %vs", time.Now().UTC().Sub(start).Seconds())

	if err = hcsshim.ImportLayer(d.info, id, tempFolder, parentLayerPaths); err != nil {
		return
	}

	return
}
Exemple #3
0
// Remove unmounts and removes the dir information.
func (d *Driver) Remove(id string) error {
	rID, err := d.resolveID(id)
	if err != nil {
		return err
	}
	os.RemoveAll(filepath.Join(d.info.HomeDir, "sysfile-backups", rID)) // ok to fail
	return hcsshim.DestroyLayer(d.info, rID)
}
Exemple #4
0
// Remove unmounts and removes the dir information.
func (d *Driver) Remove(id string) error {
	rID, err := d.resolveID(id)
	if err != nil {
		return err
	}

	return hcsshim.DestroyLayer(d.info, rID)
}
Exemple #5
0
// DiffPath returns a directory that contains files needed to construct layer diff.
func (d *Driver) DiffPath(id string) (path string, release func() error, err error) {
	id, err = d.resolveID(id)
	if err != nil {
		return
	}

	// Getting the layer paths must be done outside of the lock.
	layerChain, err := d.getLayerChain(id)
	if err != nil {
		return
	}

	layerFolder := d.dir(id)
	tempFolder := layerFolder + "-" + strconv.FormatUint(uint64(random.Rand.Uint32()), 10)
	if err = os.MkdirAll(tempFolder, 0755); err != nil {
		logrus.Errorf("Could not create %s %s", tempFolder, err)
		return
	}

	defer func() {
		if err != nil {
			_, folderName := filepath.Split(tempFolder)
			if err2 := hcsshim.DestroyLayer(d.info, folderName); err2 != nil {
				logrus.Warnf("Couldn't clean-up tempFolder: %s %s", tempFolder, err2)
			}
		}
	}()

	if err = hcsshim.ExportLayer(d.info, id, tempFolder, layerChain); err != nil {
		return
	}

	err = copySysFiles(filepath.Join(d.info.HomeDir, "sysfile-backups", id), tempFolder)
	if err != nil {
		return
	}

	return tempFolder, func() error {
		// TODO: activate layers and release here?
		_, folderName := filepath.Split(tempFolder)
		return hcsshim.DestroyLayer(d.info, folderName)
	}, nil
}
Exemple #6
0
// exportLayer generates an archive from a layer based on the given ID.
func (d *Driver) exportLayer(id string, parentLayerPaths []string) (arch archive.Archive, err error) {
	layerFolder := d.dir(id)

	tempFolder := layerFolder + "-" + strconv.FormatUint(uint64(random.Rand.Uint32()), 10)
	if err = os.MkdirAll(tempFolder, 0755); err != nil {
		logrus.Errorf("Could not create %s %s", tempFolder, err)
		return
	}
	defer func() {
		if err != nil {
			_, folderName := filepath.Split(tempFolder)
			if err2 := hcsshim.DestroyLayer(d.info, folderName); err2 != nil {
				logrus.Warnf("Couldn't clean-up tempFolder: %s %s", tempFolder, err2)
			}
		}
	}()

	if err = hcsshim.ExportLayer(d.info, id, tempFolder, parentLayerPaths); err != nil {
		return
	}

	archive, err := archive.Tar(tempFolder, archive.Uncompressed)
	if err != nil {
		return
	}
	return ioutils.NewReadCloserWrapper(archive, func() error {
		err := archive.Close()
		d.Put(id)
		_, folderName := filepath.Split(tempFolder)
		if err2 := hcsshim.DestroyLayer(d.info, folderName); err2 != nil {
			logrus.Warnf("Couldn't clean-up tempFolder: %s %s", tempFolder, err2)
		}
		return err
	}), nil

}
Exemple #7
0
// Remove unmounts and removes the dir information.
func (d *Driver) Remove(id string) error {
	rID, err := d.resolveID(id)
	if err != nil {
		return err
	}

	layerPath := filepath.Join(d.info.HomeDir, rID)
	tmpID := fmt.Sprintf("%s-removing", rID)
	tmpLayerPath := filepath.Join(d.info.HomeDir, tmpID)
	if err := os.Rename(layerPath, tmpLayerPath); err != nil && !os.IsNotExist(err) {
		return err
	}
	if err := hcsshim.DestroyLayer(d.info, tmpID); err != nil {
		logrus.Errorf("Failed to DestroyLayer %s: %s", id, err)
	}

	return nil
}
Exemple #8
0
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
}
Exemple #9
0
func main() {
	var folder string
	flag.StringVar(&folder, "folder", "", "Folder to zap.")
	flag.Parse()
	if folder == "" {
		fmt.Println("Error: folder must be supplied")
		return
	}
	if folderexists(folder) {
		location, foldername := filepath.Split(folder)
		info := hcsshim.DriverInfo{
			HomeDir: location,
			Flavour: 0,
		}
		if err := hcsshim.DestroyLayer(info, foldername); err != nil {
			fmt.Println("ERROR: ", err)
		} else {
			fmt.Println("INFO: Zapped successfully")
		}
	} else {
		fmt.Println("ERROR: Folder does not exist")
	}
}
Exemple #10
0
func (d *Driver) create(id, parent, mountLabel string, readOnly bool, storageOpt map[string]string) error {
	if len(storageOpt) != 0 {
		return fmt.Errorf("--storage-opt is not supported for windows")
	}

	rPId, err := d.resolveID(parent)
	if err != nil {
		return err
	}

	parentChain, err := d.getLayerChain(rPId)
	if err != nil {
		return err
	}

	var layerChain []string

	if rPId != "" {
		parentPath, err := hcsshim.GetLayerMountPath(d.info, rPId)
		if err != nil {
			return err
		}
		if _, err := os.Stat(filepath.Join(parentPath, "Files")); err == nil {
			// This is a legitimate parent layer (not the empty "-init" layer),
			// so include it in the layer chain.
			layerChain = []string{parentPath}
		}
	}

	layerChain = append(layerChain, parentChain...)

	if readOnly {
		if err := hcsshim.CreateLayer(d.info, id, rPId); err != nil {
			return err
		}
	} else {
		var parentPath string
		if len(layerChain) != 0 {
			parentPath = layerChain[0]
		}

		if isTP5OrOlder() {
			// Pre-create the layer directory, providing an ACL to give the Hyper-V Virtual Machines
			// group access. This is necessary to ensure that Hyper-V containers can access the
			// virtual machine data. This is not necessary post-TP5.
			path, err := syscall.UTF16FromString(filepath.Join(d.info.HomeDir, id))
			if err != nil {
				return err
			}
			// Give system and administrators full control, and VMs read, write, and execute.
			// Mark these ACEs as inherited.
			sd, err := winio.SddlToSecurityDescriptor("D:(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FRFWFX;;;S-1-5-83-0)")
			if err != nil {
				return err
			}
			err = syscall.CreateDirectory(&path[0], &syscall.SecurityAttributes{
				Length:             uint32(unsafe.Sizeof(syscall.SecurityAttributes{})),
				SecurityDescriptor: uintptr(unsafe.Pointer(&sd[0])),
			})
			if err != nil {
				return err
			}
		}

		if err := hcsshim.CreateSandboxLayer(d.info, id, parentPath, layerChain); err != nil {
			return err
		}
	}

	if _, err := os.Lstat(d.dir(parent)); err != nil {
		if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil {
			logrus.Warnf("Failed to DestroyLayer %s: %s", id, err2)
		}
		return fmt.Errorf("Cannot create layer with missing parent %s: %s", parent, err)
	}

	if err := d.setLayerChain(id, layerChain); err != nil {
		if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil {
			logrus.Warnf("Failed to DestroyLayer %s: %s", id, err2)
		}
		return err
	}

	return nil
}
Exemple #11
0
func (d *Driver) create(id, parent, mountLabel string, readOnly bool, storageOpt map[string]string) error {
	rPId, err := d.resolveID(parent)
	if err != nil {
		return err
	}

	parentChain, err := d.getLayerChain(rPId)
	if err != nil {
		return err
	}

	var layerChain []string

	if rPId != "" {
		parentPath, err := hcsshim.GetLayerMountPath(d.info, rPId)
		if err != nil {
			return err
		}
		if _, err := os.Stat(filepath.Join(parentPath, "Files")); err == nil {
			// This is a legitimate parent layer (not the empty "-init" layer),
			// so include it in the layer chain.
			layerChain = []string{parentPath}
		}
	}

	layerChain = append(layerChain, parentChain...)

	if readOnly {
		if err := hcsshim.CreateLayer(d.info, id, rPId); err != nil {
			return err
		}
	} else {
		var parentPath string
		if len(layerChain) != 0 {
			parentPath = layerChain[0]
		}

		if err := hcsshim.CreateSandboxLayer(d.info, id, parentPath, layerChain); err != nil {
			return err
		}

		storageOptions, err := parseStorageOpt(storageOpt)
		if err != nil {
			return fmt.Errorf("Failed to parse storage options - %s", err)
		}

		if storageOptions.size != 0 {
			if err := hcsshim.ExpandSandboxSize(d.info, id, storageOptions.size); err != nil {
				return err
			}
		}
	}

	if _, err := os.Lstat(d.dir(parent)); err != nil {
		if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil {
			logrus.Warnf("Failed to DestroyLayer %s: %s", id, err2)
		}
		return fmt.Errorf("Cannot create layer with missing parent %s: %s", parent, err)
	}

	if err := d.setLayerChain(id, layerChain); err != nil {
		if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil {
			logrus.Warnf("Failed to DestroyLayer %s: %s", id, err2)
		}
		return err
	}

	return nil
}
Exemple #12
0
// Remove unmounts and removes the dir information.
func (d *Driver) Remove(id string) error {
	rID, err := d.resolveID(id)
	if err != nil {
		return err
	}

	// This retry loop is due to a bug in Windows (Internal bug #9432268)
	// if GetContainers fails with ErrVmcomputeOperationInvalidState
	// it is a transient error. Retry until it succeeds.
	var computeSystems []hcsshim.ContainerProperties
	retryCount := 0
	for {
		// Get and terminate any template VMs that are currently using the layer
		computeSystems, err = hcsshim.GetContainers(hcsshim.ComputeSystemQuery{})
		if err != nil {
			if err == hcsshim.ErrVmcomputeOperationInvalidState {
				if retryCount >= 5 {
					// If we are unable to get the list of containers
					// go ahead and attempt to delete the layer anyway
					// as it will most likely work.
					break
				}
				retryCount++
				time.Sleep(2 * time.Second)
				continue
			}
			return err
		}
		break
	}

	for _, computeSystem := range computeSystems {
		if strings.Contains(computeSystem.RuntimeImagePath, id) && computeSystem.IsRuntimeTemplate {
			container, err := hcsshim.OpenContainer(computeSystem.ID)
			if err != nil {
				return err
			}
			defer container.Close()
			err = container.Terminate()
			if hcsshim.IsPending(err) {
				err = container.Wait()
			} else if hcsshim.IsAlreadyStopped(err) {
				err = nil
			}

			if err != nil {
				return err
			}
		}
	}

	layerPath := filepath.Join(d.info.HomeDir, rID)
	tmpID := fmt.Sprintf("%s-removing", rID)
	tmpLayerPath := filepath.Join(d.info.HomeDir, tmpID)
	if err := os.Rename(layerPath, tmpLayerPath); err != nil && !os.IsNotExist(err) {
		return err
	}
	if err := hcsshim.DestroyLayer(d.info, tmpID); err != nil {
		logrus.Errorf("Failed to DestroyLayer %s: %s", id, err)
	}

	return nil
}
Exemple #13
0
func (d *Driver) Create(id, parent string) error {
	rPId, err := d.resolveId(parent)
	if err != nil {
		return err
	}

	parentChain, err := d.getLayerChain(rPId)
	if err != nil {
		return err
	}

	var layerChain []string

	parentIsInit := strings.HasSuffix(rPId, "-init")

	if !parentIsInit && rPId != "" {
		parentPath, err := hcsshim.GetLayerMountPath(d.info, rPId)
		if err != nil {
			return err
		}
		layerChain = []string{parentPath}
	}

	layerChain = append(layerChain, parentChain...)

	if parentIsInit {
		if len(layerChain) == 0 {
			return fmt.Errorf("Cannot create a read/write layer without a parent layer.")
		}
		if err := hcsshim.CreateSandboxLayer(d.info, id, layerChain[0], layerChain); err != nil {
			return err
		}
	} else {
		if err := hcsshim.CreateLayer(d.info, id, rPId); err != nil {
			return err
		}
	}

	if _, err := os.Lstat(d.dir(parent)); err == nil {
		if err := d.setLayerChain(id, layerChain); err != nil {
			if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil {
				logrus.Warnf("Failed to DestroyLayer %s: %s", id, err)
			}
			return err
		}
	} else if os.IsNotExist(err) {
		// If the parent doesn't exist, this must be a special creation for an image
		// registered at an alternate location. Use the parent id as the alternate ID.
		if err := d.setId(id, parent); err != nil {
			if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil {
				logrus.Warnf("Failed to DestroyLayer %s: %s", id, err)
			}
			return err
		}
	} else {
		if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil {
			logrus.Warnf("Failed to DestroyLayer %s: %s", id, err)
		}
		return err
	}

	return nil
}
Exemple #14
0
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]

	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,
	}
	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)

	layerChain, err := GetLayerChain(windowsservercorePath)
	panicIf(err)
	fmt.Println(layerChain)

	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,
		IgnoreFlushesDuringBoot: true,
		EndpointList:            []string{endpoint.Id},
	}

	// https://github.com/docker/docker/blob/cf58eb437c4229e876f2d952a228b603a074e584/libcontainerd/client_windows.go#L111-L121
	for _, layerPath := range layerChain {
		id, err := hcsshim.NameToGuid(GetLayerId(layerPath))
		panicIf(err)

		containerConfig.Layers = append(containerConfig.Layers, hcsshim.Layer{
			Path: layerPath,
			ID:   id.ToString(),
		})
	}

	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)
}
Exemple #15
0
// Remove unmounts and removes the dir information
func (d *WindowsGraphDriver) Remove(id string) error {
	return hcsshim.DestroyLayer(d.info, id)
}
Exemple #16
0
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)

	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,
	}

	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)

	err = hcsshim.UnprepareLayer(di, newContainerId)
	warnIf(err)

	err = hcsshim.DeactivateLayer(di, newContainerId)
	warnIf(err)

	err = hcsshim.DestroyLayer(di, newContainerId)
	warnIf(err)
}