Codebase list golang-gopkg-lxc-go-lxc.v2 / ddbd03cc-ca00-42a1-91eb-5a51ebd4e85f/upstream
Import upstream version 0.0+git20210525.76e43f7 Debian Janitor 2 years ago
52 changed file(s) with 818 addition(s) and 356 deletion(s). Raw diff Collapse all Expand all
0 name: Static analysis
1 on:
2 - push
3 - pull_request
4
5 jobs:
6 test:
7 runs-on: ubuntu-20.04
8 steps:
9 - name: Install Go
10 uses: actions/setup-go@v2
11 with:
12 go-version: 1.16.x
13
14 - name: Checkout code
15 uses: actions/checkout@v2
16
17 - name: Validate Go modules
18 run: |
19 make update-gomod
20 git diff --exit-code
21
22 - name: Install dependencies
23 run: |
24 sudo add-apt-repository ppa:ubuntu-lxc/daily -y
25 sudo apt-get install -qq lxc-dev pkg-config
26 go get golang.org/x/lint/golint
27 go get golang.org/x/tools/cmd/goimports
28
29 - name: Static analysis
30 run: make all
0 name: CI tests
1 on:
2 - push
3 - pull_request
4
5 jobs:
6 test:
7 strategy:
8 fail-fast: false
9 matrix:
10 go:
11 - 1.13.x
12 - 1.14.x
13 - 1.15.x
14 - 1.16.x
15 os:
16 - ubuntu-18.04
17 - ubuntu-20.04
18 runs-on: ${{ matrix.os }}
19 steps:
20 - name: Install Go
21 uses: actions/setup-go@v2
22 with:
23 go-version: ${{ matrix.go }}
24
25 - name: Checkout code
26 uses: actions/checkout@v2
27
28 - name: Install dependencies
29 run: |
30 sudo add-apt-repository ppa:ubuntu-lxc/daily -y
31 sudo apt-get install -qq lxc lxc-dev pkg-config uidmap busybox
32
33 - name: Setup test environment
34 run: |
35 # Setup uid/gid and veth allocations
36 echo "${USER}:100000:65536" | sudo tee /etc/subuid
37 echo "${USER}:100000:65536" | sudo tee /etc/subgid
38 echo "${USER} veth lxcbr0 10" | sudo tee -a /etc/lxc/lxc-usernet
39
40 # Local user configuration for userns
41 mkdir -p ~/.config/lxc/
42 cp /etc/lxc/default.conf ~/.config/lxc/default.conf
43 echo "lxc.idmap = u 0 100000 65536" | tee -a ~/.config/lxc/default.conf
44 echo "lxc.idmap = g 0 100000 65536" | tee -a ~/.config/lxc/default.conf
45
46 # Allow traversal to the containers
47 mkdir -p ~/.local/share/lxc
48 chmod +x ~/ ~/.local ~/.local/share ~/.local/share/lxc
49
50 - name: Build the test
51 run:
52 go test -c -coverprofile=profile
53
54 - name: Unprivileged tests
55 env:
56 DOWNLOAD_KEYSERVER: keyserver.ubuntu.com
57 run: |
58 # Make all cgroups writable
59 for d in /sys/fs/cgroup/*; do
60 [ -f $d/cgroup.clone_children ] && echo 1 | sudo tee $d/cgroup.clone_children
61 [ -f $d/cgroup.use_hierarchy ] && echo 1 | sudo tee $d/cgroup.use_hierarchy
62
63 sudo mkdir -p $d/lxc-test
64 sudo chown -R $USER: $d/lxc-test
65 echo $$ | sudo tee $d/lxc-test/cgroup.procs
66 done
67
68 # Run the unprivileged tests
69 ./go-lxc.test -test.v -test.coverprofile=/tmp/unpriv.out
70
71 - name: Privileged tests
72 env:
73 DOWNLOAD_KEYSERVER: keyserver.ubuntu.com
74 run:
75 sudo -E ./go-lxc.test -test.v -test.coverprofile=/tmp/priv.out
76
77 - name: Code coverage
78 run: make cover
22 coverage.out
33 tags
44 *.swp
5 **/.idea
+0
-51
.travis.yml less more
0 language: go
1
2 os:
3 - linux
4
5 go:
6 - 1.10.x
7 - 1.11.x
8 - 1.12.x
9 - 1.13.x
10 - 1.14.x
11 - tip
12
13 matrix:
14 fast_finish: true
15 allow_failures:
16 - go: tip
17
18 before_install:
19 - sudo add-apt-repository ppa:ubuntu-lxc/daily -y
20 - sudo apt-get update
21 - sudo apt-get install -qq lxc lxc-dev uidmap busybox
22 - echo "${USER}:100000:65536" | sudo tee /etc/subuid
23 - echo "${USER}:100000:65536" | sudo tee /etc/subgid
24 - echo "${USER} veth lxcbr0 10" | sudo tee -a /etc/lxc/lxc-usernet
25 - mkdir -p ${HOME}/.config/lxc/
26 - cp /etc/lxc/default.conf ${HOME}/.config/lxc/default.conf
27 - echo "lxc.id_map = u 0 100000 65536" | sudo tee -a ${HOME}/.config/lxc/default.conf
28 - echo "lxc.id_map = g 0 100000 65536" | sudo tee -a ${HOME}/.config/lxc/default.conf
29 - "make setup-test-cgroup"
30 - mkdir -p ${HOME}/.local/share/lxc
31 - chmod +x ${HOME}
32 - chmod +x ${HOME}/.local
33 - chmod +x ${HOME}/.local/share
34 - chmod +x ${HOME}/.local/share/lxc
35
36 install:
37 - go get golang.org/x/tools/cmd/goimports
38 - go get golang.org/x/sys/unix
39 - go get gopkg.in/lxc/go-lxc.v2
40
41 script:
42 - "make all"
43 - "make test"
44 - "make test-race"
45 - "make test-privileged"
46 - "make test-privileged-race"
47 - "make cover"
48
49 notifications:
50 webhooks: https://linuxcontainers.org/webhook-lxcbot/
5050 ctags:
5151 @ctags -R --languages=c,go
5252
53 update-gomod:
54 go get -t -v -d -u ./...
55 go mod tidy
56
5357 scope:
5458 @echo "$(OK_COLOR)==> Exported container calls in container.go $(NO_COLOR)"
5559 @/bin/grep -E "\bc+\.([A-Z])\w+" container.go || true
5660
57 setup-test-cgroup:
58 for d in /sys/fs/cgroup/*; do \
59 [ -f $$d/cgroup.clone_children ] && echo 1 | sudo tee $$d/cgroup.clone_children; \
60 [ -f $$d/cgroup.use_hierarchy ] && echo 1 | sudo tee $$d/cgroup.use_hierarchy; \
61 sudo mkdir -p $$d/lxc; \
62 sudo chown -R $$USER: $$d/lxc; \
63 done
64
6561 .PHONY: all format test doc vet lint ctags
0 // Copyright © 2013, 2014, The Go-LXC Authors. All rights reserved.
1 // Use of this source code is governed by a LGPLv2.1
2 // license that can be found in the LICENSE file.
3
4 package lxc
5
6 // #cgo CFLAGS: -fvisibility=hidden
7 import "C"
+0
-10
cgo_1.12.go less more
0 // Copyright © 2013, 2014, The Go-LXC Authors. All rights reserved.
1 // Use of this source code is governed by a LGPLv2.1
2 // license that can be found in the LICENSE file.
3
4 // +build >go1.10,linux,cgo
5
6 package lxc
7
8 // #cgo CFLAGS: -fvisibility=hidden
9 import "C"
1717 "os/exec"
1818 "path"
1919 "path/filepath"
20 "reflect"
2120 "strconv"
2221 "strings"
2322 "sync"
111110 if C.lxc_container_put(c.container) == -1 {
112111 return ErrReleaseFailed
113112 }
113
114 c.container = nil
115
114116 return nil
115117 }
116118
117119 func (c *Container) name() string {
120 if c.container == nil {
121 return ""
122 }
123
118124 return C.GoString(c.container.name)
119125 }
120126
136142
137143 // Caller needs to hold the lock
138144 func (c *Container) defined() bool {
145 if c.container == nil {
146 return false
147 }
148
139149 return bool(C.go_lxc_defined(c.container))
140150 }
141151
149159
150160 // Caller needs to hold the lock
151161 func (c *Container) running() bool {
162 if c.container == nil {
163 return false
164 }
165
152166 return bool(C.go_lxc_running(c.container))
153167 }
154168
165179 c.mu.RLock()
166180 defer c.mu.RUnlock()
167181
182 if c.container == nil {
183 return false
184 }
185
168186 return bool(C.go_lxc_may_control(c.container))
169187 }
170188
172190 func (c *Container) CreateSnapshot() (*Snapshot, error) {
173191 c.mu.Lock()
174192 defer c.mu.Unlock()
193
194 if c.container == nil {
195 return nil, ErrNotDefined
196 }
175197
176198 if err := c.makeSure(isDefined | isNotRunning); err != nil {
177199 return nil, err
189211 c.mu.Lock()
190212 defer c.mu.Unlock()
191213
214 if c.container == nil {
215 return ErrNotDefined
216 }
217
192218 if err := c.makeSure(isDefined); err != nil {
193219 return err
194220 }
210236 c.mu.Lock()
211237 defer c.mu.Unlock()
212238
239 if c.container == nil {
240 return ErrNotDefined
241 }
242
213243 if err := c.makeSure(isDefined); err != nil {
214244 return err
215245 }
228258 c.mu.Lock()
229259 defer c.mu.Unlock()
230260
261 if c.container == nil {
262 return ErrNotDefined
263 }
264
231265 if err := c.makeSure(isDefined | isGreaterEqualThanLXC11); err != nil {
232266 return err
233267 }
243277 c.mu.RLock()
244278 defer c.mu.RUnlock()
245279
280 if c.container == nil {
281 return nil, ErrNotDefined
282 }
283
246284 if err := c.makeSure(isDefined); err != nil {
247285 return nil, err
248286 }
256294 return nil, ErrNoSnapshot
257295 }
258296
259 hdr := reflect.SliceHeader{
260 Data: uintptr(unsafe.Pointer(csnapshots)),
261 Len: size,
262 Cap: size,
263 }
264 gosnapshots := *(*[]C.struct_lxc_snapshot)(unsafe.Pointer(&hdr))
265
297 gosnapshots := (*[(1 << 26) - 1]C.struct_lxc_snapshot)(unsafe.Pointer(csnapshots))[:size:size]
266298 snapshots := make([]Snapshot, size, size)
267299 for i := 0; i < size; i++ {
268300 snapshots[i] = Snapshot{
299331 c.mu.RLock()
300332 defer c.mu.RUnlock()
301333
334 if c.container == nil {
335 return -1
336 }
337
302338 return int(C.go_lxc_init_pid(c.container))
303339 }
304340
306342 func (c *Container) InitPidFd() (*os.File, error) {
307343 c.mu.RLock()
308344 defer c.mu.RUnlock()
345
346 if c.container == nil {
347 return nil, ErrNotDefined
348 }
309349
310350 pidfd := int(C.go_lxc_init_pidfd(c.container))
311351 if pidfd < 0 {
320360 c.mu.RLock()
321361 defer c.mu.RUnlock()
322362
363 if c.container == nil {
364 return nil, ErrNotDefined
365 }
366
323367 devptsFd := int(C.go_lxc_devpts_fd(c.container))
324368 if devptsFd < 0 {
325369 return nil, unix.Errno(unix.EBADF)
333377 c.mu.RLock()
334378 defer c.mu.RUnlock()
335379
380 if c.container == nil {
381 return nil, ErrNotDefined
382 }
383
336384 notifyFd := int(C.go_lxc_seccomp_notify_fd(c.container))
337385 if notifyFd < 0 {
338386 return nil, unix.Errno(unix.EBADF)
346394 c.mu.RLock()
347395 defer c.mu.RUnlock()
348396
397 if c.container == nil {
398 return nil, ErrNotDefined
399 }
400
349401 notifyFd := int(C.go_lxc_seccomp_notify_fd_active(c.container))
350402 if notifyFd < 0 {
351403 return nil, unix.Errno(unix.EBADF)
359411 c.mu.RLock()
360412 defer c.mu.RUnlock()
361413
414 if c.container == nil {
415 return false
416 }
417
362418 return bool(c.container.daemonize)
363419 }
364420
366422 func (c *Container) WantDaemonize(state bool) error {
367423 c.mu.Lock()
368424 defer c.mu.Unlock()
425
426 if c.container == nil {
427 return ErrNotDefined
428 }
369429
370430 if !bool(C.go_lxc_want_daemonize(c.container, C.bool(state))) {
371431 return ErrDaemonizeFailed
379439 c.mu.Lock()
380440 defer c.mu.Unlock()
381441
442 if c.container == nil {
443 return ErrNotDefined
444 }
445
382446 if !bool(C.go_lxc_want_close_all_fds(c.container, C.bool(state))) {
383447 return ErrCloseAllFdsFailed
384448 }
397461 func (c *Container) Freeze() error {
398462 c.mu.Lock()
399463 defer c.mu.Unlock()
464
465 if c.container == nil {
466 return ErrNotDefined
467 }
400468
401469 // check the state using lockless version
402470 if c.state() == FROZEN {
414482 func (c *Container) Unfreeze() error {
415483 c.mu.Lock()
416484 defer c.mu.Unlock()
485
486 if c.container == nil {
487 return ErrNotDefined
488 }
417489
418490 if err := c.makeSure(isRunning); err != nil {
419491 return err
529601 c.mu.Lock()
530602 defer c.mu.Unlock()
531603
604 if c.container == nil {
605 return ErrNotDefined
606 }
607
532608 if err := c.makeSure(isNotRunning); err != nil {
533609 return err
534610 }
543619 func (c *Container) StartWithArgs(args []string) error {
544620 c.mu.Lock()
545621 defer c.mu.Unlock()
622
623 if c.container == nil {
624 return ErrNotDefined
625 }
546626
547627 if err := c.makeSure(isNotRunning); err != nil {
548628 return err
559639 func (c *Container) StartExecute(args []string) error {
560640 c.mu.Lock()
561641 defer c.mu.Unlock()
642
643 if c.container == nil {
644 return ErrNotDefined
645 }
562646
563647 if err := c.makeSure(isNotRunning); err != nil {
564648 return err
607691 c.mu.Lock()
608692 defer c.mu.Unlock()
609693
694 if c.container == nil {
695 return ErrNotDefined
696 }
697
610698 if err := c.makeSure(isRunning); err != nil {
611699 return err
612700 }
622710 c.mu.Lock()
623711 defer c.mu.Unlock()
624712
713 if c.container == nil {
714 return ErrNotDefined
715 }
716
625717 if err := c.makeSure(isRunning); err != nil {
626718 return err
627719 }
637729 c.mu.Lock()
638730 defer c.mu.Unlock()
639731
732 if c.container == nil {
733 return ErrNotDefined
734 }
735
640736 if err := c.makeSure(isRunning); err != nil {
641737 return err
642738 }
652748 c.mu.Lock()
653749 defer c.mu.Unlock()
654750
751 if c.container == nil {
752 return ErrNotDefined
753 }
754
655755 if err := c.makeSure(isDefined | isNotRunning); err != nil {
656756 return err
657757 }
666766 func (c *Container) DestroyWithAllSnapshots() error {
667767 c.mu.Lock()
668768 defer c.mu.Unlock()
769
770 if c.container == nil {
771 return ErrNotDefined
772 }
669773
670774 if err := c.makeSure(isDefined | isNotRunning | isGreaterEqualThanLXC11); err != nil {
671775 return err
739843 c.mu.Lock()
740844 defer c.mu.Unlock()
741845
846 if c.container == nil {
847 return ErrNotDefined
848 }
849
742850 if err := c.makeSure(isDefined | isNotRunning); err != nil {
743851 return err
744852 }
757865 c.mu.Lock()
758866 defer c.mu.Unlock()
759867
868 if c.container == nil {
869 return false
870 }
871
760872 cstate := C.CString(state.String())
761873 defer C.free(unsafe.Pointer(cstate))
762874
767879 func (c *Container) ConfigFileName() string {
768880 c.mu.RLock()
769881 defer c.mu.RUnlock()
882
883 if c.container == nil {
884 return ""
885 }
770886
771887 // allocated in lxc.c
772888 configFileName := C.go_lxc_config_file_name(c.container)
776892 }
777893
778894 func (c *Container) configItem(key string) []string {
895 if c.container == nil {
896 return nil
897 }
898
779899 ckey := C.CString(key)
780900 defer C.free(unsafe.Pointer(ckey))
781901
796916 }
797917
798918 func (c *Container) setConfigItem(key string, value string) error {
919 if c.container == nil {
920 return ErrNotDefined
921 }
922
799923 ckey := C.CString(key)
800924 defer C.free(unsafe.Pointer(ckey))
801925
817941 }
818942
819943 func (c *Container) runningConfigItem(key string) []string {
944 if c.container == nil {
945 return nil
946 }
947
820948 ckey := C.CString(key)
821949 defer C.free(unsafe.Pointer(ckey))
822950
853981 }
854982
855983 func (c *Container) setCgroupItem(key string, value string) error {
984 if c.container == nil {
985 return ErrNotDefined
986 }
987
856988 ckey := C.CString(key)
857989 defer C.free(unsafe.Pointer(ckey))
858990
8861018 c.mu.Lock()
8871019 defer c.mu.Unlock()
8881020
1021 if c.container == nil {
1022 return
1023 }
1024
8891025 C.go_lxc_clear_config(c.container)
8901026 }
8911027
8941030 c.mu.Lock()
8951031 defer c.mu.Unlock()
8961032
1033 if c.container == nil {
1034 return ErrNotDefined
1035 }
1036
8971037 ckey := C.CString(key)
8981038 defer C.free(unsafe.Pointer(ckey))
8991039
9071047 func (c *Container) ConfigKeys(key ...string) []string {
9081048 c.mu.RLock()
9091049 defer c.mu.RUnlock()
1050
1051 if c.container == nil {
1052 return nil
1053 }
9101054
9111055 var ret string
9121056 if key != nil && len(key) == 1 {
9341078 c.mu.Lock()
9351079 defer c.mu.Unlock()
9361080
1081 if c.container == nil {
1082 return ErrNotDefined
1083 }
1084
9371085 cpath := C.CString(path)
9381086 defer C.free(unsafe.Pointer(cpath))
9391087
9441092 }
9451093
9461094 func (c *Container) saveConfigFile(path string) error {
1095 if c.container == nil {
1096 return ErrNotDefined
1097 }
1098
9471099 cpath := C.CString(path)
9481100 defer C.free(unsafe.Pointer(cpath))
9491101
9621114 }
9631115
9641116 func (c *Container) configPath() string {
1117 if c.container == nil {
1118 return ""
1119 }
1120
9651121 return C.GoString(C.go_lxc_get_config_path(c.container))
9661122 }
9671123
9771133 func (c *Container) SetConfigPath(path string) error {
9781134 c.mu.Lock()
9791135 defer c.mu.Unlock()
1136
1137 if c.container == nil {
1138 return ErrNotDefined
1139 }
9801140
9811141 cpath := C.CString(path)
9821142 defer C.free(unsafe.Pointer(cpath))
12321392 c.mu.Lock()
12331393 defer c.mu.Unlock()
12341394
1395 if c.container == nil {
1396 return -1, ErrNotDefined
1397 }
1398
12351399 // FIXME: Make idiomatic
12361400 if err := c.makeSure(isRunning); err != nil {
12371401 return -1, err
12501414 func (c *Container) Console(options ConsoleOptions) error {
12511415 c.mu.Lock()
12521416 defer c.mu.Unlock()
1417
1418 if c.container == nil {
1419 return ErrNotDefined
1420 }
12531421
12541422 if err := c.makeSure(isRunning); err != nil {
12551423 return err
12741442 c.mu.Lock()
12751443 defer c.mu.Unlock()
12761444
1445 if c.container == nil {
1446 return ErrNotDefined
1447 }
1448
12771449 if err := c.makeSure(isRunning); err != nil {
12781450 return err
12791451 }
12921464
12931465 cwd := C.CString(options.Cwd)
12941466 defer C.free(unsafe.Pointer(cwd))
1467
1468 groups := makeGroups(options.Groups)
12951469
12961470 ret := int(C.go_lxc_attach(c.container,
12971471 C.bool(options.ClearEnv),
12991473 C.long(options.Arch),
13001474 C.uid_t(options.UID),
13011475 C.gid_t(options.GID),
1476 groups,
13021477 C.int(options.StdinFd),
13031478 C.int(options.StdoutFd),
13041479 C.int(options.StderrFd),
13051480 cwd,
13061481 cenv,
13071482 cenvToKeep,
1483 C.int(attachFlags(options)),
13081484 ))
13091485 if ret < 0 {
13101486 return ErrAttachFailed
13121488 return nil
13131489 }
13141490
1491 func attachFlags(opts AttachOptions) int {
1492 flags := C.LXC_ATTACH_DEFAULT
1493
1494 if opts.RemountSysProc {
1495 flags |= C.LXC_ATTACH_REMOUNT_PROC_SYS
1496 }
1497
1498 if opts.ElevatedPrivileges {
1499 flags &^= (C.LXC_ATTACH_MOVE_TO_CGROUP | C.LXC_ATTACH_DROP_CAPABILITIES | C.LXC_ATTACH_LSM_EXEC)
1500 }
1501 return flags
1502 }
1503
1504 func makeGroups(groups []int) C.struct_lxc_groups_t {
1505 if len(groups) == 0 {
1506 return C.struct_lxc_groups_t{size: 0, list: nil}
1507 }
1508 l := make([]C.gid_t, len(groups))
1509 for i, g := range groups {
1510 l[i] = C.gid_t(g)
1511 }
1512 return C.struct_lxc_groups_t{size: C.size_t(len(groups)), list: &l[0]}
1513 }
1514
13151515 func (c *Container) runCommandStatus(args []string, options AttachOptions) (int, error) {
1516 if c.container == nil {
1517 return -1, ErrNotDefined
1518 }
1519
13161520 if len(args) == 0 {
13171521 return -1, ErrInsufficientNumberOfArguments
13181522 }
13411545
13421546 cwd := C.CString(options.Cwd)
13431547 defer C.free(unsafe.Pointer(cwd))
1548
1549 groups := makeGroups(options.Groups)
13441550
13451551 ret := int(C.go_lxc_attach_run_wait(
13461552 c.container,
13491555 C.long(options.Arch),
13501556 C.uid_t(options.UID),
13511557 C.gid_t(options.GID),
1558 groups,
13521559 C.int(options.StdinFd),
13531560 C.int(options.StdoutFd),
13541561 C.int(options.StderrFd),
13561563 cenv,
13571564 cenvToKeep,
13581565 cargs,
1566 C.int(attachFlags(options)),
13591567 ))
13601568
13611569 if ret < 0 {
14101618
14111619 cwd := C.CString(options.Cwd)
14121620 defer C.free(unsafe.Pointer(cwd))
1621
1622 groups := makeGroups(options.Groups)
14131623
14141624 var attachedPid C.pid_t
14151625 ret := int(C.go_lxc_attach_no_wait(
14191629 C.long(options.Arch),
14201630 C.uid_t(options.UID),
14211631 C.gid_t(options.GID),
1632 groups,
14221633 C.int(options.StdinFd),
14231634 C.int(options.StdoutFd),
14241635 C.int(options.StderrFd),
14271638 cenvToKeep,
14281639 cargs,
14291640 &attachedPid,
1641 C.int(attachFlags(options)),
14301642 ))
14311643
14321644 if ret < 0 {
14571669 func (c *Container) Interfaces() ([]string, error) {
14581670 c.mu.RLock()
14591671 defer c.mu.RUnlock()
1672
1673 if c.container == nil {
1674 return nil, ErrNotDefined
1675 }
14601676
14611677 if err := c.makeSure(isRunning); err != nil {
14621678 return nil, err
15261742 c.mu.RLock()
15271743 defer c.mu.RUnlock()
15281744
1745 if c.container == nil {
1746 return nil, ErrNotDefined
1747 }
1748
15291749 if err := c.makeSure(isRunning); err != nil {
15301750 return nil, err
15311751 }
15451765 c.mu.RLock()
15461766 defer c.mu.RUnlock()
15471767
1768 if c.container == nil {
1769 return nil, ErrNotDefined
1770 }
1771
15481772 if err := c.makeSure(isRunning); err != nil {
15491773 return nil, err
15501774 }
15661790 func (c *Container) IPv6Address(interfaceName string) ([]string, error) {
15671791 c.mu.RLock()
15681792 defer c.mu.RUnlock()
1793
1794 if c.container == nil {
1795 return nil, ErrNotDefined
1796 }
15691797
15701798 if err := c.makeSure(isRunning); err != nil {
15711799 return nil, err
16041832 }
16051833
16061834 func (c *Container) ipAddresses() ([]string, error) {
1835 if c.container == nil {
1836 return nil, ErrNotDefined
1837 }
1838
16071839 if err := c.makeSure(isRunning); err != nil {
16081840 return nil, err
16091841 }
16291861 c.mu.RLock()
16301862 defer c.mu.RUnlock()
16311863
1864 if c.container == nil {
1865 return nil, ErrNotDefined
1866 }
1867
16321868 if err := c.makeSure(isRunning); err != nil {
16331869 return nil, err
16341870 }
16471883 func (c *Container) IPv6Addresses() ([]string, error) {
16481884 c.mu.RLock()
16491885 defer c.mu.RUnlock()
1886
1887 if c.container == nil {
1888 return nil, ErrNotDefined
1889 }
16501890
16511891 if err := c.makeSure(isRunning); err != nil {
16521892 return nil, err
17261966 c.mu.Lock()
17271967 defer c.mu.Unlock()
17281968
1969 if c.container == nil {
1970 return ErrNotDefined
1971 }
1972
17291973 if err := c.makeSure(isRunning | isPrivileged); err != nil {
17301974 return err
17311975 }
17541998 c.mu.Lock()
17551999 defer c.mu.Unlock()
17562000
2001 if c.container == nil {
2002 return ErrNotDefined
2003 }
2004
17572005 if err := c.makeSure(isRunning | isPrivileged); err != nil {
17582006 return err
17592007 }
17822030 c.mu.Lock()
17832031 defer c.mu.Unlock()
17842032
2033 if c.container == nil {
2034 return ErrNotDefined
2035 }
2036
17852037 if err := c.makeSure(isRunning | isGreaterEqualThanLXC11); err != nil {
17862038 return err
17872039 }
18032055 c.mu.Lock()
18042056 defer c.mu.Unlock()
18052057
2058 if c.container == nil {
2059 return ErrNotDefined
2060 }
2061
18062062 if err := c.makeSure(isGreaterEqualThanLXC11); err != nil {
18072063 return err
18082064 }
18222078 func (c *Container) Migrate(cmd uint, opts MigrateOptions) error {
18232079 c.mu.Lock()
18242080 defer c.mu.Unlock()
2081
2082 if c.container == nil {
2083 return ErrNotDefined
2084 }
18252085
18262086 if err := c.makeSure(isNotDefined | isGreaterEqualThanLXC20); err != nil {
18272087 return err
18792139 c.mu.Lock()
18802140 defer c.mu.Unlock()
18812141
2142 if c.container == nil {
2143 return ErrNotDefined
2144 }
2145
18822146 if err := c.makeSure(isRunning | isPrivileged | isGreaterEqualThanLXC11); err != nil {
18832147 return err
18842148 }
19002164 c.mu.Lock()
19012165 defer c.mu.Unlock()
19022166
2167 if c.container == nil {
2168 return ErrNotDefined
2169 }
2170
19032171 if err := c.makeSure(isRunning | isPrivileged | isGreaterEqualThanLXC11); err != nil {
19042172 return err
19052173 }
19172185 func (c *Container) DetachInterfaceRename(source, target string) error {
19182186 c.mu.Lock()
19192187 defer c.mu.Unlock()
2188
2189 if c.container == nil {
2190 return ErrNotDefined
2191 }
19202192
19212193 if err := c.makeSure(isRunning | isPrivileged | isGreaterEqualThanLXC11); err != nil {
19222194 return err
19392211 func (c *Container) ConsoleLog(opt ConsoleLogOptions) ([]byte, error) {
19402212 c.mu.Lock()
19412213 defer c.mu.Unlock()
2214
2215 if c.container == nil {
2216 return nil, ErrNotDefined
2217 }
19422218
19432219 cl := C.struct_lxc_console_log{
19442220 clear: C.bool(opt.ClearLog),
19752251
19762252 // ErrorNum returns the error_num field of the container.
19772253 func (c *Container) ErrorNum() int {
2254 if c.container == nil {
2255 return -1
2256 }
2257
19782258 cError := C.go_lxc_error_num(c.container)
19792259 return int(cError)
19802260 }
66 package lxc
77
88 const (
9 ErrAddDeviceNodeFailed = lxcError("adding device to container failed")
10 ErrAllocationFailed = lxcError("allocating memory failed")
11 ErrAlreadyDefined = lxcError("container already defined")
12 ErrAlreadyFrozen = lxcError("container is already frozen")
13 ErrAlreadyRunning = lxcError("container is already running")
14 ErrAttachFailed = lxcError("attaching to the container failed")
15 ErrAttachInterfaceFailed = lxcError("attaching specified netdev to the container failed")
16 ErrBlkioUsage = lxcError("BlkioUsage for the container failed")
17 ErrCheckpointFailed = lxcError("checkpoint failed")
18 ErrClearingConfigItemFailed = lxcError("clearing config item for the container failed")
19 ErrClearingCgroupItemFailed = lxcError("clearing cgroup item for the container failed")
20 ErrCloneFailed = lxcError("cloning the container failed")
21 ErrCloseAllFdsFailed = lxcError("setting close_all_fds flag for container failed")
22 ErrCreateFailed = lxcError("creating the container failed")
23 ErrCreateSnapshotFailed = lxcError("snapshotting the container failed")
24 ErrDaemonizeFailed = lxcError("setting daemonize flag for container failed")
25 ErrDestroyAllSnapshotsFailed = lxcError("destroying all snapshots failed")
26 ErrDestroyFailed = lxcError("destroying the container failed")
27 ErrDestroySnapshotFailed = lxcError("destroying the snapshot failed")
9 // ErrAddDeviceNodeFailed - adding device to container failed
10 ErrAddDeviceNodeFailed = lxcError("adding device to container failed")
11
12 // ErrAllocationFailed - allocating memory failed
13 ErrAllocationFailed = lxcError("allocating memory failed")
14
15 // ErrAlreadyDefined - container already defined
16 ErrAlreadyDefined = lxcError("container already defined")
17
18 // ErrAlreadyFrozen - container is already frozen
19 ErrAlreadyFrozen = lxcError("container is already frozen")
20
21 // ErrAlreadyRunning - container is already running
22 ErrAlreadyRunning = lxcError("container is already running")
23
24 // ErrAttachFailed - attaching to the container failed
25 ErrAttachFailed = lxcError("attaching to the container failed")
26
27 // ErrAttachInterfaceFailed - attaching specified netdev to the container failed
28 ErrAttachInterfaceFailed = lxcError("attaching specified netdev to the container failed")
29
30 // ErrBlkioUsage - BlkioUsage for the container failed
31 ErrBlkioUsage = lxcError("BlkioUsage for the container failed")
32
33 // ErrCheckpointFailed - checkpoint failed
34 ErrCheckpointFailed = lxcError("checkpoint failed")
35
36 // ErrClearingConfigItemFailed - clearing config item for the container failed
37 ErrClearingConfigItemFailed = lxcError("clearing config item for the container failed")
38
39 // ErrClearingCgroupItemFailed - clearing cgroup item for the container failed
40 ErrClearingCgroupItemFailed = lxcError("clearing cgroup item for the container failed")
41
42 // ErrCloneFailed - cloning the container failed
43 ErrCloneFailed = lxcError("cloning the container failed")
44
45 // ErrCloseAllFdsFailed - setting close_all_fds flag for container failed
46 ErrCloseAllFdsFailed = lxcError("setting close_all_fds flag for container failed")
47
48 // ErrCreateFailed - creating the container failed
49 ErrCreateFailed = lxcError("creating the container failed")
50
51 // ErrCreateSnapshotFailed - snapshotting the container failed
52 ErrCreateSnapshotFailed = lxcError("snapshotting the container failed")
53
54 // ErrDaemonizeFailed - setting daemonize flag for container failed
55 ErrDaemonizeFailed = lxcError("setting daemonize flag for container failed")
56
57 // ErrDestroyAllSnapshotsFailed - destroying all snapshots failed
58 ErrDestroyAllSnapshotsFailed = lxcError("destroying all snapshots failed")
59
60 // ErrDestroyFailed - destroying the container failed
61 ErrDestroyFailed = lxcError("destroying the container failed")
62
63 // ErrDestroySnapshotFailed - destroying the snapshot failed
64 ErrDestroySnapshotFailed = lxcError("destroying the snapshot failed")
65
66 // ErrDestroyWithAllSnapshotsFailed - destroying the container with all snapshots failed
2867 ErrDestroyWithAllSnapshotsFailed = lxcError("destroying the container with all snapshots failed")
29 ErrDetachInterfaceFailed = lxcError("detaching specified netdev to the container failed")
30 ErrExecuteFailed = lxcError("executing the command in a temporary container failed")
31 ErrFreezeFailed = lxcError("freezing the container failed")
68
69 // ErrDetachInterfaceFailed - detaching specified netdev to the container failed
70 ErrDetachInterfaceFailed = lxcError("detaching specified netdev to the container failed")
71
72 // ErrExecuteFailed - executing the command in a temporary container failed
73 ErrExecuteFailed = lxcError("executing the command in a temporary container failed")
74
75 // ErrFreezeFailed - freezing the container failed
76 ErrFreezeFailed = lxcError("freezing the container failed")
77
78 // ErrInsufficientNumberOfArguments - insufficient number of arguments were supplied
3279 ErrInsufficientNumberOfArguments = lxcError("insufficient number of arguments were supplied")
33 ErrInterfaces = lxcError("getting interface names for the container failed")
34 ErrIPAddresses = lxcError("getting IP addresses of the container failed")
35 ErrIPAddress = lxcError("getting IP address on the interface of the container failed")
36 ErrIPv4Addresses = lxcError("getting IPv4 addresses of the container failed")
37 ErrIPv6Addresses = lxcError("getting IPv6 addresses of the container failed")
38 ErrKMemLimit = lxcError("your kernel does not support cgroup kernel memory controller")
39 ErrLoadConfigFailed = lxcError("loading config file for the container failed")
40 ErrMemLimit = lxcError("your kernel does not support cgroup memory controller")
41 ErrMemorySwapLimit = lxcError("your kernel does not support cgroup swap controller")
42 ErrMethodNotAllowed = lxcError("the requested method is not currently supported with unprivileged containers")
43 ErrNewFailed = lxcError("allocating the container failed")
44 ErrNoSnapshot = lxcError("container has no snapshot")
45 ErrNotDefined = lxcError("container is not defined")
46 ErrNotFrozen = lxcError("container is not frozen")
47 ErrNotRunning = lxcError("container is not running")
48 ErrNotSupported = lxcError("method is not supported by this LXC version")
49 ErrRebootFailed = lxcError("rebooting the container failed")
50 ErrRemoveDeviceNodeFailed = lxcError("removing device from container failed")
51 ErrRenameFailed = lxcError("renaming the container failed")
52 ErrRestoreFailed = lxcError("restore failed")
53 ErrRestoreSnapshotFailed = lxcError("restoring the container failed")
54 ErrSaveConfigFailed = lxcError("saving config file for the container failed")
55 ErrSettingCgroupItemFailed = lxcError("setting cgroup item for the container failed")
56 ErrSettingConfigItemFailed = lxcError("setting config item for the container failed")
57 ErrSettingConfigPathFailed = lxcError("setting config file for the container failed")
58 ErrSettingKMemoryLimitFailed = lxcError("setting kernel memory limit for the container failed")
59 ErrSettingMemoryLimitFailed = lxcError("setting memory limit for the container failed")
60 ErrSettingMemorySwapLimitFailed = lxcError("setting memory+swap limit for the container failed")
61 ErrSettingSoftMemoryLimitFailed = lxcError("setting soft memory limit for the container failed")
62 ErrShutdownFailed = lxcError("shutting down the container failed")
63 ErrSoftMemLimit = lxcError("your kernel does not support cgroup memory controller")
64 ErrStartFailed = lxcError("starting the container failed")
65 ErrStopFailed = lxcError("stopping the container failed")
66 ErrTemplateNotAllowed = lxcError("unprivileged users only allowed to use \"download\" template")
67 ErrUnfreezeFailed = lxcError("unfreezing the container failed")
68 ErrUnknownBackendStore = lxcError("unknown backend type")
69 ErrReleaseFailed = lxcError("releasing the container failed")
80
81 // ErrInterfaces - getting interface names for the container failed
82 ErrInterfaces = lxcError("getting interface names for the container failed")
83
84 // ErrIPAddresses - getting IP addresses of the container failed
85 ErrIPAddresses = lxcError("getting IP addresses of the container failed")
86
87 // ErrIPAddress - getting IP address on the interface of the container failed
88 ErrIPAddress = lxcError("getting IP address on the interface of the container failed")
89
90 // ErrIPv4Addresses - getting IPv4 addresses of the container failed
91 ErrIPv4Addresses = lxcError("getting IPv4 addresses of the container failed")
92
93 // ErrIPv6Addresses - getting IPv6 addresses of the container failed
94 ErrIPv6Addresses = lxcError("getting IPv6 addresses of the container failed")
95
96 // ErrKMemLimit - your kernel does not support cgroup kernel memory controller
97 ErrKMemLimit = lxcError("your kernel does not support cgroup kernel memory controller")
98
99 // ErrLoadConfigFailed - loading config file for the container failed
100 ErrLoadConfigFailed = lxcError("loading config file for the container failed")
101
102 // ErrMemLimit - your kernel does not support cgroup memory controller
103 ErrMemLimit = lxcError("your kernel does not support cgroup memory controller")
104
105 // ErrMemorySwapLimit - your kernel does not support cgroup swap controller
106 ErrMemorySwapLimit = lxcError("your kernel does not support cgroup swap controller")
107
108 // ErrMethodNotAllowed - the requested method is not currently supported with unprivileged containers
109 ErrMethodNotAllowed = lxcError("the requested method is not currently supported with unprivileged containers")
110
111 // ErrNewFailed - allocating the container failed
112 ErrNewFailed = lxcError("allocating the container failed")
113
114 // ErrNoSnapshot - container has no snapshot
115 ErrNoSnapshot = lxcError("container has no snapshot")
116
117 // ErrNotDefined - container is not defined
118 ErrNotDefined = lxcError("container is not defined")
119
120 // ErrNotFrozen - container is not frozen
121 ErrNotFrozen = lxcError("container is not frozen")
122
123 // ErrNotRunning - container is not running
124 ErrNotRunning = lxcError("container is not running")
125
126 // ErrNotSupported - method is not supported by this LXC version
127 ErrNotSupported = lxcError("method is not supported by this LXC version")
128
129 // ErrRebootFailed - rebooting the container failed
130 ErrRebootFailed = lxcError("rebooting the container failed")
131
132 // ErrRemoveDeviceNodeFailed - removing device from container failed
133 ErrRemoveDeviceNodeFailed = lxcError("removing device from container failed")
134
135 // ErrRenameFailed - renaming the container failed
136 ErrRenameFailed = lxcError("renaming the container failed")
137
138 // ErrRestoreFailed - restore failed
139 ErrRestoreFailed = lxcError("restore failed")
140
141 // ErrRestoreSnapshotFailed - restoring the container failed
142 ErrRestoreSnapshotFailed = lxcError("restoring the container failed")
143
144 // ErrSaveConfigFailed - saving config file for the container failed
145 ErrSaveConfigFailed = lxcError("saving config file for the container failed")
146
147 // ErrSettingCgroupItemFailed - setting cgroup item for the container failed
148 ErrSettingCgroupItemFailed = lxcError("setting cgroup item for the container failed")
149
150 // ErrSettingConfigItemFailed - setting config item for the container failed
151 ErrSettingConfigItemFailed = lxcError("setting config item for the container failed")
152
153 // ErrSettingConfigPathFailed - setting config file for the container failed
154 ErrSettingConfigPathFailed = lxcError("setting config file for the container failed")
155
156 // ErrSettingKMemoryLimitFailed - setting kernel memory limit for the container failed
157 ErrSettingKMemoryLimitFailed = lxcError("setting kernel memory limit for the container failed")
158
159 // ErrSettingMemoryLimitFailed - setting memory limit for the container failed
160 ErrSettingMemoryLimitFailed = lxcError("setting memory limit for the container failed")
161
162 // ErrSettingMemorySwapLimitFailed - setting memory+swap limit for the container failed
163 ErrSettingMemorySwapLimitFailed = lxcError("setting memory+swap limit for the container failed")
164
165 // ErrSettingSoftMemoryLimitFailed - setting soft memory limit for the container failed
166 ErrSettingSoftMemoryLimitFailed = lxcError("setting soft memory limit for the container failed")
167
168 // ErrShutdownFailed - shutting down the container failed
169 ErrShutdownFailed = lxcError("shutting down the container failed")
170
171 // ErrSoftMemLimit - your kernel does not support cgroup memory controller
172 ErrSoftMemLimit = lxcError("your kernel does not support cgroup memory controller")
173
174 // ErrStartFailed - starting the container failed
175 ErrStartFailed = lxcError("starting the container failed")
176
177 // ErrStopFailed - stopping the container failed
178 ErrStopFailed = lxcError("stopping the container failed")
179
180 // ErrTemplateNotAllowed - unprivileged users only allowed to use "download" template
181 ErrTemplateNotAllowed = lxcError("unprivileged users only allowed to use \"download\" template")
182
183 // ErrUnfreezeFailed - unfreezing the container failed
184 ErrUnfreezeFailed = lxcError("unfreezing the container failed")
185
186 // ErrUnknownBackendStore - unknown backend type
187 ErrUnknownBackendStore = lxcError("unknown backend type")
188
189 // ErrReleaseFailed - releasing the container failed
190 ErrReleaseFailed = lxcError("releasing the container failed")
70191 )
71192
72193 type lxcError string
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
1212 "os"
1313 "sync"
1414
15 "gopkg.in/lxc/go-lxc.v2"
15 "github.com/lxc/go-lxc"
1616 )
1717
1818 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
1212 "strconv"
1313 "sync"
1414
15 "gopkg.in/lxc/go-lxc.v2"
15 "github.com/lxc/go-lxc"
1616 )
1717
1818 var (
1212 "strconv"
1313 "sync"
1414
15 "gopkg.in/lxc/go-lxc.v2"
15 "github.com/lxc/go-lxc"
1616 )
1717
1818 var (
1313 "sync"
1414 "time"
1515
16 "gopkg.in/lxc/go-lxc.v2"
16 "github.com/lxc/go-lxc"
1717 )
1818
1919 var (
1212 "strconv"
1313 "sync"
1414
15 "gopkg.in/lxc/go-lxc.v2"
15 "github.com/lxc/go-lxc"
1616 )
1717
1818 var (
1212 "strconv"
1313 "sync"
1414
15 "gopkg.in/lxc/go-lxc.v2"
15 "github.com/lxc/go-lxc"
1616 )
1717
1818 var (
1313 "strconv"
1414 "sync"
1515
16 "gopkg.in/lxc/go-lxc.v2"
16 "github.com/lxc/go-lxc"
1717 )
1818
1919 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
88 import (
99 "log"
1010
11 "gopkg.in/lxc/go-lxc.v2"
11 "github.com/lxc/go-lxc"
1212 )
1313
1414 func main() {
1010 "log"
1111 "time"
1212
13 "gopkg.in/lxc/go-lxc.v2"
13 "github.com/lxc/go-lxc"
1414 )
1515
1616 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
1010 "log"
1111 "time"
1212
13 "gopkg.in/lxc/go-lxc.v2"
13 "github.com/lxc/go-lxc"
1414 )
1515
1616 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
88 import (
99 "log"
1010
11 "gopkg.in/lxc/go-lxc.v2"
11 "github.com/lxc/go-lxc"
1212 )
1313
1414 func main() {
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
1010 "log"
1111 "time"
1212
13 "gopkg.in/lxc/go-lxc.v2"
13 "github.com/lxc/go-lxc"
1414 )
1515
1616 var (
1010 "log"
1111 "time"
1212
13 "gopkg.in/lxc/go-lxc.v2"
13 "github.com/lxc/go-lxc"
1414 )
1515
1616 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
99 "flag"
1010 "log"
1111
12 "gopkg.in/lxc/go-lxc.v2"
12 "github.com/lxc/go-lxc"
1313 )
1414
1515 var (
1010 "log"
1111 "time"
1212
13 "gopkg.in/lxc/go-lxc.v2"
13 "github.com/lxc/go-lxc"
1414 )
1515
1616 var (
0 module github.com/lxc/go-lxc
1
2 go 1.16
3
4 require golang.org/x/sys v0.0.0-20210521203332-0cec03c779c1
0 golang.org/x/sys v0.0.0-20210521203332-0cec03c779c1 h1:lCnv+lfrU9FRPGf8NeRuWAAPjNnema5WtBinMgs1fD8=
1 golang.org/x/sys v0.0.0-20210521203332-0cec03c779c1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
66 package lxc
77
88 // #cgo CFLAGS: -std=gnu11 -Wvla -Werror
9 // #cgo pkg-config: --static lxc
9 // #cgo pkg-config: --static lxc libcrypto
1010 // #cgo LDFLAGS: -static
1111 import "C"
288288 bool clear_env,
289289 int namespaces,
290290 long personality,
291 uid_t uid, gid_t gid,
291 uid_t uid, gid_t gid, lxc_groups_t groups,
292292 int stdinfd, int stdoutfd, int stderrfd,
293293 char *initial_cwd,
294294 char **extra_env_vars,
295295 char **extra_keep_env,
296296 const char * const argv[],
297 pid_t *attached_pid) {
297 pid_t *attached_pid,
298 int attach_flags) {
298299 int ret;
299300
300301 lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
302 attach_options.attach_flags = attach_flags;
303
301304 lxc_attach_command_t command = (lxc_attach_command_t){.program = NULL};
302305
303306 attach_options.env_policy = LXC_ATTACH_KEEP_ENV;
310313
311314 attach_options.uid = uid;
312315 attach_options.gid = gid;
316 #if VERSION_AT_LEAST(4, 0, 9)
317 if ( groups.size > 0 ) {
318 attach_options.groups = groups;
319 attach_options.attach_flags &= LXC_ATTACH_SETGROUPS;
320 }
321 #endif
313322
314323 attach_options.stdin_fd = stdinfd;
315324 attach_options.stdout_fd = stdoutfd;
333342 bool clear_env,
334343 int namespaces,
335344 long personality,
336 uid_t uid, gid_t gid,
345 uid_t uid, gid_t gid, lxc_groups_t groups,
337346 int stdinfd, int stdoutfd, int stderrfd,
338347 char *initial_cwd,
339348 char **extra_env_vars,
340 char **extra_keep_env) {
349 char **extra_keep_env,
350 int attach_flags) {
341351 int ret;
342352 pid_t pid;
343353
344354 lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
355 attach_options.attach_flags = attach_flags;
345356
346357 attach_options.env_policy = LXC_ATTACH_KEEP_ENV;
347358 if (clear_env) {
353364
354365 attach_options.uid = uid;
355366 attach_options.gid = gid;
367 #if VERSION_AT_LEAST(4, 0, 9)
368 if ( groups.size > 0 ) {
369 attach_options.groups = groups;
370 attach_options.attach_flags &= LXC_ATTACH_SETGROUPS;
371 }
372 #endif
356373
357374 attach_options.stdin_fd = stdinfd;
358375 attach_options.stdout_fd = stdoutfd;
361378 attach_options.initial_cwd = initial_cwd;
362379 attach_options.extra_env_vars = extra_env_vars;
363380 attach_options.extra_keep_env = extra_keep_env;
364
365 /*
366 remount_sys_proc
367 When using -s and the mount namespace is not included, this flag will cause lxc-attach to remount /proc and /sys to reflect the current other namespace contexts.
368 default_options.attach_flags |= LXC_ATTACH_REMOUNT_PROC_SYS;
369
370 elevated_privileges
371 Do not drop privileges when running command inside the container. If this option is specified, the new process will not be added to the container's cgroup(s) and it will not drop its capabilities before executing.
372 default_options.attach_flags &= ~(LXC_ATTACH_MOVE_TO_CGROUP | LXC_ATTACH_DROP_CAPABILITIES | LXC_ATTACH_APPARMOR);
373 */
374381
375382 ret = c->attach(c, lxc_attach_run_shell, NULL, &attach_options, &pid);
376383 if (ret < 0)
390397 bool clear_env,
391398 int namespaces,
392399 long personality,
393 uid_t uid, gid_t gid,
400 uid_t uid, gid_t gid, lxc_groups_t groups,
394401 int stdinfd, int stdoutfd, int stderrfd,
395402 char *initial_cwd,
396403 char **extra_env_vars,
397404 char **extra_keep_env,
398 const char * const argv[]) {
405 const char * const argv[],
406 int attach_flags) {
399407 int ret;
400408
401409 lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
410 attach_options.attach_flags = attach_flags;
402411
403412 attach_options.env_policy = LXC_ATTACH_KEEP_ENV;
404413 if (clear_env) {
410419
411420 attach_options.uid = uid;
412421 attach_options.gid = gid;
422 #if VERSION_AT_LEAST(4, 0, 9)
423 if ( groups.size > 0 ) {
424 attach_options.groups = groups;
425 attach_options.attach_flags &= LXC_ATTACH_SETGROUPS;
426 }
427 #endif
413428
414429 attach_options.stdin_fd = stdinfd;
415430 attach_options.stdout_fd = stdoutfd;
4747
4848 // Acquire increments the reference counter of the container object.
4949 func Acquire(c *Container) bool {
50 c.mu.RLock()
51 defer c.mu.RUnlock()
52
5053 return C.lxc_container_get(c.container) == 1
5154 }
5255
5356 // Release decrements the reference counter of the container object.
5457 func Release(c *Container) bool {
55 if C.lxc_container_put(c.container) == -1 {
56 return false
57 }
58 return true
58 return c.Release() == nil
5959 }
6060
6161 // Version returns the LXC version.
311311 }
312312
313313 // HasApiExtension returns true if the extension is supported.
314 // Deprecated: Please use HasAPIExtension instead.
314315 func HasApiExtension(extension string) bool {
316 return HasAPIExtension(extension)
317 }
318
319 // HasAPIExtension returns true if the extension is supported.
320 func HasAPIExtension(extension string) bool {
315321 if runtimeLiblxcVersionAtLeast(3, 1, 0) {
316322 apiExtension := C.CString(extension)
317323 defer C.free(unsafe.Pointer(apiExtension))
00 // Copyright © 2013, 2014, The Go-LXC Authors. All rights reserved.
11 // Use of this source code is governed by a LGPLv2.1
22 // license that can be found in the LICENSE file.
3
4 #include <lxc/attach_options.h>
35
46 #define VERSION_AT_LEAST(major, minor, micro) \
57 ((LXC_DEVEL == 1) || (!(major > LXC_VERSION_MAJOR || \
4547 extern char* go_lxc_get_running_config_item(struct lxc_container *c, const char *key);
4648 extern const char* go_lxc_get_config_path(struct lxc_container *c);
4749 extern const char* go_lxc_state(struct lxc_container *c);
50
51 #if !VERSION_AT_LEAST(4, 0, 9) && !defined(LXC_ATTACH_SETGROUPS)
52 typedef struct lxc_groups_t {
53 size_t size;
54 gid_t *list;
55 } lxc_groups_t;
56 # endif
57
4858 extern int go_lxc_attach_run_wait(struct lxc_container *c,
4959 bool clear_env,
5060 int namespaces,
5161 long personality,
52 uid_t uid, gid_t gid,
53 int stdinfd, int stdoutfd, int stderrfd,
54 char *initial_cwd,
55 char **extra_env_vars,
56 char **extra_keep_env,
57 const char * const argv[]);
58 extern int go_lxc_attach(struct lxc_container *c,
59 bool clear_env,
60 int namespaces,
61 long personality,
62 uid_t uid, gid_t gid,
63 int stdinfd, int stdoutfd, int stderrfd,
64 char *initial_cwd,
65 char **extra_env_vars,
66 char **extra_keep_env);
67 extern int go_lxc_attach_no_wait(struct lxc_container *c,
68 bool clear_env,
69 int namespaces,
70 long personality,
71 uid_t uid, gid_t gid,
62 uid_t uid, gid_t gid, lxc_groups_t groups,
7263 int stdinfd, int stdoutfd, int stderrfd,
7364 char *initial_cwd,
7465 char **extra_env_vars,
7566 char **extra_keep_env,
7667 const char * const argv[],
77 pid_t *attached_pid);
68 int attach_flags);
69 extern int go_lxc_attach(struct lxc_container *c,
70 bool clear_env,
71 int namespaces,
72 long personality,
73 uid_t uid, gid_t gid, lxc_groups_t groups,
74 int stdinfd, int stdoutfd, int stderrfd,
75 char *initial_cwd,
76 char **extra_env_vars,
77 char **extra_keep_env,
78 int attach_flags);
79 extern int go_lxc_attach_no_wait(struct lxc_container *c,
80 bool clear_env,
81 int namespaces,
82 long personality,
83 uid_t uid, gid_t gid, lxc_groups_t groups,
84 int stdinfd, int stdoutfd, int stderrfd,
85 char *initial_cwd,
86 char **extra_env_vars,
87 char **extra_keep_env,
88 const char * const argv[],
89 pid_t *attached_pid,
90 int attach_flags);
7891 extern int go_lxc_console_getfd(struct lxc_container *c, int ttynum);
7992 extern int go_lxc_snapshot_list(struct lxc_container *c, struct lxc_snapshot **ret);
8093 extern int go_lxc_snapshot(struct lxc_container *c);
2626 DefaultContainerRestoreName = "ipsum"
2727 DefaultContainerCloneName = "consectetur"
2828 DefaultContainerCloneOverlayName = "adipiscing"
29 DefaultContainerCloneAufsName = "pellentesque"
3029 )
3130
3231 func exists(name string) bool {
7574 }
7675
7776 func template() TemplateOptions {
78 if !unprivileged() {
79 return BusyboxTemplateOptions
80 }
81
82 // travis uses trusy which comes with lxc 1.0.x so use a compatible image
8377 return TemplateOptions{
8478 Template: "download",
85 Distro: "ubuntu",
86 Release: "trusty",
79 Distro: "alpine",
80 Release: "edge",
8781 Arch: "amd64",
8882 }
8983 }
116110 return DefaultContainerCloneOverlayName
117111 }
118112
119 func ContainerCloneAufsName() string {
120 if unprivileged() {
121 return fmt.Sprintf("%s-unprivileged", DefaultContainerCloneAufsName)
122 }
123 return DefaultContainerCloneAufsName
124 }
125
126113 func TestVersion(t *testing.T) {
127114 t.Logf("LXC version: %s", Version())
128115 }
163150 }
164151
165152 func TestConcurrentDefined_Negative(t *testing.T) {
153 t.Skip("Skipping concurrent tests for now")
154
166155 defer runtime.GOMAXPROCS(runtime.NumCPU())
167156
168157 var wg sync.WaitGroup
211200 }
212201 defer c.Release()
213202
203 c.SetConfigItem("lxc.apparmor.profile", "unconfined")
214204 if _, err := c.Execute("/bin/true"); err != nil {
215205 t.Errorf(err.Error())
216206 }
274264 }
275265 }
276266
277 func TestCloneUsingAufs(t *testing.T) {
278 if unprivileged() {
279 t.Skip("skipping test in unprivileged mode.")
280 }
281
282 if !supported("aufs") {
283 t.Skip("skipping test as aufs support is missing.")
284 }
285
286 c, err := NewContainer(ContainerName())
287 if err != nil {
288 t.Errorf(err.Error())
289 }
290 defer c.Release()
291
292 err = c.Clone(ContainerCloneAufsName(), CloneOptions{
293 Backend: Aufs,
294 KeepName: true,
295 KeepMAC: true,
296 Snapshot: true,
297 })
298 if err != nil {
299 t.Errorf(err.Error())
300 }
301 }
302
303267 func TestCreateSnapshot(t *testing.T) {
304268 c, err := NewContainer(ContainerName())
305269 if err != nil {
327291 }
328292
329293 func TestRestoreSnapshot(t *testing.T) {
294 if os.Getenv("GITHUB_ACTION") != "" {
295 t.Skip("Test broken on Github")
296 }
297
330298 c, err := NewContainer(ContainerName())
331299 if err != nil {
332300 t.Errorf(err.Error())
340308 }
341309
342310 func TestConcurrentCreate(t *testing.T) {
311 t.Skip("Skipping concurrent tests for now")
312
343313 defer runtime.GOMAXPROCS(runtime.NumCPU())
344
345 if unprivileged() {
346 t.Skip("skipping test in unprivileged mode.")
347 }
348314
349315 var wg sync.WaitGroup
350316
383349 }
384350
385351 func TestConcurrentStart(t *testing.T) {
352 t.Skip("Skipping concurrent tests for now")
353
386354 defer runtime.GOMAXPROCS(runtime.NumCPU())
387
388 if unprivileged() {
389 t.Skip("skipping test in unprivileged mode.")
390 }
391355
392356 var wg sync.WaitGroup
393357
440404 }
441405
442406 func TestConcurrentDefined_Positive(t *testing.T) {
407 t.Skip("Skipping concurrent tests for now")
408
443409 defer runtime.GOMAXPROCS(runtime.NumCPU())
444
445 if unprivileged() {
446 t.Skip("skipping test in unprivileged mode.")
447 }
448410
449411 var wg sync.WaitGroup
450412
510472 }
511473
512474 func TestWaitIPAddresses(t *testing.T) {
513 if !unprivileged() {
514 t.Skip("skipping test in privileged mode.")
515 }
516
517475 c, err := NewContainer(ContainerName())
518476 if err != nil {
519477 t.Errorf(err.Error())
722680 }
723681 defer c.Release()
724682
725 if c.ConfigItem("lxc.utsname")[0] != ContainerName() {
683 if c.ConfigItem("lxc.uts.name")[0] != ContainerName() {
726684 t.Errorf("ConfigItem failed...")
727685 }
728686 }
734692 }
735693 defer c.Release()
736694
737 if err := c.SetConfigItem("lxc.utsname", ContainerName()); err != nil {
738 t.Errorf(err.Error())
739 }
740
741 if c.ConfigItem("lxc.utsname")[0] != ContainerName() {
695 if err := c.SetConfigItem("lxc.uts.name", ContainerName()); err != nil {
696 t.Errorf(err.Error())
697 }
698
699 if c.ConfigItem("lxc.uts.name")[0] != ContainerName() {
742700 t.Errorf("ConfigItem failed...")
743701 }
744702 }
12081166
12091167 options := DefaultAttachOptions
12101168 options.ClearEnv = true
1211 options.EnvToKeep = []string{"TERM"}
1212
1213 args := []string{"/bin/sh", "-c", fmt.Sprintf("test $TERM = '%s'", os.Getenv("TERM"))}
1169 options.EnvToKeep = []string{"USER"}
1170
1171 args := []string{"/bin/sh", "-c", fmt.Sprintf("test $USER = '%s'", os.Getenv("USER"))}
12141172 ok, err := c.RunCommand(args, DefaultAttachOptions)
12151173 if err != nil {
12161174 t.Errorf(err.Error())
13911349 }
13921350
13931351 func TestIPv4Addresses(t *testing.T) {
1394 if !unprivileged() {
1395 t.Skip("skipping test in privileged mode.")
1396 }
1397
13981352 c, err := NewContainer(ContainerName())
13991353 if err != nil {
14001354 t.Errorf(err.Error())
14071361 }
14081362
14091363 func TestIPv6Addresses(t *testing.T) {
1410 if !unprivileged() {
1411 t.Skip("skipping test in privileged mode.")
1412 }
1413
14141364 if !ipv6() {
14151365 t.Skip("skipping test since lxc bridge does not have ipv6 address")
14161366 }
14401390 }
14411391
14421392 func TestConcurrentShutdown(t *testing.T) {
1393 t.Skip("Skipping concurrent tests for now")
1394
14431395 defer runtime.GOMAXPROCS(runtime.NumCPU())
1444
1445 if unprivileged() {
1446 t.Skip("skipping test in unprivileged mode.")
1447 }
14481396
14491397 var wg sync.WaitGroup
14501398
15511499 }
15521500 }
15531501
1554 if !unprivileged() && supported("aufs") {
1555 c, err := NewContainer(ContainerCloneAufsName())
1556 if err != nil {
1557 t.Errorf(err.Error())
1558 }
1559 defer c.Release()
1560
1502 c, err := NewContainer(ContainerCloneName())
1503 if err != nil {
1504 t.Errorf(err.Error())
1505 }
1506 defer c.Release()
1507
1508 if err := c.Destroy(); err != nil {
1509 t.Errorf(err.Error())
1510 }
1511
1512 c, err = NewContainer(ContainerRestoreName())
1513 if err != nil {
1514 t.Errorf(err.Error())
1515 }
1516 defer c.Release()
1517
1518 if c.Defined() {
15611519 if err := c.Destroy(); err != nil {
15621520 t.Errorf(err.Error())
15631521 }
15641522 }
1565 c, err := NewContainer(ContainerCloneName())
1523
1524 c, err = NewContainer(ContainerName())
15661525 if err != nil {
15671526 t.Errorf(err.Error())
15681527 }
15711530 if err := c.Destroy(); err != nil {
15721531 t.Errorf(err.Error())
15731532 }
1574
1575 c, err = NewContainer(ContainerRestoreName())
1576 if err != nil {
1577 t.Errorf(err.Error())
1578 }
1579 defer c.Release()
1580
1581 if err := c.Destroy(); err != nil {
1582 t.Errorf(err.Error())
1583 }
1584
1585 c, err = NewContainer(ContainerName())
1586 if err != nil {
1587 t.Errorf(err.Error())
1588 }
1589 defer c.Release()
1590
1591 if err := c.Destroy(); err != nil {
1592 t.Errorf(err.Error())
1593 }
15941533 }
15951534
15961535 func TestConcurrentDestroy(t *testing.T) {
1536 t.Skip("Skipping concurrent tests for now")
1537
15971538 defer runtime.GOMAXPROCS(runtime.NumCPU())
1598
1599 if unprivileged() {
1600 t.Skip("skipping test in unprivileged mode.")
1601 }
16021539
16031540 var wg sync.WaitGroup
16041541
2727 // GID specifies the group id to run as.
2828 GID int
2929
30 // Groups specifies the list of additional group ids to run with.
31 Groups []int
32
3033 // If ClearEnv is true the environment is cleared before running the command.
3134 ClearEnv bool
3235
4447
4548 // StderrFd specifies the fd to write error output to.
4649 StderrFd uintptr
50
51 // RemountSysProc remounts /sys and /proc for the executed command.
52 // This is required to reflect the container (PID) namespace context
53 // if the command does not attach to the container's mount namespace.
54 RemountSysProc bool
55
56 // ElevatedPrivileges runs the command with elevated privileges.
57 // The capabilities, cgroup and security module restrictions of the container are not applied.
58 // WARNING: This may leak privileges into the container.
59 ElevatedPrivileges bool
4760 }
4861
4962 // DefaultAttachOptions is a convenient set of options to be used.
5063 var DefaultAttachOptions = AttachOptions{
51 Namespaces: -1,
52 Arch: -1,
53 Cwd: "/",
54 UID: -1,
55 GID: -1,
56 ClearEnv: false,
57 Env: nil,
58 EnvToKeep: nil,
59 StdinFd: os.Stdin.Fd(),
60 StdoutFd: os.Stdout.Fd(),
61 StderrFd: os.Stderr.Fd(),
64 Namespaces: -1,
65 Arch: -1,
66 Cwd: "/",
67 UID: -1,
68 GID: -1,
69 Groups: nil,
70 ClearEnv: false,
71 Env: nil,
72 EnvToKeep: nil,
73 StdinFd: os.Stdin.Fd(),
74 StdoutFd: os.Stdout.Fd(),
75 StderrFd: os.Stderr.Fd(),
76 RemountSysProc: false,
77 ElevatedPrivileges: false,
6278 }
6379
6480 // TemplateOptions type is used for defining various template options.
106122 ExtraArgs []string
107123 }
108124
125 // BackendStoreSpecs represents a LXC storage backend.
109126 type BackendStoreSpecs struct {
110127 FSType string
111128 FSSize uint64
6464 case Overlayfs:
6565 return "overlayfs"
6666 case Loopback:
67 return "loopback"
67 return "loop"
6868 case Best:
6969 return "best"
7070 }
155155 type ByteSize float64
156156
157157 const (
158 // B - byte
158159 B = iota
160
159161 // KB - kilobyte
160162 KB ByteSize = 1 << (10 * iota)
163
161164 // MB - megabyte
162165 MB
166
163167 // GB - gigabyte
164168 GB
169
165170 // TB - terabyte
166171 TB
172
167173 // PB - petabyte
168174 PB
175
169176 // EB - exabyte
170177 EB
178
171179 // ZB - zettabyte
172180 ZB
181
173182 // YB - yottabyte
174183 YB
175184 )
332341 type Personality int64
333342
334343 const (
335 X86 Personality = 0x0008
336 X86_64 = 0x0000
337 )
338
339 const (
340 MIGRATE_PRE_DUMP = 0
341 MIGRATE_DUMP = 1
342 MIGRATE_RESTORE = 2
344 // X86 - Intel 32bit
345 X86 Personality = 0x0008
346
347 // X86_64 - Intel 64bit
348 X86_64 = 0x0000
349 )
350
351 const (
352 // MIGRATE_PRE_DUMP - pre-dump live migration phase
353 MIGRATE_PRE_DUMP = 0
354
355 // MIGRATE_DUMP - main live migration phase
356 MIGRATE_DUMP = 1
357
358 // MIGRATE_RESTORE - post migration phase
359 MIGRATE_RESTORE = 2
360
361 // MIGRATE_FEATURE_CHECK - migration feature check
343362 MIGRATE_FEATURE_CHECK = 3
344363 )
345364
365 // CriuFeatures represents a set of CRIU features
346366 type CriuFeatures uint64
347367
348368 const (
369 // FEATURE_MEM_TRACK - memory tracking support
349370 FEATURE_MEM_TRACK CriuFeatures = 1 << iota
371
372 // FEATURE_LAZY_PAGES - lazy pages support
350373 FEATURE_LAZY_PAGES
351374 )
4646 import "C"
4747
4848 import (
49 "reflect"
5049 "unsafe"
5150 )
5251
8180 return nil
8281 }
8382
84 var A []*C.char
85
86 hdr := reflect.SliceHeader{
87 Data: uintptr(unsafe.Pointer(cArgs)),
88 Len: size,
89 Cap: size,
83 tmpslice := (*[(1 << 29) - 1]*C.char)(unsafe.Pointer(cArgs))[:size:size]
84 result := make([]string, size)
85 for i, s := range tmpslice {
86 result[i] = C.GoString(s)
9087 }
91 cArgsInterface := reflect.NewAt(reflect.TypeOf(A), unsafe.Pointer(&hdr)).Elem().Interface()
92
93 result := make([]string, size)
94 for i := 0; i < size; i++ {
95 result[i] = C.GoString(cArgsInterface.([]*C.char)[i])
96 }
97 C.freeCharArray(cArgs, C.size_t(size))
98
9988 return result
10089 }
10190