summaryrefslogtreecommitdiff
path: root/pkg/util
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/util')
-rw-r--r--pkg/util/camelcase/LICENSE.md20
-rw-r--r--pkg/util/camelcase/README.md58
-rw-r--r--pkg/util/camelcase/camelcase.go91
-rw-r--r--pkg/util/utils.go60
-rw-r--r--pkg/util/utils_linux_test.go29
-rw-r--r--pkg/util/utils_supported.go4
-rw-r--r--pkg/util/utils_test.go31
7 files changed, 268 insertions, 25 deletions
diff --git a/pkg/util/camelcase/LICENSE.md b/pkg/util/camelcase/LICENSE.md
new file mode 100644
index 000000000..aa4a536ca
--- /dev/null
+++ b/pkg/util/camelcase/LICENSE.md
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Fatih Arslan
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/pkg/util/camelcase/README.md b/pkg/util/camelcase/README.md
new file mode 100644
index 000000000..105a6ae33
--- /dev/null
+++ b/pkg/util/camelcase/README.md
@@ -0,0 +1,58 @@
+# CamelCase [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/camelcase) [![Build Status](http://img.shields.io/travis/fatih/camelcase.svg?style=flat-square)](https://travis-ci.org/fatih/camelcase)
+
+CamelCase is a Golang (Go) package to split the words of a camelcase type
+string into a slice of words. It can be used to convert a camelcase word (lower
+or upper case) into any type of word.
+
+## Splitting rules:
+
+1. If string is not valid UTF-8, return it without splitting as
+ single item array.
+2. Assign all unicode characters into one of 4 sets: lower case
+ letters, upper case letters, numbers, and all other characters.
+3. Iterate through characters of string, introducing splits
+ between adjacent characters that belong to different sets.
+4. Iterate through array of split strings, and if a given string
+ is upper case:
+ * if subsequent string is lower case:
+ * move last character of upper case string to beginning of
+ lower case string
+
+## Install
+
+```bash
+go get github.com/fatih/camelcase
+```
+
+## Usage and examples
+
+```go
+splitted := camelcase.Split("GolangPackage")
+
+fmt.Println(splitted[0], splitted[1]) // prints: "Golang", "Package"
+```
+
+Both lower camel case and upper camel case are supported. For more info please
+check: [http://en.wikipedia.org/wiki/CamelCase](http://en.wikipedia.org/wiki/CamelCase)
+
+Below are some example cases:
+
+```
+"" => []
+"lowercase" => ["lowercase"]
+"Class" => ["Class"]
+"MyClass" => ["My", "Class"]
+"MyC" => ["My", "C"]
+"HTML" => ["HTML"]
+"PDFLoader" => ["PDF", "Loader"]
+"AString" => ["A", "String"]
+"SimpleXMLParser" => ["Simple", "XML", "Parser"]
+"vimRPCPlugin" => ["vim", "RPC", "Plugin"]
+"GL11Version" => ["GL", "11", "Version"]
+"99Bottles" => ["99", "Bottles"]
+"May5" => ["May", "5"]
+"BFG9000" => ["BFG", "9000"]
+"BöseÜberraschung" => ["Böse", "Überraschung"]
+"Two spaces" => ["Two", " ", "spaces"]
+"BadUTF8\xe2\xe2\xa1" => ["BadUTF8\xe2\xe2\xa1"]
+```
diff --git a/pkg/util/camelcase/camelcase.go b/pkg/util/camelcase/camelcase.go
new file mode 100644
index 000000000..0a82d1005
--- /dev/null
+++ b/pkg/util/camelcase/camelcase.go
@@ -0,0 +1,91 @@
+// Package camelcase is a micro package to split the words of a camelcase type
+// string into a slice of words.
+package camelcase
+
+import (
+ "unicode"
+ "unicode/utf8"
+)
+
+// Split splits the camelcase word and returns a list of words. It also
+// supports digits. Both lower camel case and upper camel case are supported.
+// For more info please check: http://en.wikipedia.org/wiki/CamelCase
+//
+// Examples
+//
+// "" => [""]
+// "lowercase" => ["lowercase"]
+// "Class" => ["Class"]
+// "MyClass" => ["My", "Class"]
+// "MyC" => ["My", "C"]
+// "HTML" => ["HTML"]
+// "PDFLoader" => ["PDF", "Loader"]
+// "AString" => ["A", "String"]
+// "SimpleXMLParser" => ["Simple", "XML", "Parser"]
+// "vimRPCPlugin" => ["vim", "RPC", "Plugin"]
+// "GL11Version" => ["GL", "11", "Version"]
+// "99Bottles" => ["99", "Bottles"]
+// "May5" => ["May", "5"]
+// "BFG9000" => ["BFG", "9000"]
+// "BöseÜberraschung" => ["Böse", "Überraschung"]
+// "Two spaces" => ["Two", " ", "spaces"]
+// "BadUTF8\xe2\xe2\xa1" => ["BadUTF8\xe2\xe2\xa1"]
+//
+// Splitting rules
+//
+// 1) If string is not valid UTF-8, return it without splitting as
+// single item array.
+// 2) Assign all unicode characters into one of 4 sets: lower case
+// letters, upper case letters, numbers, and all other characters.
+// 3) Iterate through characters of string, introducing splits
+// between adjacent characters that belong to different sets.
+// 4) Iterate through array of split strings, and if a given string
+// is upper case:
+// if subsequent string is lower case:
+// move last character of upper case string to beginning of
+// lower case string
+func Split(src string) (entries []string) {
+ // don't split invalid utf8
+ if !utf8.ValidString(src) {
+ return []string{src}
+ }
+ entries = []string{}
+ var runes [][]rune
+ lastClass := 0
+ class := 0
+ // split into fields based on class of unicode character
+ for _, r := range src {
+ switch {
+ case unicode.IsLower(r):
+ class = 1
+ case unicode.IsUpper(r):
+ class = 2
+ case unicode.IsDigit(r):
+ class = 3
+ default:
+ class = 4
+ }
+ if class == lastClass {
+ runes[len(runes)-1] = append(runes[len(runes)-1], r)
+ } else {
+ runes = append(runes, []rune{r})
+ }
+ lastClass = class
+ }
+ // handle upper case -> lower case sequences, e.g.
+ // "PDFL", "oader" -> "PDF", "Loader"
+ for i := 0; i < len(runes)-1; i++ {
+ if unicode.IsUpper(runes[i][0]) && unicode.IsLower(runes[i+1][0]) {
+ runes[i+1] = append([]rune{runes[i][len(runes[i])-1]}, runes[i+1]...)
+ runes[i] = runes[i][:len(runes[i])-1]
+ }
+ }
+ // construct []string from results
+ for _, s := range runes {
+ if len(s) > 0 {
+ entries = append(entries, string(s))
+ }
+ }
+
+ return entries
+}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 6aa3c221e..0c055745d 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -18,9 +18,9 @@ import (
"github.com/containers/libpod/pkg/errorhandling"
"github.com/containers/libpod/pkg/namespaces"
"github.com/containers/libpod/pkg/rootless"
+ "github.com/containers/libpod/pkg/signal"
"github.com/containers/storage"
"github.com/containers/storage/pkg/idtools"
- "github.com/docker/docker/pkg/signal"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -309,15 +309,15 @@ func ParseSignal(rawSignal string) (syscall.Signal, error) {
// Strip off leading dash, to allow -1 or -HUP
basename := strings.TrimPrefix(rawSignal, "-")
- signal, err := signal.ParseSignal(basename)
+ sig, err := signal.ParseSignal(basename)
if err != nil {
return -1, err
}
// 64 is SIGRTMAX; wish we could get this from a standard Go library
- if signal < 1 || signal > 64 {
+ if sig < 1 || sig > 64 {
return -1, errors.Errorf("valid signals are 1 through 64")
}
- return signal, nil
+ return sig, nil
}
// ParseIDMapping takes idmappings and subuid and subgid maps and returns a storage mapping
@@ -600,3 +600,55 @@ func HomeDir() (string, error) {
}
return home, nil
}
+
+func Tmpdir() string {
+ tmpdir := os.Getenv("TMPDIR")
+ if tmpdir == "" {
+ tmpdir = "/var/tmp"
+ }
+
+ return tmpdir
+}
+
+// ValidateSysctls validates a list of sysctl and returns it.
+func ValidateSysctls(strSlice []string) (map[string]string, error) {
+ sysctl := make(map[string]string)
+ validSysctlMap := map[string]bool{
+ "kernel.msgmax": true,
+ "kernel.msgmnb": true,
+ "kernel.msgmni": true,
+ "kernel.sem": true,
+ "kernel.shmall": true,
+ "kernel.shmmax": true,
+ "kernel.shmmni": true,
+ "kernel.shm_rmid_forced": true,
+ }
+ validSysctlPrefixes := []string{
+ "net.",
+ "fs.mqueue.",
+ }
+
+ for _, val := range strSlice {
+ foundMatch := false
+ arr := strings.Split(val, "=")
+ if len(arr) < 2 {
+ return nil, errors.Errorf("%s is invalid, sysctl values must be in the form of KEY=VALUE", val)
+ }
+ if validSysctlMap[arr[0]] {
+ sysctl[arr[0]] = arr[1]
+ continue
+ }
+
+ for _, prefix := range validSysctlPrefixes {
+ if strings.HasPrefix(arr[0], prefix) {
+ sysctl[arr[0]] = arr[1]
+ foundMatch = true
+ break
+ }
+ }
+ if !foundMatch {
+ return nil, errors.Errorf("sysctl '%s' is not whitelisted", arr[0])
+ }
+ }
+ return sysctl, nil
+}
diff --git a/pkg/util/utils_linux_test.go b/pkg/util/utils_linux_test.go
new file mode 100644
index 000000000..38e6dbef9
--- /dev/null
+++ b/pkg/util/utils_linux_test.go
@@ -0,0 +1,29 @@
+package util
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestGetImageConfigStopSignal(t *testing.T) {
+ // Linux-only beause parsing signal names is not supported on non-Linux systems by
+ // pkg/signal.
+ stopSignalValidInt, err := GetImageConfig([]string{"STOPSIGNAL 9"})
+ require.Nil(t, err)
+ assert.Equal(t, stopSignalValidInt.StopSignal, "9")
+
+ stopSignalValidString, err := GetImageConfig([]string{"STOPSIGNAL SIGKILL"})
+ require.Nil(t, err)
+ assert.Equal(t, stopSignalValidString.StopSignal, "9")
+
+ _, err = GetImageConfig([]string{"STOPSIGNAL 0"})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"STOPSIGNAL garbage"})
+ assert.NotNil(t, err)
+
+ _, err = GetImageConfig([]string{"STOPSIGNAL "})
+ assert.NotNil(t, err)
+}
diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go
index 0b78a8150..c6aed9943 100644
--- a/pkg/util/utils_supported.go
+++ b/pkg/util/utils_supported.go
@@ -33,7 +33,7 @@ func GetRuntimeDir() (string, error) {
logrus.Debugf("unable to make temp dir %s", tmpDir)
}
st, err := os.Stat(tmpDir)
- if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
+ if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0700 == 0700) {
runtimeDir = tmpDir
}
}
@@ -43,7 +43,7 @@ func GetRuntimeDir() (string, error) {
logrus.Debugf("unable to make temp dir %s", tmpDir)
}
st, err := os.Stat(tmpDir)
- if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
+ if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0700 == 0700) {
runtimeDir = tmpDir
}
}
diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go
index f4b03599d..a9b37844e 100644
--- a/pkg/util/utils_test.go
+++ b/pkg/util/utils_test.go
@@ -219,25 +219,6 @@ func TestGetImageConfigLabel(t *testing.T) {
assert.NotNil(t, err)
}
-func TestGetImageConfigStopSignal(t *testing.T) {
- stopSignalValidInt, err := GetImageConfig([]string{"STOPSIGNAL 9"})
- require.Nil(t, err)
- assert.Equal(t, stopSignalValidInt.StopSignal, "9")
-
- stopSignalValidString, err := GetImageConfig([]string{"STOPSIGNAL SIGKILL"})
- require.Nil(t, err)
- assert.Equal(t, stopSignalValidString.StopSignal, "9")
-
- _, err = GetImageConfig([]string{"STOPSIGNAL 0"})
- assert.NotNil(t, err)
-
- _, err = GetImageConfig([]string{"STOPSIGNAL garbage"})
- assert.NotNil(t, err)
-
- _, err = GetImageConfig([]string{"STOPSIGNAL "})
- assert.NotNil(t, err)
-}
-
func TestGetImageConfigOnBuild(t *testing.T) {
onBuildOne, err := GetImageConfig([]string{"ONBUILD ADD /testdir1"})
require.Nil(t, err)
@@ -264,3 +245,15 @@ func TestGetImageConfigMisc(t *testing.T) {
_, err = GetImageConfig([]string{"BADINST testvalue"})
assert.NotNil(t, err)
}
+
+func TestValidateSysctls(t *testing.T) {
+ strSlice := []string{"net.core.test1=4", "kernel.msgmax=2"}
+ result, _ := ValidateSysctls(strSlice)
+ assert.Equal(t, result["net.core.test1"], "4")
+}
+
+func TestValidateSysctlBadSysctl(t *testing.T) {
+ strSlice := []string{"BLAU=BLUE", "GELB^YELLOW"}
+ _, err := ValidateSysctls(strSlice)
+ assert.Error(t, err)
+}