Skip to content

Commit 74d6245

Browse files
author
Ma Shimiao
committed
man: add manpage for option --mounts-add
Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
1 parent ccef443 commit 74d6245

4 files changed

Lines changed: 41 additions & 153 deletions

File tree

cmd/oci-runtime-tool/generate.go

Lines changed: 4 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ var generateFlags = []cli.Flag{
8080
cli.StringFlag{Name: "linux-selinux-label", Usage: "process selinux label"},
8181
cli.StringSliceFlag{Name: "linux-sysctl", Usage: "add sysctl settings e.g net.ipv4.forward=1"},
8282
cli.StringSliceFlag{Name: "linux-uidmappings", Usage: "add UIDMappings e.g HostID:ContainerID:Size"},
83-
cli.StringSliceFlag{Name: "mount-bind", Usage: "bind mount directories src:dest[:options...]"},
8483
cli.StringFlag{Name: "mount-cgroups", Value: "no", Usage: "mount cgroups (rw,ro,no)"},
8584
cli.StringSliceFlag{Name: "mounts-add", Usage: "configures additional mounts inside container"},
85+
cli.BoolFlag{Name: "mounts-remove-all", Usage: "remove all mounts inside container"},
8686
cli.StringFlag{Name: "output", Usage: "output file (defaults to stdout)"},
8787
cli.BoolFlag{Name: "privileged", Usage: "enable privileged container settings"},
8888
cli.StringSliceFlag{Name: "process-cap-add-ambient", Usage: "add Linux ambient capabilities"},
@@ -109,7 +109,6 @@ var generateFlags = []cli.Flag{
109109
cli.StringFlag{Name: "rootfs-path", Value: "rootfs", Usage: "path to the root filesystem"},
110110
cli.BoolFlag{Name: "rootfs-readonly", Usage: "make the container's rootfs readonly"},
111111
cli.StringFlag{Name: "template", Usage: "base template to use for creating the configuration"},
112-
cli.StringSliceFlag{Name: "tmpfs", Usage: "mount tmpfs e.g. ContainerDIR[:OPTIONS...]"},
113112
}
114113

115114
var generateCommand = cli.Command{
@@ -416,41 +415,22 @@ func setupSpec(g *generate.Generator, context *cli.Context) error {
416415
g.AddOrReplaceLinuxNamespace("user", "")
417416
}
418417

419-
if context.IsSet("tmpfs") {
420-
tmpfsSlice := context.StringSlice("tmpfs")
421-
for _, s := range tmpfsSlice {
422-
dest, options, err := parseTmpfsMount(s)
423-
if err != nil {
424-
return err
425-
}
426-
g.AddTmpfsMount(dest, options)
427-
}
428-
}
429-
430418
mountCgroupOption := context.String("mount-cgroups")
431419
if err := g.AddCgroupsMount(mountCgroupOption); err != nil {
432420
return err
433421
}
434422

435-
if context.IsSet("mount-bind") {
436-
binds := context.StringSlice("mount-bind")
437-
for _, bind := range binds {
438-
source, dest, options, err := parseBindMount(bind)
439-
if err != nil {
440-
return err
441-
}
442-
g.AddBindMount(source, dest, options)
443-
}
423+
if context.IsSet("mounts-remove-all") {
424+
g.ClearMounts()
444425
}
445426

446427
if context.IsSet("mounts-add") {
447428
mounts := context.StringSlice("mounts-add")
448429
for _, mount := range mounts {
449-
source, dest, mType, options, err := parseMount(mount)
430+
err := g.AddMounts(mount)
450431
if err != nil {
451432
return err
452433
}
453-
g.AddMounts(source, dest, mType, options)
454434
}
455435
}
456436

@@ -869,62 +849,6 @@ func parseNetworkPriority(np string) (string, int32, error) {
869849
return parts[0], int32(priority), nil
870850
}
871851

872-
func parseTmpfsMount(s string) (string, []string, error) {
873-
var dest string
874-
var options []string
875-
var err error
876-
877-
parts := strings.Split(s, ":")
878-
if len(parts) == 2 && parts[0] != "" {
879-
dest = parts[0]
880-
options = strings.Split(parts[1], ",")
881-
} else if len(parts) == 1 {
882-
dest = parts[0]
883-
options = []string{"rw", "noexec", "nosuid", "nodev", "size=65536k"}
884-
} else {
885-
err = fmt.Errorf("invalid -- tmpfs value: %s", s)
886-
}
887-
888-
return dest, options, err
889-
}
890-
891-
func parseBindMount(s string) (string, string, []string, error) {
892-
var source, dest string
893-
options := []string{}
894-
895-
bparts := strings.SplitN(s, ":", 3)
896-
switch len(bparts) {
897-
case 2:
898-
source, dest = bparts[0], bparts[1]
899-
case 3:
900-
source, dest, options = bparts[0], bparts[1], strings.Split(bparts[2], ":")
901-
default:
902-
return source, dest, options, fmt.Errorf("--mount-bind should have format src:dest[:options...]")
903-
}
904-
905-
if source == "" || dest == "" {
906-
return source, dest, options, fmt.Errorf("--mount-bind should have format src:dest[:options...]")
907-
}
908-
return source, dest, options, nil
909-
}
910-
911-
func parseMount(s string) (string, string, string, []string, error) {
912-
var source, dest, mType string
913-
options := []string{}
914-
915-
mparts := strings.SplitN(s, ":", 4)
916-
switch len(mparts) {
917-
case 3:
918-
source, dest, mType = mparts[0], mparts[1], mparts[2]
919-
case 4:
920-
source, dest, mType, options = mparts[0], mparts[1], mparts[2], strings.Split(mparts[3], ":")
921-
default:
922-
return source, dest, mType, options, fmt.Errorf("--mounts-add should have format src:dest:type:[:options...]")
923-
}
924-
925-
return source, dest, mType, options, nil
926-
}
927-
928852
func parseRlimit(rlimit string) (string, uint64, uint64, error) {
929853
parts := strings.Split(rlimit, ":")
930854
if len(parts) != 3 || parts[0] == "" {

completions/bash/oci-runtime-tool

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,8 @@ _oci-runtime-tool_generate() {
360360
--linux-selinux-label
361361
--linux-sysctl
362362
--linux-uidmappings
363-
--mount-bind
364363
--mount-cgroups
364+
--mounts-add
365365
--output
366366
--process-cap-add-ambient
367367
--process-cap-add-bounding
@@ -382,7 +382,6 @@ _oci-runtime-tool_generate() {
382382
--process-uid
383383
--rootfs-path
384384
--template
385-
--tmpfs
386385
"
387386

388387
local boolean_options="
@@ -392,6 +391,7 @@ _oci-runtime-tool_generate() {
392391
--linux-namespace-remove-all
393392
--linux-seccomp-only
394393
--linux-seccomp-remove-all
394+
--mounts-remove-all
395395
--privileged
396396
--process-cap-drop-all
397397
--process-no-new-privileges
@@ -462,7 +462,7 @@ _oci-runtime-tool_generate() {
462462
return
463463
;;
464464

465-
--rootfs-path|--tmpfs|--mount-bind|--process-cwd)
465+
--rootfs-path|--process-cwd)
466466
case "$cur" in
467467
*:*)
468468
# TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine)

generate/generate.go

Lines changed: 15 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -874,30 +874,26 @@ func (g *Generator) AddPostStartHookTimeout(path string, timeout int) {
874874
g.spec.Hooks.Poststart = append(g.spec.Hooks.Poststart, hook)
875875
}
876876

877-
// AddTmpfsMount adds a tmpfs mount into g.spec.Mounts.
878-
func (g *Generator) AddTmpfsMount(dest string, options []string) {
879-
mnt := rspec.Mount{
880-
Destination: dest,
881-
Type: "tmpfs",
882-
Source: "tmpfs",
883-
Options: options,
884-
}
885-
877+
// AddMounts adds a mount into g.spec.Mounts.
878+
func (g *Generator) AddMounts(mountObject string) error {
886879
g.initSpec()
880+
881+
mnt := rspec.Mount{}
882+
err := json.Unmarshal([]byte(mountObject), &mnt)
883+
if err != nil {
884+
return err
885+
}
887886
g.spec.Mounts = append(g.spec.Mounts, mnt)
887+
888+
return nil
888889
}
889890

890-
// AddMounts adds a mount into g.spec.Mounts.
891-
func (g *Generator) AddMounts(source, dest, mType string, options []string) {
892-
mnt := rspec.Mount{
893-
Destination: dest,
894-
Type: mType,
895-
Source: source,
896-
Options: options,
891+
// ClearMounts clear g.spec.Mounts
892+
func (g *Generator) ClearMounts() {
893+
if g.spec == nil {
894+
return
897895
}
898-
899-
g.initSpec()
900-
g.spec.Mounts = append(g.spec.Mounts, mnt)
896+
g.spec.Mounts = []rspec.Mount{}
901897
}
902898

903899
// AddCgroupsMount adds a cgroup mount into g.spec.Mounts.
@@ -923,35 +919,6 @@ func (g *Generator) AddCgroupsMount(mountCgroupOption string) error {
923919
return nil
924920
}
925921

926-
// AddBindMount adds a bind mount into g.spec.Mounts.
927-
func (g *Generator) AddBindMount(source, dest string, options []string) {
928-
if len(options) == 0 {
929-
options = []string{"rw"}
930-
}
931-
932-
// We have to make sure that there is a bind option set, otherwise it won't
933-
// be an actual bindmount.
934-
foundBindOption := false
935-
for _, opt := range options {
936-
if opt == "bind" || opt == "rbind" {
937-
foundBindOption = true
938-
break
939-
}
940-
}
941-
if !foundBindOption {
942-
options = append(options, "bind")
943-
}
944-
945-
mnt := rspec.Mount{
946-
Destination: dest,
947-
Type: "bind",
948-
Source: source,
949-
Options: options,
950-
}
951-
g.initSpec()
952-
g.spec.Mounts = append(g.spec.Mounts, mnt)
953-
}
954-
955922
// SetupPrivileged sets up the privilege-related fields inside g.spec.
956923
func (g *Generator) SetupPrivileged(privileged bool) {
957924
if privileged { // Add all capabilities in privileged mode.

man/oci-runtime-tool-generate.1.md

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -283,19 +283,24 @@ read the configuration from `config.json`.
283283

284284
Add UIDMappings e.g HostUID:ContainerID:Size. Implies **--user=**.
285285

286-
**--mount-bind**=*[[HOST-DIR:CONTAINER-DIR][:OPTIONS...]]*
287-
Bind mount directories src:dest:(rw,ro) If you specify, ` --mount-bind
288-
/HOST-DIR:/CONTAINER-DIR`, runc bind mounts `/HOST-DIR` in the host
289-
to `/CONTAINER-DIR` in the OCI container. The `OPTIONS` are a colon
290-
delimited list and can be any mount option support by the runtime such
291-
as [rw|ro|rbind|bind|...]. The `HOST_DIR` and `CONTAINER-DIR` must be
292-
absolute paths such as `/src/docs`. You can set the `ro` or `rw`
293-
options to a bind-mount to mount it read-only or read-write mode,
294-
respectively. By default, bind-mounts are mounted read-write.
295-
296286
**--mount-cgroups**=[rw|ro|no]
297287
Mount cgroups. The default is *no*.
298288

289+
**--mounts-add**=[]
290+
Configures additional mounts inside container.
291+
This option can be specified multiple times.
292+
For example,
293+
A. Add tmpfs into container.
294+
--mounts-add '{"destination": "/tmp","type": "tmpfs","source": "tmpfs","options": ["nosuid","strictatime","mode=755","size=65536k"]}'
295+
B. Bind host directory into containeri.
296+
--mounts-add '{"destination": "/data","type": "bind","source": "/volumes/testing","options": ["rbind","rw"]}'
297+
C. mount for windows platform
298+
--mount-add '{"destination": "C:\\folder-inside-container","source": "C:\\folder-on-host","options": ["ro"]}'
299+
300+
**--mounts-remove-all**=true|false
301+
Remove all mounts inside the container. The default is *false*.
302+
When specified with --mount-add, this option will be parsed first.
303+
299304
**--output**=PATH
300305
Instead of writing the configuration JSON to stdout, write it to a
301306
file at *PATH* (overwriting the existing content if a file already
@@ -392,14 +397,6 @@ read the configuration from `config.json`.
392397
Additional options will only adjust the relevant portions of your template.
393398
Templates are not validated for correctness, so the user should ensure that they are correct.
394399

395-
**--tmpfs**=[] Create a tmpfs mount
396-
Mount a temporary filesystem (`tmpfs`) mount into a container, for example:
397-
398-
$ oci-runtime-tool generate -d --tmpfs /tmp:rw,size=787448k,mode=1777 my_image
399-
400-
This command mounts a `tmpfs` at `/tmp` within the container. The supported mount options are the same as the Linux default `mount` flags. If you do not specify any options, the systems uses the following options:
401-
`rw,noexec,nosuid,nodev,size=65536k`.
402-
403400
# EXAMPLES
404401

405402
## Generating container in read-only mode
@@ -413,14 +410,14 @@ This protects the containers image from modification. Read only containers may
413410
still need to write temporary data. The best way to handle this is to mount
414411
tmpfs directories on /generate and /tmp.
415412

416-
$ oci-runtime-tool generate --rootfs-readonly --tmpfs /generate --tmpfs /tmp --tmpfs /run --rootfs-path /var/lib/containers/fedora --args bash
413+
$ oci-runtime-tool generate --rootfs-readonly --mounts-add '{"destination": "/tmp","type": "tmpfs","source": "tmpfs","options": ["nosuid","strictatime","mode=755","size=65536k"]}' --mounts-add '{"destination": "/run","type": "tmpfs","source": "tmpfs","options": ["nosuid","strictatime","mode=755","size=65536k"]}' --rootfs-path /var/lib/containers/fedora --args bash
417414

418415
## Exposing log messages from the container to the host's log
419416

420417
If you want messages that are logged in your container to show up in the host's
421418
syslog/journal then you should bind mount the /dev/log directory as follows.
422419

423-
$ oci-runtime-tool generate --mount-bind /dev/log:/dev/log --rootfs-path /var/lib/containers/fedora --args bash
420+
$ oci-runtime-tool generate --mounts-add '{"destination": "/dev/log","type": "bind","source": "/dev/log","options": ["rbind","rw"]}' --rootfs-path /var/lib/containers/fedora --args bash
424421

425422
From inside the container you can test this by sending a message to the log.
426423

@@ -440,13 +437,13 @@ To mount a host directory as a container volume, specify the absolute path to
440437
the directory and the absolute path for the container directory separated by a
441438
colon:
442439

443-
$ oci-runtime-tool generate --mount-bind /var/db:/data1 --rootfs-path /var/lib/containers/fedora --args bash
440+
$ oci-runtime-tool generate --mounts-add '{"destination": "/var/db","type": "bind","source": "/data1","options": ["rbind","rw"]}' --rootfs-path /var/lib/containers/fedora --args bash
444441

445442
## Using SELinux
446443

447444
You can use SELinux to add security to the container. You must specify the process label to run the init process inside of the container using `--linux-selinux-label`.
448445

449-
$ oci-runtime-tool generate --mount-bind /var/db:/data1 --linux-selinux-label system_u:system_r:svirt_lxc_net_t:s0:c1,c2 --linux-mount-label system_u:object_r:svirt_sandbo x_file_t:s0:c1,c2 --rootfs-path /var/lib/containers/fedora --args bash
446+
$ oci-runtime-tool generate --mounts-add '{"destination": "/var/db","type": "bind","source": "/data1","options": ["rbind","rw"]}' --linux-selinux-label system_u:system_r:svirt_lxc_net_t:s0:c1,c2 --linux-mount-label system_u:object_r:svirt_sandbo x_file_t:s0:c1,c2 --rootfs-path /var/lib/containers/fedora --args bash
450447

451448
Not in the above example we used a type of svirt_lxc_net_t and an MCS Label of s0:c1,c2. If you want to guarantee separation between containers, you need to make sure that each container gets launched with a different MCS Label pair.
452449

0 commit comments

Comments
 (0)