Skip to content

Commit 1dfcb6a

Browse files
authored
Merge pull request #16 from thediveo/develop
implements #15
2 parents 5483e3b + 7d4cd60 commit 1dfcb6a

File tree

8 files changed

+107
-3
lines changed

8 files changed

+107
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
![build and test](https://github.com/thediveo/morbyd/actions/workflows/buildandtest.yaml/badge.svg?branch=master)
88
![goroutines](https://img.shields.io/badge/go%20routines-not%20leaking-success)
99
[![Go Report Card](https://goreportcard.com/badge/github.com/thediveo/morbyd)](https://goreportcard.com/report/github.com/thediveo/morbyd)
10-
![Coverage](https://img.shields.io/badge/Coverage-98.7%25-brightgreen)
10+
![Coverage](https://img.shields.io/badge/Coverage-98.6%25-brightgreen)
1111

1212
`morbyd` is a thin layer on top of the standard Docker Go client to easily build
1313
and run throw-away test Docker images and containers. And to easily run commands

container.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,16 @@ func (c *Container) PID(ctx context.Context) (int, error) {
135135
}
136136
}
137137

138+
// Pause the container.
139+
func (c *Container) Pause(ctx context.Context) error {
140+
return c.Session.moby.ContainerPause(ctx, c.ID)
141+
}
142+
143+
// Unpause the container.
144+
func (c *Container) Unpause(ctx context.Context) error {
145+
return c.Session.moby.ContainerUnpause(ctx, c.ID)
146+
}
147+
138148
// Stop the container by sending it a termination signal. Default is SIGTERM,
139149
// unless changed using [run.WithStopSignal].
140150
func (c *Container) Stop(ctx context.Context) {

container_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,23 @@ var _ = Describe("containers", Ordered, func() {
5757
Expect(time.Since(start)).To(BeNumerically(">=", 4*time.Second))
5858
})
5959

60+
It("pauses and unpauses a container", func(ctx context.Context) {
61+
cntr := Successful(sess.Run(ctx, "busybox",
62+
run.WithCommand("/bin/sh", "-c", "while true; do sleep 1; done"),
63+
run.WithAutoRemove(),
64+
run.WithCombinedOutput(timestamper.New(GinkgoWriter)),
65+
))
66+
Expect(cntr.PID(ctx)).Error().NotTo(HaveOccurred())
67+
68+
Expect(cntr.Pause(ctx)).To(Succeed())
69+
Expect(cntr.Refresh(ctx)).To(Succeed())
70+
Expect(cntr.Details.State.Paused).To(BeTrue())
71+
72+
Expect(cntr.Unpause(ctx)).To(Succeed())
73+
Expect(cntr.Refresh(ctx)).To(Succeed())
74+
Expect(cntr.Details.State.Paused).To(BeFalse())
75+
})
76+
6077
It("stops a container cooperatively", func(ctx context.Context) {
6178
var buff safe.Buffer
6279

morbyd.code-workspace

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,27 @@
1111
"-v",
1212
"-race",
1313
"--ginkgo.no-color"
14+
],
15+
"statsBar.memoUsage.format": "$(chip) ${used}/${total} ${unit}, ${percent}%",
16+
"statsBar.location": "Right",
17+
},
18+
"launch": {
19+
"version": "0.2.0",
20+
"configurations": [
21+
{
22+
"name": "Debug/Test Package",
23+
"type": "go",
24+
"request": "launch",
25+
"mode": "auto",
26+
"program": "${fileDirname}"
27+
}
28+
],
29+
"compounds": []
30+
},
31+
"extensions": {
32+
"recommendations": [
33+
"ms-vscode.live-server",
34+
"njzy.stats-bar"
1435
]
1536
}
1637
}

registry_test.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package morbyd
1717
import (
1818
"context"
1919
"fmt"
20+
"net/http"
2021
"time"
2122

2223
"github.com/thediveo/morbyd/pull"
@@ -51,10 +52,23 @@ var _ = Describe("given a (local) registry", Ordered, Serial, func() {
5152
sess.Close(ctx)
5253
})
5354
By("starting a local container registry")
54-
_ = Successful(sess.Run(ctx, "registry:2",
55+
Expect(sess.Run(ctx, "registry:2",
5556
run.WithName("local-registry"),
5657
run.WithPublishedPort(fmt.Sprintf("127.0.0.1:%d:5000", registryPort)),
57-
run.WithAutoRemove()))
58+
run.WithAutoRemove())).Error().NotTo(HaveOccurred())
59+
By("waiting for the registry to become operational")
60+
Eventually(func() error {
61+
resp, err := http.Get(fmt.Sprintf("http://127.0.0.1:%d/v2/", registryPort))
62+
if err != nil {
63+
return err
64+
}
65+
defer resp.Body.Close()
66+
if resp.StatusCode != http.StatusOK {
67+
return fmt.Errorf("HTTP status code %d", resp.StatusCode)
68+
}
69+
return nil
70+
}).Within(5 * time.Second).ProbeEvery(250 * time.Millisecond).
71+
Should(Succeed())
5872
})
5973

6074
BeforeEach(func(ctx context.Context) {

run/doc.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
/*
22
Package run provides configuration options for running containers.
3+
4+
In many cases, Docker's documentation on [docker container run] and the
5+
[containers/create API endpoint] can give useful hints as to what various API
6+
configuration settings might do.
7+
8+
[docker container run]: https://docs.docker.com/reference/cli/docker/container/run/
9+
[containers/create API endpoint]: https://docs.docker.com/reference/api/engine/version/v1.39/#tag/Container/operation/ContainerCreate
310
*/
411
package run

run/options.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,37 @@ func WithAllPortsPublished() Opt {
632632
}
633633
}
634634

635+
// WithCPUSet configures the [set of CPUs] on which processes of the container
636+
// are allowed to execute. The list of CPUs is a comma-separated list of CPU
637+
// numbers and ranges of numbers, where the numbers are decimal numbers. For
638+
// instance, “1,3,5”, "0-42,666", et cetera.
639+
//
640+
// To avoid stuttering this option is simply named “WithCPUSet” instead of
641+
// “WithCpusetCPUs”, or similar awkward letter salads.
642+
//
643+
// [set of CPUs]: https://man7.org/linux/man-pages/man7/cpuset.7.html
644+
func WithCPUSet(cpulist string) Opt {
645+
return func(o *Options) error {
646+
o.Host.CpusetCpus = cpulist
647+
return nil
648+
}
649+
}
650+
651+
// WithMems configures the [set of memory nodes] on which processes of the
652+
// container are allowed to allocate memory. The list of memory nodes is a
653+
// comma-separated list of memory node numbers and ranges of numbers, where the
654+
// numbers are decimal numbers. For instance, “1,3,5”, "0-42,666", et cetera.
655+
//
656+
// [set of memory nodes]: https://man7.org/linux/man-pages/man7/cpuset.7.html
657+
func WithMems(memlist string) Opt {
658+
return func(o *Options) error {
659+
o.Host.CpusetMems = memlist
660+
return nil
661+
}
662+
}
663+
664+
// WithCustomInit instructs Docker to run an init inside the container that
665+
// forwards signals and reaps processes.
635666
func WithCustomInit() Opt {
636667
return func(o *Options) error {
637668
customInit := true

run/options_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ var _ = Describe("run (container) options", func() {
112112
WithPublishedPort("[fe80::dead:beef]:2345:1234"),
113113
WithPublishedPort("127.0.0.1:1234"),
114114
WithPublishedPort("127.0.0.2:12345/udp"),
115+
WithCPUSet("1,3,5,99"),
116+
WithMems("6,66"),
115117
WithCustomInit(),
116118
)
117119

@@ -167,6 +169,8 @@ var _ = Describe("run (container) options", func() {
167169
nat.Port("12345/udp"),
168170
ConsistOf(nat.PortBinding{HostIP: "127.0.0.2", HostPort: "0"})))
169171

172+
Expect(o.Host.CpusetCpus).To(Equal("1,3,5,99"))
173+
Expect(o.Host.CpusetMems).To(Equal("6,66"))
170174
Expect(o.Host.Init).To(gstruct.PointTo(BeTrue()))
171175

172176
o = opts(WithLabel("foo=bar"))

0 commit comments

Comments
 (0)