mirror of
https://github.com/containers/podman.git
synced 2025-10-17 03:04:21 +08:00

Pull in updates made to the filters code for images. Filters now perform an AND operation except for th reference filter which does an OR operation for positive case but an AND operation for negative cases. Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>
226 lines
7.6 KiB
Go
226 lines
7.6 KiB
Go
//go:build windows
|
|
|
|
package hcsshim
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/Microsoft/hcsshim/internal/hcs"
|
|
"github.com/Microsoft/hcsshim/internal/hcs/schema1"
|
|
"github.com/Microsoft/hcsshim/internal/mergemaps"
|
|
)
|
|
|
|
// ContainerProperties holds the properties for a container and the processes running in that container
|
|
type ContainerProperties = schema1.ContainerProperties
|
|
|
|
// MemoryStats holds the memory statistics for a container
|
|
type MemoryStats = schema1.MemoryStats
|
|
|
|
// ProcessorStats holds the processor statistics for a container
|
|
type ProcessorStats = schema1.ProcessorStats
|
|
|
|
// StorageStats holds the storage statistics for a container
|
|
type StorageStats = schema1.StorageStats
|
|
|
|
// NetworkStats holds the network statistics for a container
|
|
type NetworkStats = schema1.NetworkStats
|
|
|
|
// Statistics is the structure returned by a statistics call on a container
|
|
type Statistics = schema1.Statistics
|
|
|
|
// ProcessList is the structure of an item returned by a ProcessList call on a container
|
|
type ProcessListItem = schema1.ProcessListItem
|
|
|
|
// MappedVirtualDiskController is the structure of an item returned by a MappedVirtualDiskList call on a container
|
|
type MappedVirtualDiskController = schema1.MappedVirtualDiskController
|
|
|
|
// Type of Request Support in ModifySystem
|
|
type RequestType = schema1.RequestType
|
|
|
|
// Type of Resource Support in ModifySystem
|
|
type ResourceType = schema1.ResourceType
|
|
|
|
// RequestType const
|
|
const (
|
|
Add = schema1.Add
|
|
Remove = schema1.Remove
|
|
Network = schema1.Network
|
|
)
|
|
|
|
// ResourceModificationRequestResponse is the structure used to send request to the container to modify the system
|
|
// Supported resource types are Network and Request Types are Add/Remove
|
|
type ResourceModificationRequestResponse = schema1.ResourceModificationRequestResponse
|
|
|
|
type container struct {
|
|
system *hcs.System
|
|
waitOnce sync.Once
|
|
waitErr error
|
|
waitCh chan struct{}
|
|
}
|
|
|
|
// createContainerAdditionalJSON is read from the environment at initialization
|
|
// time. It allows an environment variable to define additional JSON which
|
|
// is merged in the CreateComputeSystem call to HCS.
|
|
var createContainerAdditionalJSON []byte
|
|
|
|
func init() {
|
|
createContainerAdditionalJSON = ([]byte)(os.Getenv("HCSSHIM_CREATECONTAINER_ADDITIONALJSON"))
|
|
}
|
|
|
|
// CreateContainer creates a new container with the given configuration but does not start it.
|
|
func CreateContainer(id string, c *ContainerConfig) (Container, error) {
|
|
fullConfig, err := mergemaps.MergeJSON(c, createContainerAdditionalJSON)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to merge additional JSON '%s': %w", createContainerAdditionalJSON, err)
|
|
}
|
|
|
|
system, err := hcs.CreateComputeSystem(context.Background(), id, fullConfig)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &container{system: system}, err
|
|
}
|
|
|
|
// OpenContainer opens an existing container by ID.
|
|
func OpenContainer(id string) (Container, error) {
|
|
system, err := hcs.OpenComputeSystem(context.Background(), id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &container{system: system}, err
|
|
}
|
|
|
|
// GetContainers gets a list of the containers on the system that match the query
|
|
func GetContainers(q ComputeSystemQuery) ([]ContainerProperties, error) {
|
|
return hcs.GetComputeSystems(context.Background(), q)
|
|
}
|
|
|
|
// Start synchronously starts the container.
|
|
func (container *container) Start() error {
|
|
return convertSystemError(container.system.Start(context.Background()), container)
|
|
}
|
|
|
|
// Shutdown requests a container shutdown, but it may not actually be shutdown until Wait() succeeds.
|
|
func (container *container) Shutdown() error {
|
|
err := container.system.Shutdown(context.Background())
|
|
if err != nil {
|
|
return convertSystemError(err, container)
|
|
}
|
|
return &ContainerError{Container: container, Err: ErrVmcomputeOperationPending, Operation: "hcsshim::ComputeSystem::Shutdown"}
|
|
}
|
|
|
|
// Terminate requests a container terminate, but it may not actually be terminated until Wait() succeeds.
|
|
func (container *container) Terminate() error {
|
|
err := container.system.Terminate(context.Background())
|
|
if err != nil {
|
|
return convertSystemError(err, container)
|
|
}
|
|
return &ContainerError{Container: container, Err: ErrVmcomputeOperationPending, Operation: "hcsshim::ComputeSystem::Terminate"}
|
|
}
|
|
|
|
// Waits synchronously waits for the container to shutdown or terminate.
|
|
func (container *container) Wait() error {
|
|
err := container.system.Wait()
|
|
if err == nil {
|
|
err = container.system.ExitError()
|
|
}
|
|
return convertSystemError(err, container)
|
|
}
|
|
|
|
// WaitTimeout synchronously waits for the container to terminate or the duration to elapse. It
|
|
// returns false if timeout occurs.
|
|
func (container *container) WaitTimeout(timeout time.Duration) error {
|
|
container.waitOnce.Do(func() {
|
|
container.waitCh = make(chan struct{})
|
|
go func() {
|
|
container.waitErr = container.Wait()
|
|
close(container.waitCh)
|
|
}()
|
|
})
|
|
t := time.NewTimer(timeout)
|
|
defer t.Stop()
|
|
select {
|
|
case <-t.C:
|
|
return &ContainerError{Container: container, Err: ErrTimeout, Operation: "hcsshim::ComputeSystem::Wait"}
|
|
case <-container.waitCh:
|
|
return container.waitErr
|
|
}
|
|
}
|
|
|
|
// Pause pauses the execution of a container.
|
|
func (container *container) Pause() error {
|
|
return convertSystemError(container.system.Pause(context.Background()), container)
|
|
}
|
|
|
|
// Resume resumes the execution of a container.
|
|
func (container *container) Resume() error {
|
|
return convertSystemError(container.system.Resume(context.Background()), container)
|
|
}
|
|
|
|
// HasPendingUpdates returns true if the container has updates pending to install
|
|
func (container *container) HasPendingUpdates() (bool, error) {
|
|
return false, nil
|
|
}
|
|
|
|
// Statistics returns statistics for the container. This is a legacy v1 call
|
|
func (container *container) Statistics() (Statistics, error) {
|
|
properties, err := container.system.Properties(context.Background(), schema1.PropertyTypeStatistics)
|
|
if err != nil {
|
|
return Statistics{}, convertSystemError(err, container)
|
|
}
|
|
|
|
return properties.Statistics, nil
|
|
}
|
|
|
|
// ProcessList returns an array of ProcessListItems for the container. This is a legacy v1 call
|
|
func (container *container) ProcessList() ([]ProcessListItem, error) {
|
|
properties, err := container.system.Properties(context.Background(), schema1.PropertyTypeProcessList)
|
|
if err != nil {
|
|
return nil, convertSystemError(err, container)
|
|
}
|
|
|
|
return properties.ProcessList, nil
|
|
}
|
|
|
|
// This is a legacy v1 call
|
|
func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskController, error) {
|
|
properties, err := container.system.Properties(context.Background(), schema1.PropertyTypeMappedVirtualDisk)
|
|
if err != nil {
|
|
return nil, convertSystemError(err, container)
|
|
}
|
|
|
|
return properties.MappedVirtualDiskControllers, nil
|
|
}
|
|
|
|
// CreateProcess launches a new process within the container.
|
|
func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
|
|
p, err := container.system.CreateProcess(context.Background(), c)
|
|
if err != nil {
|
|
return nil, convertSystemError(err, container)
|
|
}
|
|
return &process{p: p.(*hcs.Process)}, nil
|
|
}
|
|
|
|
// OpenProcess gets an interface to an existing process within the container.
|
|
func (container *container) OpenProcess(pid int) (Process, error) {
|
|
p, err := container.system.OpenProcess(context.Background(), pid)
|
|
if err != nil {
|
|
return nil, convertSystemError(err, container)
|
|
}
|
|
return &process{p: p}, nil
|
|
}
|
|
|
|
// Close cleans up any state associated with the container but does not terminate or wait for it.
|
|
func (container *container) Close() error {
|
|
return convertSystemError(container.system.Close(), container)
|
|
}
|
|
|
|
// Modify the System
|
|
func (container *container) Modify(config *ResourceModificationRequestResponse) error {
|
|
return convertSystemError(container.system.Modify(context.Background(), config), container)
|
|
}
|