Skip to content

Commit 18a122b

Browse files
author
Ma Shimiao
authored
Merge pull request #325 from q384566678/device-dle
add device-remove and device-remove-all option
2 parents 4f29e1e + 6e253af commit 18a122b

File tree

4 files changed

+79
-29
lines changed

4 files changed

+79
-29
lines changed

cmd/oci-runtime-tool/generate.go

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ var generateFlags = []cli.Flag{
2626
cli.StringSliceFlag{Name: "cap-drop", Usage: "drop Linux capabilities"},
2727
cli.StringFlag{Name: "cgroups-path", Usage: "specify the path to the cgroups"},
2828
cli.StringFlag{Name: "cwd", Value: "/", Usage: "current working directory for the process"},
29-
cli.StringSliceFlag{Name: "device", Usage: "specifies a device which must be made available in the container"},
29+
cli.StringSliceFlag{Name: "device-add", Usage: "add a device which must be made available in the container"},
30+
cli.StringSliceFlag{Name: "device-remove", Usage: "remove a device which must be made available in the container"},
31+
cli.BoolFlag{Name: "device-remove-all", Usage: "remove all devices which must be made available in the container"},
3032
cli.BoolFlag{Name: "disable-oom-kill", Usage: "disable OOM Killer"},
3133
cli.StringSliceFlag{Name: "env", Usage: "add environment variable e.g. key=value"},
3234
cli.StringSliceFlag{Name: "env-file", Usage: "read in a file of environment variables"},
@@ -502,15 +504,31 @@ func setupSpec(g *generate.Generator, context *cli.Context) error {
502504
g.ClearProcessRlimits()
503505
}
504506

505-
if context.IsSet("device") {
506-
devices := context.StringSlice("device")
507+
if context.IsSet("device-add") {
508+
devices := context.StringSlice("device-add")
507509
for _, deviceArg := range devices {
508-
err := addDevice(deviceArg, g)
510+
dev, err := parseDevice(deviceArg, g)
509511
if err != nil {
510512
return err
511513
}
514+
g.AddDevice(dev)
512515
}
513516
}
517+
518+
if context.IsSet("device-remove") {
519+
devices := context.StringSlice("device-remove")
520+
for _, device := range devices {
521+
err := g.RemoveDevice(device)
522+
if err != nil {
523+
return err
524+
}
525+
}
526+
}
527+
528+
if context.Bool("device-remove-all") {
529+
g.ClearLinuxDevices()
530+
}
531+
514532
err := addSeccomp(context, g)
515533
return err
516534
}
@@ -642,33 +660,33 @@ var deviceType = map[string]bool{
642660
"p": true, // a FIFO
643661
}
644662

645-
// addDevice takes the raw string passed with the --device flag, parses it, and add it
646-
func addDevice(device string, g *generate.Generator) error {
663+
// parseDevice takes the raw string passed with the --device-add flag
664+
func parseDevice(device string, g *generate.Generator) (rspec.LinuxDevice, error) {
647665
dev := rspec.LinuxDevice{}
648666

649667
// The required part and optional part are separated by ":"
650668
argsParts := strings.Split(device, ":")
651669
if len(argsParts) < 4 {
652-
return fmt.Errorf("Incomplete device arguments: %s", device)
670+
return dev, fmt.Errorf("Incomplete device arguments: %s", device)
653671
}
654672
requiredPart := argsParts[0:4]
655673
optionalPart := argsParts[4:]
656674

657675
// The required part must contain type, major, minor, and path
658676
dev.Type = requiredPart[0]
659677
if !deviceType[dev.Type] {
660-
return fmt.Errorf("Invalid device type: %s", dev.Type)
678+
return dev, fmt.Errorf("Invalid device type: %s", dev.Type)
661679
}
662680

663681
i, err := strconv.ParseInt(requiredPart[1], 10, 64)
664682
if err != nil {
665-
return err
683+
return dev, err
666684
}
667685
dev.Major = i
668686

669687
i, err = strconv.ParseInt(requiredPart[2], 10, 64)
670688
if err != nil {
671-
return err
689+
return dev, err
672690
}
673691
dev.Minor = i
674692
dev.Path = requiredPart[3]
@@ -678,7 +696,7 @@ func addDevice(device string, g *generate.Generator) error {
678696
parts := strings.SplitN(s, "=", 2)
679697

680698
if len(parts) != 2 {
681-
return fmt.Errorf("Incomplete device arguments: %s", s)
699+
return dev, fmt.Errorf("Incomplete device arguments: %s", s)
682700
}
683701

684702
name, value := parts[0], parts[1]
@@ -687,33 +705,31 @@ func addDevice(device string, g *generate.Generator) error {
687705
case "fileMode":
688706
i, err := strconv.ParseInt(value, 10, 32)
689707
if err != nil {
690-
return err
708+
return dev, err
691709
}
692710
mode := os.FileMode(i)
693711
dev.FileMode = &mode
694712
case "uid":
695713
i, err := strconv.ParseInt(value, 10, 32)
696714
if err != nil {
697-
return err
715+
return dev, err
698716
}
699717
uid := uint32(i)
700718
dev.UID = &uid
701719

702720
case "gid":
703721
i, err := strconv.ParseInt(value, 10, 32)
704722
if err != nil {
705-
return err
723+
return dev, err
706724
}
707725
gid := uint32(i)
708726
dev.GID = &gid
709727
default:
710-
return fmt.Errorf("'%s' is not supported by device section", name)
728+
return dev, fmt.Errorf("'%s' is not supported by device section", name)
711729
}
712730
}
713731

714-
g.AddDevice(dev.Path, dev.Type, dev.Major, dev.Minor, dev.FileMode, dev.UID, dev.GID)
715-
716-
return nil
732+
return dev, nil
717733
}
718734

719735
func addSeccomp(context *cli.Context, g *generate.Generator) error {

completions/bash/oci-runtime-tool

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,8 @@ _oci-runtime-tool_generate() {
309309
--cap-drop
310310
--cgroups-path
311311
--cwd
312-
--device
312+
--device-add
313+
--device-remove
313314
--env
314315
--env-file
315316
--gid
@@ -367,6 +368,7 @@ _oci-runtime-tool_generate() {
367368
"
368369

369370
local boolean_options="
371+
--device-remove-all
370372
--disable-oom-kill
371373
--help -h
372374
--linux-namespace-remove-all

generate/generate.go

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,21 +1015,45 @@ func (g *Generator) RemoveLinuxNamespace(ns string) error {
10151015
}
10161016

10171017
// AddDevice - add a device into g.spec.Linux.Devices
1018-
func (g *Generator) AddDevice(path, devType string, major, minor int64, fileMode *os.FileMode, uid, gid *uint32) {
1018+
func (g *Generator) AddDevice(device rspec.LinuxDevice) {
10191019
g.initSpecLinux()
10201020

1021-
device := rspec.LinuxDevice{
1022-
Path: path,
1023-
Type: devType,
1024-
Major: major,
1025-
Minor: minor,
1026-
FileMode: fileMode,
1027-
UID: uid,
1028-
GID: gid,
1021+
for i, dev := range g.spec.Linux.Devices {
1022+
if dev.Path == device.Path {
1023+
g.spec.Linux.Devices[i] = device
1024+
return
1025+
}
1026+
if dev.Type == device.Type && dev.Major == device.Major && dev.Minor == device.Minor {
1027+
fmt.Fprintln(os.Stderr, "WARNING: The same type, major and minor should not be used for multiple devices.")
1028+
}
10291029
}
1030+
10301031
g.spec.Linux.Devices = append(g.spec.Linux.Devices, device)
10311032
}
10321033

1034+
//RemoveDevice remove a device from g.spec.Linux.Devices
1035+
func (g *Generator) RemoveDevice(path string) error {
1036+
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Devices == nil {
1037+
return nil
1038+
}
1039+
1040+
for i, device := range g.spec.Linux.Devices {
1041+
if device.Path == path {
1042+
g.spec.Linux.Devices = append(g.spec.Linux.Devices[:i], g.spec.Linux.Devices[i+1:]...)
1043+
return nil
1044+
}
1045+
}
1046+
return nil
1047+
}
1048+
1049+
func (g *Generator) ClearLinuxDevices() {
1050+
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Devices == nil {
1051+
return
1052+
}
1053+
1054+
g.spec.Linux.Devices = []rspec.LinuxDevice{}
1055+
}
1056+
10331057
// strPtr returns the pointer pointing to the string s.
10341058
func strPtr(s string) *string { return &s }
10351059

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ read the configuration from `config.json`.
5151
**--cwd**=PATH
5252
Current working directory for the process. The deafult is */*.
5353

54-
**--device**=*TYPE:MAJOR:MINOR:PATH[:OPTIONS...]*
54+
**--device-add**=*TYPE:MAJOR:MINOR:PATH[:OPTIONS...]*
5555
Add a device file in container. e.g. --device=c:10:229:/dev/fuse:fileMode=438:uid=0:gid=0
5656
The *TYPE*, *MAJOR*, *MINOR*, *PATH* are required.
5757
*TYPE* is the device type. The acceptable values are b (block), c (character), u (unbuffered), p (FIFO).
@@ -60,6 +60,14 @@ read the configuration from `config.json`.
6060
The *fileMode*, *uid*, *gid* are optional.
6161
*fileMode* is the file mode of the device file.
6262
*uid*/*gid* is the user/group id of the device file.
63+
This option can be specified multiple times.
64+
65+
**--device-remove**=*PATH*
66+
Remove a device file in container.
67+
This option can be specified multiple times.
68+
69+
**--device-remove-all**=true|false
70+
Remove all devices for linux inside the container. The default is *false*.
6371

6472
**--disable-oom-kill**=true|false
6573
Whether to disable OOM Killer for the container or not.

0 commit comments

Comments
 (0)