-
Notifications
You must be signed in to change notification settings - Fork 301
Expand file tree
/
Copy pathpod_lcow.go
More file actions
135 lines (110 loc) · 3.67 KB
/
Copy pathpod_lcow.go
File metadata and controls
135 lines (110 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//go:build windows && lcow
package pod
import (
"context"
"fmt"
"sync"
"github.com/Microsoft/hcsshim/internal/controller/linuxcontainer"
)
// Controller manages the lifecycle of a single pod inside a Utility VM.
type Controller struct {
mu sync.RWMutex
// podID is the containerd facing pod identifier.
podID string
// gcsPodID is the identifier used when communicating with the GCS.
gcsPodID string
// vm is the parent Utility VM that hosts this pod.
vm vmController
// network manages the network namespace and endpoint lifecycle
// for this pod.
network networkController
// containers maps containerID → [linuxcontainer.Controller] for every
// live container in this pod. Access must be guarded by mu.
containers map[string]*linuxcontainer.Controller
}
// New creates a ready-to-use [Controller] for the given pod.
func New(
podID string,
networkNamespaceID string,
vm vmController,
) *Controller {
return &Controller{
podID: podID,
// Same ID is used as the pod. Post migration, we can always change
// the primary ID while GCS continues to use the original one.
gcsPodID: podID,
vm: vm,
network: vm.NetworkController(networkNamespaceID),
containers: make(map[string]*linuxcontainer.Controller),
}
}
// SetupNetwork performs network setup for the pod.
func (c *Controller) SetupNetwork(ctx context.Context) error {
if err := c.network.Setup(ctx); err != nil {
return fmt.Errorf("setup network for pod %s: %w", c.podID, err)
}
return nil
}
// TeardownNetwork performs network teardown for the pod.
func (c *Controller) TeardownNetwork(ctx context.Context) error {
if err := c.network.Teardown(ctx); err != nil {
return fmt.Errorf("teardown network for pod %s: %w", c.podID, err)
}
return nil
}
// GetContainer returns the container controller for the given containerID.
func (c *Controller) GetContainer(containerID string) (*linuxcontainer.Controller, error) {
c.mu.RLock()
defer c.mu.RUnlock()
containerCtrl, ok := c.containers[containerID]
if !ok {
return nil, fmt.Errorf("container %q not found in pod %q", containerID, c.podID)
}
return containerCtrl, nil
}
// NewContainer creates a new [linuxcontainer.Controller] and registers it
// in this pod.
func (c *Controller) NewContainer(ctx context.Context, containerID string) (*linuxcontainer.Controller, error) {
c.mu.Lock()
defer c.mu.Unlock()
// Ensure we don't create a duplicate container controller.
if _, ok := c.containers[containerID]; ok {
return nil, fmt.Errorf("container %q already exists in pod %q", containerID, c.podID)
}
scsiCtrl, err := c.vm.SCSIController(ctx)
if err != nil {
return nil, fmt.Errorf("get SCSI controller for pod %s: %w", c.podID, err)
}
containerCtrl := linuxcontainer.New(
c.vm.RuntimeID(),
c.gcsPodID,
containerID,
c.vm.Guest(),
scsiCtrl,
c.vm.Plan9Controller(),
c.vm.VPCIController(),
)
c.containers[containerID] = containerCtrl
return containerCtrl, nil
}
// ListContainers returns a snapshot of all live container controllers in
// this pod, keyed by container ID.
func (c *Controller) ListContainers() map[string]*linuxcontainer.Controller {
c.mu.RLock()
defer c.mu.RUnlock()
result := make(map[string]*linuxcontainer.Controller, len(c.containers))
for containerID, containerCtrl := range c.containers {
result[containerID] = containerCtrl
}
return result
}
// DeleteContainer removes a container from the pod's container map.
func (c *Controller) DeleteContainer(ctx context.Context, containerID string) error {
c.mu.Lock()
defer c.mu.Unlock()
if _, ok := c.containers[containerID]; !ok {
return fmt.Errorf("container %q not found in pod %q", containerID, c.podID)
}
delete(c.containers, containerID)
return nil
}