@@ -33,26 +33,41 @@ import (
33
33
)
34
34
35
35
const (
36
- kernelArgsFormat = "console=ttyS0 noapic reboot=k panic=1 pci=off nomodules rw ip=%s::%s:%s:::off::::"
37
- macAddress = "AA:FC:00:00:00:01"
38
- hostDevName = "tap0"
36
+ kernelArgsFormat = "console=ttyS0 noapic reboot=k panic=1 pci=off nomodules rw ip=%s::%s:%s:::off::::"
37
+ defaultMacAddress = "AA:FC:00:00:00:01"
38
+ defaultHostDevName = "tap0"
39
39
)
40
40
41
41
func main () {
42
42
var ip = flag .String ("ip" , "" , "ip address assigned to the container. Example: -ip 172.16.0.1" )
43
43
var gateway = flag .String ("gw" , "" , "gateway ip address. Example: -gw 172.16.0.1" )
44
44
var netMask = flag .String ("mask" , "" , "subnet gatway mask. Example: -mask 255.255.255.0" )
45
+ var netNS = flag .String ("netns" , "" , "firecracker VM network namespace. Example: -netNS testing" )
46
+ var hostDevName = flag .String ("host_device" , defaultHostDevName ,
47
+ "the host device name for the network interface, required when specifying 'netns'. Example: -host_device tap0" )
48
+ var macAddress = flag .String ("mac" , defaultMacAddress ,
49
+ "the mac address for the network interface, required when specifying 'netns'. Example: -mac AA:FC:00:00:00:01" )
50
+ var kernelNetworkArgs = flag .Bool ("kernel_nw_args" , false ,
51
+ "specifies if network params for the VMs should be included with kernel args. Example: -kernel_nw_args true" )
45
52
log .SetFlags (log .Ldate | log .Ltime | log .Lmicroseconds )
46
53
flag .Parse ()
47
- if * ip != "" && (* gateway == "" || * netMask == "" ) {
48
- log .Fatal ("Incorrect usage. 'gw' and 'mask' need to be specified when 'ip ' is specified " )
54
+ if * kernelNetworkArgs && (* gateway == "" || * netMask == "" ) {
55
+ log .Fatal ("Incorrect usage. 'gw' and 'mask' need to be specified when 'kernel_nw_args ' is set " )
49
56
}
50
- if err := taskWorkflow (* ip , * gateway , * netMask ); err != nil {
57
+ if err := taskWorkflow (* ip , * kernelNetworkArgs , * gateway , * netMask , * macAddress , * hostDevName , * netNS ); err != nil {
51
58
log .Fatal (err )
52
59
}
53
60
}
54
61
55
- func taskWorkflow (containerIP string , gateway string , netMask string ) error {
62
+ func taskWorkflow (
63
+ containerIP string ,
64
+ kernelNetworkArgs bool ,
65
+ gateway string ,
66
+ netMask string ,
67
+ macAddress string ,
68
+ hostDevName string ,
69
+ netNS string ,
70
+ ) error {
56
71
log .Println ("Creating containerd client" )
57
72
client , err := containerd .New ("/run/containerd/containerd.sock" )
58
73
if err != nil {
@@ -93,21 +108,23 @@ func taskWorkflow(containerIP string, gateway string, netMask string) error {
93
108
task , err := container .NewTask (ctx ,
94
109
cio .NewCreator (cio .WithStdio ),
95
110
func (ctx context.Context , _ * containerd.Client , ti * containerd.TaskInfo ) error {
96
- if containerIP == "" {
111
+ if containerIP == "" && netNS == "" {
112
+ // No params to configure, return.
97
113
return nil
98
114
}
99
- // An IP address for the container has been provided. Configure
100
- // the VM opts accordingly.
101
- firecrackerConfig := & proto.FirecrackerConfig {
102
- NetworkInterfaces : []* proto.FirecrackerNetworkInterface {
103
- {
104
- MacAddress : macAddress ,
105
- HostDevName : hostDevName ,
106
- },
107
- },
108
- KernelArgs : fmt .Sprintf (kernelArgsFormat , containerIP , gateway , netMask ),
115
+ // An IP address or the network namespace for the container has
116
+ // been provided. Configure VM opts accordingly.
117
+ builder := newFirecrackerConfigBuilder ()
118
+ if containerIP != "" {
119
+ builder .setNetworkConfig (macAddress , hostDevName )
109
120
}
110
- ti .Options = firecrackerConfig
121
+ if kernelNetworkArgs {
122
+ builder .setKernelNetworkArgs (containerIP , gateway , netMask )
123
+ }
124
+ if netNS != "" {
125
+ builder .setNetNS (netNS )
126
+ }
127
+ ti .Options = builder .build ()
111
128
return nil
112
129
})
113
130
if err != nil {
@@ -151,6 +168,47 @@ func taskWorkflow(containerIP string, gateway string, netMask string) error {
151
168
return nil
152
169
}
153
170
171
+ type firecrackerConfigBuilder struct {
172
+ vmConfig * proto.FirecrackerConfig
173
+ }
174
+
175
+ func newFirecrackerConfigBuilder () * firecrackerConfigBuilder {
176
+ return & firecrackerConfigBuilder {
177
+ vmConfig : & proto.FirecrackerConfig {},
178
+ }
179
+ }
180
+
181
+ func (builder * firecrackerConfigBuilder ) build () * proto.FirecrackerConfig {
182
+ return builder .vmConfig
183
+ }
184
+
185
+ // setNetworkConfig sets the fields in the protobuf message required to
186
+ // configure the VM with the container IP, gateway and netmask sepcified.
187
+ func (builder * firecrackerConfigBuilder ) setNetworkConfig (
188
+ macAddress string ,
189
+ hostDevName string ,
190
+ ) {
191
+ builder .vmConfig .NetworkInterfaces = []* proto.FirecrackerNetworkInterface {
192
+ {
193
+ MacAddress : macAddress ,
194
+ HostDevName : hostDevName ,
195
+ },
196
+ }
197
+ }
198
+
199
+ func (builder * firecrackerConfigBuilder ) setKernelNetworkArgs (
200
+ containerIP string ,
201
+ gateway string ,
202
+ netMask string ,
203
+ ) {
204
+ builder .vmConfig .KernelArgs = fmt .Sprintf (kernelArgsFormat , containerIP , gateway , netMask )
205
+ }
206
+
207
+ // setNetNS sets the network namespace field in the protobuf message.
208
+ func (builder * firecrackerConfigBuilder ) setNetNS (netNS string ) {
209
+ builder .vmConfig .FirecrackerNetworkNamespace = netNS
210
+ }
211
+
154
212
func getResponse (containerIP string ) {
155
213
response , err := http .Get ("http://" + containerIP )
156
214
if err != nil {
0 commit comments