Merge pull request #4850 from vrothberg/fix-linting

Fix linting
This commit is contained in:
OpenShift Merge Robot 2020-01-13 21:03:21 +01:00 committed by GitHub
commit 796ae87b1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
58 changed files with 229 additions and 1019 deletions

View file

@ -102,6 +102,8 @@ gating_task:
networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
gate_script:
# TODO: remove once the image doesn't ship with pre-installed tools
- rm /go/bin/*
# N/B: entrypoint.sh resets $GOSRC (same as make clean)
- '/usr/local/bin/entrypoint.sh install.tools |& ${TIMESTAMP}'
- '/usr/local/bin/entrypoint.sh validate |& ${TIMESTAMP}'

View file

@ -6,8 +6,9 @@ run:
- selinux
concurrency: 6
deadline: 5m
skip-dirs-use-default: true
skip-dirs:
- dependencies/*
- dependencies
- contrib
- test/e2e
- docs
@ -16,39 +17,19 @@ run:
skip-files:
- iopodman.go
linters:
disable-all: true
enable:
- bodyclose
- deadcode
- depguard
# dupl really overdid it; disabling
# - dupl
- errcheck
- gofmt
- gosimple
- govet
- ineffassign
- nakedret
- staticcheck
- structcheck
- typecheck
- unused
- varcheck
# - gochecknoglobals
# - gochecknoinits
# - goconst
# - gocritic
# - gocyclo
# - goimports
# - golint
# - gosec
- interfacer
# - lll
# - maligned
# - misspell
# - prealloc
- scopelint
- stylecheck
- unconvert
# I think we should uncomment this one and used it
# - unparam
enable-all: true
disable:
- dupl
- funlen
- gochecknoglobals
- gochecknoinits
- goconst
- gocyclo
- golint
- goimports
- gosec
- lll
- maligned
- misspell
- prealloc
- unparam

View file

@ -1,46 +0,0 @@
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
# Create the linter path for use later
LINTER=${GOPATH}/bin/gometalinter
# Make sure gometalinter is installed
if [ ! -f ${LINTER} ]; then
echo >&2 "gometalinter must be installed. Please run 'make install.tools' and try again"
exit 1
fi
PKGS=$(find . -type d -not -path . -a -not -iwholename '*.git*' -a -not -iname '.tool' -a -not -iwholename '*vendor*' -a -not -iname 'hack' -a -not -iwholename '*.artifacts*' -a -not -iwholename '*contrib*' -a -not -iwholename '*test*' -a -not -iwholename '*logo*' -a -not -iwholename '*conmon*' -a -not -iwholename '*completions*' -a -not -iwholename '*docs*' -a -not -iwholename '*pause*' -a -not -iwholename './_output*' -a -not -iwholename '*ioprojectatomicpodman.go')
echo $PKGS
# Execute the linter
${LINTER} \
--concurrency=4\
--enable-gc\
--vendored-linters\
--deadline=600s --disable-all\
--enable=deadcode\
--enable=errcheck\
--enable=gofmt\
--enable=golint\
--enable=ineffassign\
--enable=megacheck\
--enable=misspell\
--enable=structcheck\
--enable=varcheck\
--enable=vet\
--enable=vetshadow\
--exclude='error return value not checked.*\(errcheck\)$'\
--exclude='declaration of.*err.*shadows declaration.*\(vetshadow\)$'\
--exclude='.*_test\.go:.*error return value not checked.*\(errcheck\)$'\
--exclude='duplicate of.*_test.go.*\(dupl\)$'\
--exclude='cmd\/client\/.*\.go.*\(dupl\)$'\
--exclude='vendor\/.*'\
--exclude='podman\/.*'\
--exclude='server\/seccomp\/.*\.go.*$'\
--exclude='dependencies\/.*'\
${PKGS[@]}

View file

@ -148,9 +148,7 @@ ifeq ("$(wildcard $(GOPKGDIR))","")
endif
touch $@
lint: .gopathok varlink_generate ## Execute the source code linter
@echo "checking lint"
@./.tool/lint
lint: golangci-lint
golangci-lint: .gopathok varlink_generate .install.golangci-lint
$(GOBIN)/golangci-lint run --tests=false --skip-files swagger.go
@ -314,12 +312,6 @@ remotesystem:
system.test-binary: .install.ginkgo
$(GO) test -c ./test/system
perftest: ## Build perf tests
$ cd contrib/perftest;go build
run-perftest: perftest ## Build and run perf tests
$ contrib/perftest/perftest
vagrant-check:
BOX=$(BOX) sh ./vagrant.sh
@ -517,7 +509,7 @@ endef
.install.golangci-lint: .gopathok
if [ ! -x "$(GOBIN)/golangci-lint" ]; then \
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOBIN)/ v1.17.1; \
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOBIN)/ v1.18.0; \
fi
.install.md2man: .gopathok

View file

@ -116,21 +116,22 @@ func getContainerfiles(files []string) []string {
func getNsValues(c *cliconfig.BuildValues) ([]buildah.NamespaceOption, error) {
var ret []buildah.NamespaceOption
if c.Network != "" {
if c.Network == "host" {
switch {
case c.Network == "host":
ret = append(ret, buildah.NamespaceOption{
Name: string(specs.NetworkNamespace),
Host: true,
})
} else if c.Network == "container" {
case c.Network == "container":
ret = append(ret, buildah.NamespaceOption{
Name: string(specs.NetworkNamespace),
})
} else if c.Network[0] == '/' {
case c.Network[0] == '/':
ret = append(ret, buildah.NamespaceOption{
Name: string(specs.NetworkNamespace),
Path: c.Network,
})
} else {
default:
return nil, fmt.Errorf("unsupported configuration network=%s", c.Network)
}
}

View file

@ -24,7 +24,8 @@ func getAllOrLatestContainers(c *cliconfig.PodmanCommand, runtime *libpod.Runtim
var containers []*libpod.Container
var lastError error
var err error
if c.Bool("all") {
switch {
case c.Bool("all"):
if filterState != -1 {
var filterFuncs []libpod.ContainerFilter
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
@ -38,13 +39,13 @@ func getAllOrLatestContainers(c *cliconfig.PodmanCommand, runtime *libpod.Runtim
if err != nil {
return nil, errors.Wrapf(err, "unable to get %s containers", verb)
}
} else if c.Bool("latest") {
case c.Bool("latest"):
lastCtr, err := runtime.GetLatestContainer()
if err != nil {
return nil, errors.Wrapf(err, "unable to get latest container")
}
containers = append(containers, lastCtr)
} else {
default:
args := c.InputArgs
for _, i := range args {
container, err := runtime.LookupContainer(i)

View file

@ -138,25 +138,25 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
hostOwner := idtools.IDPair{UID: int(hostUID), GID: int(hostGID)}
if isFromHostToCtr {
if isVol, volDestName, volName := isVolumeDestName(destPath, ctr); isVol {
if isVol, volDestName, volName := isVolumeDestName(destPath, ctr); isVol { //nolint(gocritic)
path, err := pathWithVolumeMount(ctr, runtime, volDestName, volName, destPath)
if err != nil {
return errors.Wrapf(err, "error getting destination path from volume %s", volDestName)
}
destPath = path
} else if isBindMount, mount := isBindMountDestName(destPath, ctr); isBindMount {
} else if isBindMount, mount := isBindMountDestName(destPath, ctr); isBindMount { //nolint(gocritic)
path, err := pathWithBindMountSource(mount, destPath)
if err != nil {
return errors.Wrapf(err, "error getting destination path from bind mount %s", mount.Destination)
}
destPath = path
} else if filepath.IsAbs(destPath) {
} else if filepath.IsAbs(destPath) { //nolint(gocritic)
cleanedPath, err := securejoin.SecureJoin(mountPoint, destPath)
if err != nil {
return err
}
destPath = cleanedPath
} else {
} else { //nolint(gocritic)
ctrWorkDir, err := securejoin.SecureJoin(mountPoint, ctr.WorkingDir())
if err != nil {
return err
@ -172,25 +172,25 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
}
} else {
destOwner = idtools.IDPair{UID: os.Getuid(), GID: os.Getgid()}
if isVol, volDestName, volName := isVolumeDestName(srcPath, ctr); isVol {
if isVol, volDestName, volName := isVolumeDestName(srcPath, ctr); isVol { //nolint(gocritic)
path, err := pathWithVolumeMount(ctr, runtime, volDestName, volName, srcPath)
if err != nil {
return errors.Wrapf(err, "error getting source path from volume %s", volDestName)
}
srcPath = path
} else if isBindMount, mount := isBindMountDestName(srcPath, ctr); isBindMount {
} else if isBindMount, mount := isBindMountDestName(srcPath, ctr); isBindMount { //nolint(gocritic)
path, err := pathWithBindMountSource(mount, srcPath)
if err != nil {
return errors.Wrapf(err, "error getting source path from bind mount %s", mount.Destination)
}
srcPath = path
} else if filepath.IsAbs(srcPath) {
} else if filepath.IsAbs(srcPath) { //nolint(gocritic)
cleanedPath, err := securejoin.SecureJoin(mountPoint, srcPath)
if err != nil {
return err
}
srcPath = cleanedPath
} else {
} else { //nolint(gocritic)
cleanedPath, err := securejoin.SecureJoin(mountPoint, filepath.Join(ctr.WorkingDir(), srcPath))
if err != nil {
return err

View file

@ -115,14 +115,14 @@ func genHistoryFormat(format string, quiet bool) string {
}
// historyToGeneric makes an empty array of interfaces for output
func historyToGeneric(templParams []historyTemplateParams, JSONParams []*image.History) (genericParams []interface{}) {
func historyToGeneric(templParams []historyTemplateParams, jsonParams []*image.History) (genericParams []interface{}) {
if len(templParams) > 0 {
for _, v := range templParams {
genericParams = append(genericParams, interface{}(v))
}
return
}
for _, v := range JSONParams {
for _, v := range jsonParams {
genericParams = append(genericParams, interface{}(v))
}
return

View file

@ -209,7 +209,7 @@ func (i imagesOptions) setOutputFormat() string {
}
// imagesToGeneric creates an empty array of interfaces for output
func imagesToGeneric(templParams []imagesTemplateParams, JSONParams []imagesJSONParams) []interface{} {
func imagesToGeneric(templParams []imagesTemplateParams, jsonParams []imagesJSONParams) []interface{} {
genericParams := []interface{}{}
if len(templParams) > 0 {
for _, v := range templParams {
@ -217,7 +217,7 @@ func imagesToGeneric(templParams []imagesTemplateParams, JSONParams []imagesJSON
}
return genericParams
}
for _, v := range JSONParams {
for _, v := range jsonParams {
genericParams = append(genericParams, interface{}(v))
}
return genericParams
@ -282,11 +282,9 @@ func getImagesTemplateOutput(ctx context.Context, images []*adapter.ContainerIma
if len(tag) == 71 && strings.HasPrefix(tag, "sha256:") {
imageDigest = digest.Digest(tag)
tag = ""
} else {
if img.Digest() != "" {
} else if img.Digest() != "" {
imageDigest = img.Digest()
}
}
params := imagesTemplateParams{
Repository: repo,
Tag: tag,

View file

@ -75,12 +75,8 @@ var rootCmd = &cobra.Command{
Use: path.Base(os.Args[0]),
Long: "manage pods and images",
RunE: commandRunE(),
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return before(cmd, args)
},
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
return after(cmd, args)
},
PersistentPreRunE: before,
PersistentPostRunE: after,
SilenceUsage: true,
SilenceErrors: true,
}
@ -160,18 +156,15 @@ func main() {
}
if err := rootCmd.Execute(); err != nil {
outputError(err)
} else {
} else if exitCode == define.ExecErrorCodeGeneric {
// The exitCode modified from define.ExecErrorCodeGeneric,
// indicates an application
// running inside of a container failed, as opposed to the
// podman command failed. Must exit with that exit code
// otherwise command exited correctly.
if exitCode == define.ExecErrorCodeGeneric {
exitCode = 0
}
}
// Check if /etc/containers/registries.conf exists when running in
// in a local environment.
CheckForRegistries()

View file

@ -320,13 +320,14 @@ func generatePodFilterFuncs(filter, filterValue string) (func(pod *adapter.Pod)
// generate the template based on conditions given
func genPodPsFormat(c *cliconfig.PodPsValues) string {
format := ""
if c.Format != "" {
switch {
case c.Format != "":
// "\t" from the command line is not being recognized as a tab
// replacing the string "\t" to a tab character if the user passes in "\t"
format = strings.Replace(c.Format, `\t`, "\t", -1)
} else if c.Quiet {
case c.Quiet:
format = formats.IDString
} else {
default:
format = "table {{.ID}}\t{{.Name}}\t{{.Status}}\t{{.Created}}"
if c.Bool("namespace") {
format += "\t{{.Cgroup}}\t{{.Namespaces}}"
@ -341,14 +342,14 @@ func genPodPsFormat(c *cliconfig.PodPsValues) string {
return format
}
func podPsToGeneric(templParams []podPsTemplateParams, JSONParams []podPsJSONParams) (genericParams []interface{}) {
func podPsToGeneric(templParams []podPsTemplateParams, jsonParams []podPsJSONParams) (genericParams []interface{}) {
if len(templParams) > 0 {
for _, v := range templParams {
genericParams = append(genericParams, interface{}(v))
}
return
}
for _, v := range JSONParams {
for _, v := range jsonParams {
genericParams = append(genericParams, interface{}(v))
}
return

View file

@ -124,10 +124,8 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
for i := 0; i < t.NumField(); i++ {
value := strings.ToUpper(splitCamelCase(t.Field(i).Name))
switch value {
case "CPU":
value = value + " %"
case "MEM":
value = value + " %"
case "CPU", "MEM":
value += " %"
case "MEM USAGE":
value = "MEM USAGE / LIMIT"
}
@ -167,12 +165,10 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
results := podContainerStatsToPodStatOut(newStats)
if len(format) == 0 {
outputToStdOut(results)
} else {
if err := printPSFormat(c.Format, results, headerNames); err != nil {
} else if err := printPSFormat(c.Format, results, headerNames); err != nil {
return err
}
}
}
time.Sleep(time.Second)
previousPodStats := new([]*libpod.PodContainerStats)
if err := libpod.JSONDeepCopy(newStats, previousPodStats); err != nil {

View file

@ -65,7 +65,7 @@ func rmiCmd(c *cliconfig.RmiValues) error {
return errors.Errorf("when using the --all switch, you may not pass any images names or IDs")
}
images := args[:]
images := args
removeImage := func(img *adapter.ContainerImage) {
response, err := runtime.RemoveImage(ctx, img, c.Force)

View file

@ -650,10 +650,7 @@ func getNamespaceInfo(path string) (string, error) {
// getStrFromSquareBrackets gets the string inside [] from a string.
func getStrFromSquareBrackets(cmd string) string {
reg, err := regexp.Compile(`.*\[|\].*`)
if err != nil {
return ""
}
reg := regexp.MustCompile(`.*\[|\].*`)
arr := strings.Split(reg.ReplaceAllLiteralString(cmd, ""), ",")
return strings.Join(arr, ",")
}

View file

@ -444,11 +444,12 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
// USER
user := c.String("user")
if user == "" {
if usernsMode.IsKeepID() {
switch {
case usernsMode.IsKeepID():
user = fmt.Sprintf("%d:%d", rootless.GetRootlessUID(), rootless.GetRootlessGID())
} else if data == nil {
case data == nil:
user = "0"
} else {
default:
user = data.Config.User
}
}

View file

@ -59,18 +59,20 @@ func CreatePodStatusResults(ctrStatuses map[string]define.ContainerStatus) (stri
}
}
if statuses[PodStateRunning] > 0 {
switch {
case statuses[PodStateRunning] > 0:
return PodStateRunning, nil
} else if statuses[PodStatePaused] == ctrNum {
case statuses[PodStatePaused] == ctrNum:
return PodStatePaused, nil
} else if statuses[PodStateStopped] == ctrNum {
case statuses[PodStateStopped] == ctrNum:
return PodStateExited, nil
} else if statuses[PodStateStopped] > 0 {
case statuses[PodStateStopped] > 0:
return PodStateStopped, nil
} else if statuses[PodStateErrored] > 0 {
case statuses[PodStateErrored] > 0:
return PodStateErrored, nil
}
default:
return PodStateCreated, nil
}
}
// GetNamespaceOptions transforms a slice of kernel namespaces

View file

@ -105,9 +105,10 @@ func statsCmd(c *cliconfig.StatsValues) error {
var ctrs []*libpod.Container
containerFunc := runtime.GetRunningContainers
if len(c.InputArgs) > 0 {
switch {
case len(c.InputArgs) > 0:
containerFunc = func() ([]*libpod.Container, error) { return runtime.GetContainersByList(c.InputArgs) }
} else if latest {
case latest:
containerFunc = func() ([]*libpod.Container, error) {
lastCtr, err := runtime.GetLatestContainer()
if err != nil {
@ -115,7 +116,7 @@ func statsCmd(c *cliconfig.StatsValues) error {
}
return []*libpod.Container{lastCtr}, nil
}
} else if all {
case all:
containerFunc = runtime.GetAllContainers
}
@ -219,14 +220,14 @@ func genStatsFormat(format string) string {
}
// imagesToGeneric creates an empty array of interfaces for output
func statsToGeneric(templParams []statsOutputParams, JSONParams []statsOutputParams) (genericParams []interface{}) {
func statsToGeneric(templParams []statsOutputParams, jsonParams []statsOutputParams) (genericParams []interface{}) {
if len(templParams) > 0 {
for _, v := range templParams {
genericParams = append(genericParams, interface{}(v))
}
return
}
for _, v := range JSONParams {
for _, v := range jsonParams {
genericParams = append(genericParams, interface{}(v))
}
return

View file

@ -113,12 +113,12 @@ func printImageChildren(layerMap map[string]*image.LayerInfo, layerID string, pr
intend := middleItem
if !last {
// add continueItem i.e. '|' for next iteration prefix
prefix = prefix + continueItem
prefix += continueItem
} else if len(ll.ChildID) > 1 || len(ll.ChildID) == 0 {
// The above condition ensure, alignment happens for node, which has more then 1 children.
// If node is last in printing hierarchy, it should not be printed as middleItem i.e. ├──
intend = lastItem
prefix = prefix + " "
prefix += " "
}
var tags string

View file

@ -134,14 +134,14 @@ func genVolLsFormat(c *cliconfig.VolumeLsValues) string {
}
// Convert output to genericParams for printing
func volLsToGeneric(templParams []volumeLsTemplateParams, JSONParams []volumeLsJSONParams) (genericParams []interface{}) {
func volLsToGeneric(templParams []volumeLsTemplateParams, jsonParams []volumeLsJSONParams) (genericParams []interface{}) {
if len(templParams) > 0 {
for _, v := range templParams {
genericParams = append(genericParams, interface{}(v))
}
return
}
for _, v := range JSONParams {
for _, v := range jsonParams {
genericParams = append(genericParams, interface{}(v))
}
return

View file

@ -1,51 +0,0 @@
## perftest : tool for benchmarking and profiling libpod library
perftest uses libpod as golang library and perform stress test and profile for CPU usage.
Build:
```
# cd $GOPATH/src/github.com/containers/libpod/contrib/perftest
# go build
# go install
```
Usage:
```
# perftest -h
Usage of perftest:
-count int
count of loop counter for test (default 50)
-image string
image-name to be used for test (default "docker.io/library/alpine:latest")
```
e.g.
```
# perftest
runc version spec: 1.0.1-dev
conmon version 1.12.0-dev, commit: b6c5cafeffa9b3cde89812207b29ccedd3102712
preparing test environment...
2018/11/05 16:52:14 profile: cpu profiling enabled, /tmp/profile626959338/cpu.pprof
Test Round: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
Profile data
Create Start Stop Delete
Min 0.23s 0.34s 2.12s 0.51s
Avg 0.25s 0.38s 2.13s 0.54s
Max 0.27s 0.48s 2.13s 0.70s
Total 12.33s 18.82s 106.47s 26.91s
2018/11/05 16:54:59 profile: cpu profiling disabled, /tmp/profile626959338/cpu.pprof
```
Analyse CPU profile.
```
# go tool pprof -http=":8081" $GOPATH/src/github.com/containers/libpod/contrib/perftest/perftest /tmp/profile626959338/cpu.pprof
```
- Open http://localhost:8081 in webbrowser

View file

@ -1,282 +0,0 @@
package main
import (
"context"
"flag"
"fmt"
"os"
"strings"
"text/tabwriter"
"time"
"github.com/containers/image/v5/types"
"github.com/containers/libpod/libpod"
image2 "github.com/containers/libpod/libpod/image"
cc "github.com/containers/libpod/pkg/spec"
"github.com/containers/libpod/pkg/util"
"github.com/containers/storage/pkg/reexec"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/pkg/profile"
"github.com/sirupsen/logrus"
)
const (
defaultTestImage = "docker.io/library/alpine:latest"
defaultRunCount = 50
)
var helpMessage = `
-count int
count of loop counter for test (default 50)
-image string
image-name to be used for test (default "docker.io/library/alpine:latest")
-log string
log level (info|debug|warn|error) (default "error")
`
func main() {
if reexec.Init() {
return
}
ctx := context.Background()
imageName := ""
testImageName := flag.String("image", defaultTestImage, "image-name to be used for test")
testRunCount := flag.Int("count", defaultRunCount, "count of loop counter for test")
logLevel := flag.String("log", "error", "log level (info|debug|warn|error)")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
fmt.Fprintf(os.Stderr, "%s \n", helpMessage)
}
flag.Parse()
switch strings.ToLower(*logLevel) {
case "error":
logrus.SetLevel(logrus.ErrorLevel)
case "warn":
logrus.SetLevel(logrus.WarnLevel)
case "info":
logrus.SetLevel(logrus.InfoLevel)
case "debug":
logrus.SetLevel(logrus.DebugLevel)
default:
logrus.Fatalf("invalid option : %s ", *logLevel)
}
opts := defaultRuntimeOptions()
client, err := libpod.NewRuntime(opts...)
if err != nil {
logrus.Fatal(err)
}
defer client.Shutdown(false)
// Print Runtime & System Information.
err = printSystemInfo(client)
if err != nil {
logrus.Fatal(err)
}
imageRuntime := client.ImageRuntime()
if imageRuntime == nil {
logrus.Fatal("ImageRuntime is null")
}
fmt.Printf("preparing test environment...\n")
//Prepare for test.
testImage, err := imageRuntime.NewFromLocal(*testImageName)
if err != nil {
// Download the image from remote registry.
writer := os.Stderr
registryCreds := &types.DockerAuthConfig{
Username: "",
Password: "",
}
dockerRegistryOptions := image2.DockerRegistryOptions{
DockerRegistryCreds: registryCreds,
DockerCertPath: "",
DockerInsecureSkipTLSVerify: types.OptionalBoolFalse,
}
fmt.Printf("image %s not found locally, fetching from remote registry..\n", *testImageName)
testImage, err = client.ImageRuntime().New(ctx, *testImageName, "", "", writer, &dockerRegistryOptions, image2.SigningOptions{}, nil, util.PullImageMissing)
if err != nil {
logrus.Fatal(err)
}
fmt.Printf("image downloaded successfully\n\n")
}
names := testImage.Names()
if len(names) > 0 {
imageName = names[0]
} else {
imageName = testImage.ID()
}
idmappings, err := util.ParseIDMapping(nil, nil, "", "")
if err != nil {
logrus.Fatal(err)
}
config := &cc.CreateConfig{
Tty: true,
Image: imageName,
ImageID: testImage.ID(),
IDMappings: idmappings,
Command: []string{"/bin/sh"},
WorkDir: "/",
NetMode: "bridge",
Network: "bridge",
}
// Enable CPU Profile
defer profile.Start().Stop()
data, err := runSingleThreadedStressTest(ctx, client, imageName, testImage.ID(), config, *testRunCount)
if err != nil {
logrus.Fatal(err)
}
data.printProfiledData((float64)(*testRunCount))
}
func defaultRuntimeOptions() []libpod.RuntimeOption {
options := []libpod.RuntimeOption{}
return options
/*
//TODO: Shall we test in clean environment?
sOpts := storage.StoreOptions{
GraphDriverName: "overlay",
RunRoot: "/var/run/containers/storage",
GraphRoot: "/var/lib/containers/storage",
}
storageOpts := libpod.WithStorageConfig(sOpts)
options = append(options, storageOpts)
return options
*/
}
func printSystemInfo(client *libpod.Runtime) error {
OCIRuntimeInfo, err := client.GetOCIRuntimeVersion()
if err != nil {
return err
}
connmanInfo, err := client.GetConmonVersion()
if err != nil {
return err
}
fmt.Printf("%s\n%s\n\n", OCIRuntimeInfo, connmanInfo)
return nil
}
func runSingleThreadedStressTest(ctx context.Context, client *libpod.Runtime, imageName string, imageID string, config *cc.CreateConfig, testCount int) (*profileData, error) {
data := new(profileData)
fmt.Printf("Test Round: ")
for i := 0; i < testCount; i++ {
fmt.Printf("%d ", i)
runtimeSpec, err := cc.CreateConfigToOCISpec(config)
if err != nil {
return nil, err
}
//Create Container
networks := make([]string, 0)
netmode := "bridge"
createStartTime := time.Now()
ctr, err := client.NewContainer(ctx,
runtimeSpec,
libpod.WithRootFSFromImage(imageID, imageName, false),
libpod.WithNetNS([]ocicni.PortMapping{}, false, netmode, networks),
)
if err != nil {
return nil, err
}
createTotalTime := time.Now().Sub(createStartTime)
// Start container
startStartTime := time.Now()
err = ctr.Start(ctx, false)
if err != nil {
return nil, err
}
startTotalTime := time.Now().Sub(startStartTime)
//Stop Container
stopStartTime := time.Now()
err = ctr.StopWithTimeout(2)
if err != nil {
return nil, err
}
stopTotalTime := time.Now().Sub(stopStartTime)
//Delete Container
deleteStartTime := time.Now()
err = client.RemoveContainer(ctx, ctr, true, false)
if err != nil {
return nil, err
}
deleteTotalTime := time.Now().Sub(deleteStartTime)
data.updateProfileData(createTotalTime, startTotalTime, stopTotalTime, deleteTotalTime)
}
return data, nil
}
type profileData struct {
minCreate, minStart, minStop, minDel time.Duration
avgCreate, avgStart, avgStop, avgDel time.Duration
maxCreate, maxStart, maxStop, maxDel time.Duration
}
func (data *profileData) updateProfileData(create, start, stop, delete time.Duration) {
if create < data.minCreate || data.minCreate == 0 {
data.minCreate = create
}
if create > data.maxCreate || data.maxCreate == 0 {
data.maxCreate = create
}
if start < data.minStart || data.minStart == 0 {
data.minStart = start
}
if start > data.maxStart || data.maxStart == 0 {
data.maxStart = start
}
if stop < data.minStop || data.minStop == 0 {
data.minStop = stop
}
if stop > data.maxStop || data.maxStop == 0 {
data.maxStop = stop
}
if delete < data.minDel || data.minDel == 0 {
data.minDel = delete
}
if delete > data.maxDel || data.maxDel == 0 {
data.maxDel = delete
}
data.avgCreate = data.avgCreate + create
data.avgStart = data.avgStart + start
data.avgStop = data.avgStop + stop
data.avgDel = data.avgDel + delete
}
func (data *profileData) printProfiledData(testCount float64) {
fmt.Printf("\nProfile data\n\n")
w := new(tabwriter.Writer)
w.Init(os.Stdout, 0, 8, 0, '\t', 0)
fmt.Fprintln(w, "\tCreate\tStart\tStop\tDelete")
fmt.Fprintf(w, "Min\t%.2fs\t%.2fs\t%.2fs\t%.2fs\n", data.minCreate.Seconds(), data.minStart.Seconds(), data.minStop.Seconds(), data.minDel.Seconds())
fmt.Fprintf(w, "Avg\t%.2fs\t%.2fs\t%.2fs\t%.2fs\n", data.avgCreate.Seconds()/testCount, data.avgStart.Seconds()/testCount, data.avgStop.Seconds()/testCount, data.avgDel.Seconds()/testCount)
fmt.Fprintf(w, "Max\t%.2fs\t%.2fs\t%.2fs\t%.2fs\n", data.maxCreate.Seconds(), data.maxStart.Seconds(), data.maxStop.Seconds(), data.maxDel.Seconds())
fmt.Fprintf(w, "Total\t%.2fs\t%.2fs\t%.2fs\t%.2fs\n", data.avgCreate.Seconds(), data.avgStart.Seconds(), data.avgStop.Seconds(), data.avgDel.Seconds())
fmt.Fprintln(w)
w.Flush()
}

2
go.mod
View file

@ -51,7 +51,7 @@ require (
github.com/opencontainers/selinux v1.3.0
github.com/opentracing/opentracing-go v1.1.0
github.com/pkg/errors v0.8.1
github.com/pkg/profile v1.4.0
github.com/pkg/profile v1.4.0 // indirect
github.com/pmezard/go-difflib v1.0.0
github.com/rootless-containers/rootlesskit v0.7.1
github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f

View file

@ -652,12 +652,10 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error {
if string(depCtrPod) != pod.ID() {
return errors.Wrapf(define.ErrInvalidArg, "container %s depends on container %s which is in a different pod (%s)", ctr.ID(), dependsCtr, string(depCtrPod))
}
} else {
} else if depCtrPod != nil {
// If we're not part of a pod, we cannot depend on containers in a pod
if depCtrPod != nil {
return errors.Wrapf(define.ErrInvalidArg, "container %s depends on container %s which is in a pod - containers not in pods cannot depend on containers in pods", ctr.ID(), dependsCtr)
}
}
depNamespace := depCtrBkt.Get(namespaceKey)
if !bytes.Equal(ctrNamespace, depNamespace) {

View file

@ -472,12 +472,10 @@ func (c *Container) specFromState() (*spec.Spec, error) {
if err := json.Unmarshal(content, &returnSpec); err != nil {
return nil, errors.Wrapf(err, "error unmarshalling container config")
}
} else {
} else if !os.IsNotExist(err) {
// ignore when the file does not exist
if !os.IsNotExist(err) {
return nil, errors.Wrapf(err, "error opening container config")
}
}
return returnSpec, nil
}

View file

@ -56,7 +56,7 @@ func (c *Container) readFromLogFile(options *logs.LogOptions, logChannel chan *l
continue
}
if nll.Partial() {
partial = partial + nll.Msg
partial += nll.Msg
continue
} else if !nll.Partial() && len(partial) > 1 {
nll.Msg = partial

View file

@ -113,7 +113,7 @@ func detectCycles(graph *ContainerGraph) (bool, error) {
info := new(nodeInfo)
info.index = index
info.lowLink = index
index = index + 1
index++
nodes[node.id] = info

View file

@ -1214,11 +1214,12 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
// Network mode parsing.
networkMode := ""
if c.config.CreateNetNS {
switch {
case c.config.CreateNetNS:
networkMode = "default"
} else if c.config.NetNsCtr != "" {
case c.config.NetNsCtr != "":
networkMode = fmt.Sprintf("container:%s", c.config.NetNsCtr)
} else {
default:
// Find the spec's network namespace.
// If there is none, it's host networking.
// If there is one and it has a path, it's "ns:".

View file

@ -22,7 +22,7 @@ import (
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/mount"
"github.com/cyphar/filepath-securejoin"
securejoin "github.com/cyphar/filepath-securejoin"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
@ -339,7 +339,7 @@ func (c *Container) handleRestartPolicy(ctx context.Context) (restarted bool, er
c.newContainerEvent(events.Restart)
// Increment restart count
c.state.RestartCount = c.state.RestartCount + 1
c.state.RestartCount += 1
logrus.Debugf("Container %s now on retry %d", c.ID(), c.state.RestartCount)
if err := c.save(); err != nil {
return false, err
@ -1286,7 +1286,7 @@ func (c *Container) restartWithTimeout(ctx context.Context, timeout uint) (err e
// TODO: Add ability to override mount label so we can use this for Mount() too
// TODO: Can we use this for export? Copying SHM into the export might not be
// good
func (c *Container) mountStorage() (_ string, Err error) {
func (c *Container) mountStorage() (_ string, deferredErr error) {
var err error
// Container already mounted, nothing to do
if c.state.Mounted {
@ -1307,7 +1307,7 @@ func (c *Container) mountStorage() (_ string, Err error) {
return "", errors.Wrapf(err, "failed to chown %s", c.config.ShmDir)
}
defer func() {
if Err != nil {
if deferredErr != nil {
if err := c.unmountSHM(c.config.ShmDir); err != nil {
logrus.Errorf("Error unmounting SHM for container %s after mount error: %v", c.ID(), err)
}
@ -1324,7 +1324,7 @@ func (c *Container) mountStorage() (_ string, Err error) {
return "", err
}
defer func() {
if Err != nil {
if deferredErr != nil {
if err := c.unmount(false); err != nil {
logrus.Errorf("Error unmounting container %s after mount error: %v", c.ID(), err)
}
@ -1339,7 +1339,7 @@ func (c *Container) mountStorage() (_ string, Err error) {
return "", err
}
defer func() {
if Err == nil {
if deferredErr == nil {
return
}
vol.lock.Lock()

View file

@ -62,7 +62,7 @@ func (c *Container) unmountSHM(mount string) error {
// prepare mounts the container and sets up other required resources like net
// namespaces
func (c *Container) prepare() (Err error) {
func (c *Container) prepare() error {
var (
wg sync.WaitGroup
netNS ns.NetNS
@ -1277,21 +1277,21 @@ func (c *Container) generateResolvConf() (string, error) {
}
// If the user provided dns, it trumps all; then dns masq; then resolv.conf
if len(c.config.DNSServer) > 0 {
switch {
case len(c.config.DNSServer) > 0:
// We store DNS servers as net.IP, so need to convert to string
for _, server := range c.config.DNSServer {
nameservers = append(nameservers, server.String())
}
} else if len(cniNameServers) > 0 {
case len(cniNameServers) > 0:
nameservers = append(nameservers, cniNameServers...)
} else {
default:
// Make a new resolv.conf
nameservers = resolvconf.GetNameservers(resolv.Content)
// slirp4netns has a built in DNS server.
if c.config.NetMode.IsSlirp4netns() {
nameservers = append([]string{"10.0.2.3"}, nameservers...)
}
}
search := resolvconf.GetSearchDomains(resolv.Content)
@ -1451,23 +1451,24 @@ func (c *Container) getOCICgroupPath() (string, error) {
if err != nil {
return "", err
}
if (rootless.IsRootless() && !unified) || c.config.NoCgroups {
switch {
case (rootless.IsRootless() && !unified) || c.config.NoCgroups:
return "", nil
} else if c.runtime.config.CgroupManager == define.SystemdCgroupsManager {
case c.runtime.config.CgroupManager == define.SystemdCgroupsManager:
// When runc is set to use Systemd as a cgroup manager, it
// expects cgroups to be passed as follows:
// slice:prefix:name
systemdCgroups := fmt.Sprintf("%s:libpod:%s", path.Base(c.config.CgroupParent), c.ID())
logrus.Debugf("Setting CGroups for container %s to %s", c.ID(), systemdCgroups)
return systemdCgroups, nil
} else if c.runtime.config.CgroupManager == define.CgroupfsCgroupsManager {
case c.runtime.config.CgroupManager == define.CgroupfsCgroupsManager:
cgroupPath, err := c.CGroupPath()
if err != nil {
return "", err
}
logrus.Debugf("Setting CGroup path for container %s to %s", c.ID(), cgroupPath)
return cgroupPath, nil
} else {
default:
return "", errors.Wrapf(define.ErrInvalidArg, "invalid cgroup manager %s requested", c.runtime.config.CgroupManager)
}
}

View file

@ -129,8 +129,6 @@ func StringToStatus(name string) (Status, error) {
return Attach, nil
case Checkpoint.String():
return Checkpoint, nil
case Restore.String():
return Restore, nil
case Cleanup.String():
return Cleanup, nil
case Commit.String():

View file

@ -238,7 +238,7 @@ func (c *Container) updateHealthCheckLog(hcl HealthCheckLog, inStartPeriod bool)
}
if !inStartPeriod {
// increment failing streak
healthCheck.FailingStreak = healthCheck.FailingStreak + 1
healthCheck.FailingStreak += 1
// if failing streak > retries, then status to unhealthy
if healthCheck.FailingStreak >= c.HealthCheckConfig().Retries {
healthCheck.Status = HealthCheckUnhealthy

View file

@ -902,8 +902,7 @@ func (i *Image) Annotations(ctx context.Context) (map[string]string, error) {
}
}
annotations := make(map[string]string)
switch manifestType {
case ociv1.MediaTypeImageManifest:
if manifestType == ociv1.MediaTypeImageManifest {
var m ociv1.Manifest
if err := json.Unmarshal(imageManifest, &m); err == nil {
for k, v := range m.Annotations {

View file

@ -15,7 +15,7 @@ import (
"github.com/opencontainers/runtime-tools/generate"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@ -365,11 +365,12 @@ func generateKubeVolumeMount(m specs.Mount) (v1.VolumeMount, v1.Volume, error) {
// neither a directory or a file lives here, default to creating a directory
// TODO should this be an error instead?
var hostPathType v1.HostPathType
if err != nil {
switch {
case err != nil:
hostPathType = v1.HostPathDirectoryOrCreate
} else if isDir {
case isDir:
hostPathType = v1.HostPathDirectory
} else {
default:
hostPathType = v1.HostPathFile
}
vo.HostPath.Type = &hostPathType

View file

@ -96,7 +96,7 @@ func getTailLog(path string, tail int) ([]*LogLine, error) {
}
nlls = append(nlls, nll)
if !nll.Partial() {
tailCounter = tailCounter + 1
tailCounter++
}
if tailCounter == tail {
break
@ -105,9 +105,9 @@ func getTailLog(path string, tail int) ([]*LogLine, error) {
// Now we iterate the results and assemble partial messages to become full messages
for _, nll := range nlls {
if nll.Partial() {
partial = partial + nll.Msg
partial += nll.Msg
} else {
nll.Msg = nll.Msg + partial
nll.Msg += partial
tailLog = append(tailLog, nll)
partial = ""
}
@ -127,7 +127,7 @@ func (l *LogLine) String(options *LogOptions) string {
out = fmt.Sprintf("%s ", cid)
}
if options.Timestamps {
out = out + fmt.Sprintf("%s ", l.Time.Format(LogTimeFormat))
out += fmt.Sprintf("%s ", l.Time.Format(LogTimeFormat))
}
return out + l.Msg
}

View file

@ -586,7 +586,8 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options
// we don't want to step on users fds they asked to preserve
// Since 0-2 are used for stdio, start the fds we pass in at preserveFDs+3
execCmd.Env = append(r.conmonEnv, fmt.Sprintf("_OCI_SYNCPIPE=%d", options.PreserveFDs+3), fmt.Sprintf("_OCI_STARTPIPE=%d", options.PreserveFDs+4), fmt.Sprintf("_OCI_ATTACHPIPE=%d", options.PreserveFDs+5))
execCmd.Env = r.conmonEnv
execCmd.Env = append(execCmd.Env, fmt.Sprintf("_OCI_SYNCPIPE=%d", options.PreserveFDs+3), fmt.Sprintf("_OCI_STARTPIPE=%d", options.PreserveFDs+4), fmt.Sprintf("_OCI_ATTACHPIPE=%d", options.PreserveFDs+5))
execCmd.Env = append(execCmd.Env, conmonEnv...)
execCmd.ExtraFiles = append(execCmd.ExtraFiles, childSyncPipe, childStartPipe, childAttachPipe)
@ -998,7 +999,8 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
return err
}
cmd.Env = append(r.conmonEnv, fmt.Sprintf("_OCI_SYNCPIPE=%d", 3), fmt.Sprintf("_OCI_STARTPIPE=%d", 4))
cmd.Env = r.conmonEnv
cmd.Env = append(cmd.Env, fmt.Sprintf("_OCI_SYNCPIPE=%d", 3), fmt.Sprintf("_OCI_STARTPIPE=%d", 4))
cmd.Env = append(cmd.Env, conmonEnv...)
cmd.ExtraFiles = append(cmd.ExtraFiles, childSyncPipe, childStartPipe)
cmd.ExtraFiles = append(cmd.ExtraFiles, envFiles...)
@ -1306,15 +1308,13 @@ func (r *ConmonOCIRuntime) moveConmonToCgroupAndSignal(ctr *Container, cmd *exec
control, err := cgroups.New(cgroupPath, &spec.LinuxResources{})
if err != nil {
logrus.Warnf("Failed to add conmon to cgroupfs sandbox cgroup: %v", err)
} else {
} else if err := control.AddPid(cmd.Process.Pid); err != nil {
// we need to remove this defer and delete the cgroup once conmon exits
// maybe need a conmon monitor?
if err := control.AddPid(cmd.Process.Pid); err != nil {
logrus.Warnf("Failed to add conmon to cgroupfs sandbox cgroup: %v", err)
}
}
}
}
/* We set the cgroup, now the child can start creating children */
if err := writeConmonPipeData(startFd); err != nil {

View file

@ -733,7 +733,9 @@ func WithExitCommand(exitCommand []string) CtrCreateOption {
return define.ErrCtrFinalized
}
ctr.config.ExitCommand = append(exitCommand, ctr.ID())
ctr.config.ExitCommand = exitCommand
ctr.config.ExitCommand = append(ctr.config.ExitCommand, ctr.ID())
return nil
}
}

View file

@ -180,12 +180,13 @@ func getLockManager(runtime *Runtime) (lock.Manager, error) {
// Set up the lock manager
manager, err = lock.OpenSHMLockManager(lockPath, runtime.config.NumLocks)
if err != nil {
if os.IsNotExist(errors.Cause(err)) {
switch {
case os.IsNotExist(errors.Cause(err)):
manager, err = lock.NewSHMLockManager(lockPath, runtime.config.NumLocks)
if err != nil {
return nil, errors.Wrapf(err, "failed to get new shm lock manager")
}
} else if errors.Cause(err) == syscall.ERANGE && runtime.doRenumber {
case errors.Cause(err) == syscall.ERANGE && runtime.doRenumber:
logrus.Debugf("Number of locks does not match - removing old locks")
// ERANGE indicates a lock numbering mismatch.
@ -199,7 +200,7 @@ func getLockManager(runtime *Runtime) (lock.Manager, error) {
if err != nil {
return nil, err
}
} else {
default:
return nil, err
}
}
@ -289,11 +290,9 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (err error) {
logrus.Debug("Not configuring container store")
} else if runtime.noStore {
logrus.Debug("No store required. Not opening container store.")
} else {
if err := runtime.configureStore(); err != nil {
} else if err := runtime.configureStore(); err != nil {
return err
}
}
defer func() {
if err != nil && store != nil {
// Don't forcibly shut down
@ -718,19 +717,15 @@ func (r *Runtime) generateName() (string, error) {
// Make sure container with this name does not exist
if _, err := r.state.LookupContainer(name); err == nil {
continue
} else {
if errors.Cause(err) != define.ErrNoSuchCtr {
} else if errors.Cause(err) != define.ErrNoSuchCtr {
return "", err
}
}
// Make sure pod with this name does not exist
if _, err := r.state.LookupPod(name); err == nil {
continue
} else {
if errors.Cause(err) != define.ErrNoSuchPod {
} else if errors.Cause(err) != define.ErrNoSuchPod {
return "", err
}
}
return name, nil
}
// The code should never reach here.

View file

@ -107,8 +107,7 @@ func (r *Runtime) removeStorageContainer(idOrName string, force bool) error {
if timesMounted > 0 {
return errors.Wrapf(define.ErrCtrStateInvalid, "container %q is mounted and cannot be removed without using force", idOrName)
}
} else {
if _, err := r.store.Unmount(ctr.ID, true); err != nil {
} else if _, err := r.store.Unmount(ctr.ID, true); err != nil {
if errors.Cause(err) == storage.ErrContainerUnknown {
// Container again gone, no error
logrus.Warnf("Storage for container %s already removed", ctr.ID)
@ -116,7 +115,6 @@ func (r *Runtime) removeStorageContainer(idOrName string, force bool) error {
}
return errors.Wrapf(err, "error unmounting container %q", idOrName)
}
}
if err := r.store.DeleteContainer(ctr.ID); err != nil {
if errors.Cause(err) == storage.ErrContainerUnknown {

View file

@ -234,15 +234,16 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai
}
case define.SystemdCgroupsManager:
if ctr.config.CgroupParent == "" {
if pod != nil && pod.config.UsePodCgroup {
switch {
case pod != nil && pod.config.UsePodCgroup:
podCgroup, err := pod.CgroupPath()
if err != nil {
return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID())
}
ctr.config.CgroupParent = podCgroup
} else if rootless.IsRootless() {
case rootless.IsRootless():
ctr.config.CgroupParent = SystemdDefaultRootlessCgroupParent
} else {
default:
ctr.config.CgroupParent = SystemdDefaultCgroupParent
}
} else if len(ctr.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(ctr.config.CgroupParent), ".slice") {
@ -361,11 +362,9 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai
if err := r.state.AddContainerToPod(pod, ctr); err != nil {
return nil, err
}
} else {
if err := r.state.AddContainer(ctr); err != nil {
} else if err := r.state.AddContainer(ctr); err != nil {
return nil, err
}
}
ctr.newContainerEvent(events.Create)
return ctr, nil
}

View file

@ -19,7 +19,7 @@ import (
)
// NewPod makes a new, empty pod
func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Pod, Err error) {
func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Pod, deferredErr error) {
r.lock.Lock()
defer r.lock.Unlock()
@ -65,7 +65,7 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
pod.config.LockID = pod.lock.ID()
defer func() {
if Err != nil {
if deferredErr != nil {
if err := pod.lock.Free(); err != nil {
logrus.Errorf("Error freeing pod lock after failed creation: %v", err)
}
@ -126,7 +126,7 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
return nil, errors.Wrapf(err, "error adding pod to state")
}
defer func() {
if Err != nil {
if deferredErr != nil {
if err := r.removePod(ctx, pod, true, true); err != nil {
logrus.Errorf("Error removing pod after pause container creation failure: %v", err)
}

View file

@ -28,7 +28,7 @@ func (r *Runtime) NewVolume(ctx context.Context, options ...VolumeCreateOption)
}
// newVolume creates a new empty volume
func (r *Runtime) newVolume(ctx context.Context, options ...VolumeCreateOption) (_ *Volume, Err error) {
func (r *Runtime) newVolume(ctx context.Context, options ...VolumeCreateOption) (_ *Volume, deferredErr error) {
volume, err := newVolume(r)
if err != nil {
return nil, errors.Wrapf(err, "error creating volume")
@ -98,7 +98,7 @@ func (r *Runtime) newVolume(ctx context.Context, options ...VolumeCreateOption)
volume.config.LockID = volume.lock.ID()
defer func() {
if Err != nil {
if deferredErr != nil {
if err := volume.lock.Free(); err != nil {
logrus.Errorf("Error freeing volume lock after failed creation: %v", err)
}

View file

@ -39,7 +39,7 @@ func (v *Volume) mount() error {
// If the count is non-zero, the volume is already mounted.
// Nothing to do.
if v.state.MountCount > 0 {
v.state.MountCount = v.state.MountCount + 1
v.state.MountCount += 1
logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount)
return v.save()
}
@ -81,7 +81,7 @@ func (v *Volume) mount() error {
logrus.Debugf("Mounted volume %s", v.Name())
// Increment the mount counter
v.state.MountCount = v.state.MountCount + 1
v.state.MountCount += 1
logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount)
return v.save()
}
@ -124,7 +124,7 @@ func (v *Volume) unmount(force bool) error {
}
if !force {
v.state.MountCount = v.state.MountCount - 1
v.state.MountCount -= 1
} else {
v.state.MountCount = 0
}

View file

@ -609,11 +609,12 @@ func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues)
return state == define.ContainerStateExited
})
if c.Import != "" {
switch {
case c.Import != "":
containers, err = crImportCheckpoint(ctx, r.Runtime, c.Import, c.Name)
} else if c.All {
case c.All:
containers, err = r.GetContainers(filterFuncs...)
} else {
default:
containers, err = shortcuts.GetContainersByContext(false, c.Latest, c.InputArgs, r.Runtime)
}
if err != nil {
@ -835,25 +836,26 @@ func (r *LocalRuntime) Restart(ctx context.Context, c *cliconfig.RestartValues)
inputTimeout := c.Timeout
// Handle --latest
if c.Latest {
switch {
case c.Latest:
lastCtr, err := r.Runtime.GetLatestContainer()
if err != nil {
return nil, nil, errors.Wrapf(err, "unable to get latest container")
}
restartContainers = append(restartContainers, lastCtr)
} else if c.Running {
case c.Running:
containers, err = r.GetRunningContainers()
if err != nil {
return nil, nil, err
}
restartContainers = append(restartContainers, containers...)
} else if c.All {
case c.All:
containers, err = r.Runtime.GetAllContainers()
if err != nil {
return nil, nil, err
}
restartContainers = append(restartContainers, containers...)
} else {
default:
for _, id := range c.InputArgs {
ctr, err := r.Runtime.LookupContainer(id)
if err != nil {

View file

@ -407,7 +407,8 @@ func (r *LocalRuntime) Events(c *cliconfig.EventValues) error {
}
w := bufio.NewWriter(os.Stdout)
for event := range eventChannel {
if c.Format == formats.JSONString {
switch {
case c.Format == formats.JSONString:
jsonStr, err := event.ToJSONString()
if err != nil {
return errors.Wrapf(err, "unable to format json")
@ -415,11 +416,11 @@ func (r *LocalRuntime) Events(c *cliconfig.EventValues) error {
if _, err := w.Write([]byte(jsonStr)); err != nil {
return err
}
} else if len(c.Format) > 0 {
case len(c.Format) > 0:
if err := tmpl.Execute(w, event); err != nil {
return err
}
} else {
default:
if _, err := w.Write([]byte(event.ToHumanReadable())); err != nil {
return err
}

View file

@ -42,12 +42,13 @@ func GetContainersByContext(all, latest bool, names []string, runtime *libpod.Ru
var ctr *libpod.Container
ctrs = []*libpod.Container{}
if all {
switch {
case all:
ctrs, err = runtime.GetAllContainers()
} else if latest {
case latest:
ctr, err = runtime.GetLatestContainer()
ctrs = append(ctrs, ctr)
} else {
default:
for _, n := range names {
ctr, e := runtime.LookupContainer(n)
if e != nil {

View file

@ -12,19 +12,19 @@ import (
// WriteResponse encodes the given value as JSON or string and renders it for http client
func WriteResponse(w http.ResponseWriter, code int, value interface{}) {
switch value.(type) {
switch v := value.(type) {
case string:
w.Header().Set("Content-Type", "text/plain; charset=us-ascii")
w.WriteHeader(code)
if _, err := fmt.Fprintln(w, value); err != nil {
if _, err := fmt.Fprintln(w, v); err != nil {
log.Errorf("unable to send string response: %q", err)
}
case *os.File:
w.Header().Set("Content-Type", "application/octet; charset=us-ascii")
w.WriteHeader(code)
if _, err := io.Copy(w, value.(*os.File)); err != nil {
if _, err := io.Copy(w, v); err != nil {
log.Errorf("unable to copy to response: %q", err)
}
default:

View file

@ -155,7 +155,7 @@ func (c *CgroupControl) getCgroupv1Path(name string) string {
}
// createCgroupv2Path creates the cgroupv2 path and enables all the available controllers
func createCgroupv2Path(path string) (Err error) {
func createCgroupv2Path(path string) (deferredError error) {
content, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers")
if err != nil {
return errors.Wrapf(err, "read /sys/fs/cgroup/cgroup.controllers")
@ -169,7 +169,7 @@ func createCgroupv2Path(path string) (Err error) {
if i == 0 {
res = fmt.Sprintf("+%s", c)
} else {
res = res + fmt.Sprintf(" +%s", c)
res += fmt.Sprintf(" +%s", c)
}
}
resByte := []byte(res)
@ -186,7 +186,7 @@ func createCgroupv2Path(path string) (Err error) {
} else {
// If the directory was created, be sure it is not left around on errors.
defer func() {
if Err != nil {
if deferredError != nil {
os.Remove(current)
}
}()

View file

@ -44,7 +44,8 @@ func (c *NetworkConfig) ToCreateOptions(runtime *libpod.Runtime, userns *UserCon
}
}
if c.NetMode.IsNS() {
switch {
case c.NetMode.IsNS():
ns := c.NetMode.NS()
if ns == "" {
return nil, errors.Errorf("invalid empty user-defined network namespace")
@ -53,13 +54,13 @@ func (c *NetworkConfig) ToCreateOptions(runtime *libpod.Runtime, userns *UserCon
if err != nil {
return nil, err
}
} else if c.NetMode.IsContainer() {
case c.NetMode.IsContainer():
connectedCtr, err := runtime.LookupContainer(c.NetMode.Container())
if err != nil {
return nil, errors.Wrapf(err, "container %q not found", c.NetMode.Container())
}
options = append(options, libpod.WithNetNSFrom(connectedCtr))
} else if !c.NetMode.IsHost() && !c.NetMode.IsNone() {
case !c.NetMode.IsHost() && !c.NetMode.IsNone():
postConfigureNetNS := userns.getPostConfigureNetNS()
options = append(options, libpod.WithNetNS(portBindings, postConfigureNetNS, string(c.NetMode), networks))
}
@ -102,29 +103,31 @@ func (c *NetworkConfig) ToCreateOptions(runtime *libpod.Runtime, userns *UserCon
// state of the NetworkConfig.
func (c *NetworkConfig) ConfigureGenerator(g *generate.Generator) error {
netMode := c.NetMode
if netMode.IsHost() {
netCtr := netMode.Container()
switch {
case netMode.IsHost():
logrus.Debug("Using host netmode")
if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil {
return err
}
} else if netMode.IsNone() {
case netMode.IsNone():
logrus.Debug("Using none netmode")
} else if netMode.IsBridge() {
case netMode.IsBridge():
logrus.Debug("Using bridge netmode")
} else if netCtr := netMode.Container(); netCtr != "" {
case netCtr != "":
logrus.Debugf("using container %s netmode", netCtr)
} else if IsNS(string(netMode)) {
case IsNS(string(netMode)):
logrus.Debug("Using ns netmode")
if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), NS(string(netMode))); err != nil {
return err
}
} else if IsPod(string(netMode)) {
case IsPod(string(netMode)):
logrus.Debug("Using pod netmode, unless pod is not sharing")
} else if netMode.IsSlirp4netns() {
case netMode.IsSlirp4netns():
logrus.Debug("Using slirp4netns netmode")
} else if netMode.IsUserDefined() {
case netMode.IsUserDefined():
logrus.Debug("Using user defined netmode")
} else {
default:
return errors.Errorf("unknown network mode")
}
@ -220,7 +223,8 @@ func (c *CgroupConfig) ToCreateOptions(runtime *libpod.Runtime) ([]libpod.CtrCre
// ToCreateOptions converts the input to container create options.
func (c *UserConfig) ToCreateOptions(runtime *libpod.Runtime) ([]libpod.CtrCreateOption, error) {
options := make([]libpod.CtrCreateOption, 0)
if c.UsernsMode.IsNS() {
switch {
case c.UsernsMode.IsNS():
ns := c.UsernsMode.NS()
if ns == "" {
return nil, errors.Errorf("invalid empty user-defined user namespace")
@ -230,13 +234,13 @@ func (c *UserConfig) ToCreateOptions(runtime *libpod.Runtime) ([]libpod.CtrCreat
return nil, err
}
options = append(options, libpod.WithIDMappings(*c.IDMappings))
} else if c.UsernsMode.IsContainer() {
case c.UsernsMode.IsContainer():
connectedCtr, err := runtime.LookupContainer(c.UsernsMode.Container())
if err != nil {
return nil, errors.Wrapf(err, "container %q not found", c.UsernsMode.Container())
}
options = append(options, libpod.WithUserNSFrom(connectedCtr))
} else {
default:
options = append(options, libpod.WithIDMappings(*c.IDMappings))
}
@ -413,20 +417,22 @@ func (c *UtsConfig) ToCreateOptions(runtime *libpod.Runtime, pod *libpod.Pod) ([
// of the UtsConfig.
func (c *UtsConfig) ConfigureGenerator(g *generate.Generator, net *NetworkConfig, runtime *libpod.Runtime) error {
hostname := c.Hostname
utsCtrID := c.UtsMode.Container()
var err error
if hostname == "" {
if utsCtrID := c.UtsMode.Container(); utsCtrID != "" {
switch {
case utsCtrID != "":
utsCtr, err := runtime.GetContainer(utsCtrID)
if err != nil {
return errors.Wrapf(err, "unable to retrieve hostname from dependency container %s", utsCtrID)
}
hostname = utsCtr.Hostname()
} else if net.NetMode.IsHost() || c.UtsMode.IsHost() {
case net.NetMode.IsHost() || c.UtsMode.IsHost():
hostname, err = os.Hostname()
if err != nil {
return errors.Wrap(err, "unable to retrieve hostname of the host")
}
} else {
default:
logrus.Debug("No hostname set; container's hostname will default to runtime default")
}
}

View file

@ -409,9 +409,10 @@ func getBindMount(args []string) (spec.Mount, error) {
// ro=[true|false]
// rw
// rw=[true|false]
if len(kv) == 1 {
switch len(kv) {
case 1:
newMount.Options = append(newMount.Options, kv[0])
} else if len(kv) == 2 {
case 2:
switch strings.ToLower(kv[1]) {
case "true":
newMount.Options = append(newMount.Options, kv[0])
@ -424,7 +425,7 @@ func getBindMount(args []string) (spec.Mount, error) {
default:
return newMount, errors.Wrapf(optionArgError, "%s must be set to true or false, instead received %q", kv[0], kv[1])
}
} else {
default:
return newMount, errors.Wrapf(optionArgError, "badly formatted option %q", val)
}
case "nosuid", "suid":

View file

@ -34,7 +34,7 @@ func GetTimestamp(value string, reference time.Time) (string, error) {
// if the string has a Z or a + or three dashes use parse otherwise use parseinlocation
parseInLocation := !(strings.ContainsAny(value, "zZ+") || strings.Count(value, "-") == 3)
if strings.Contains(value, ".") {
if strings.Contains(value, ".") { // nolint(gocritic)
if parseInLocation {
format = rFC3339NanoLocal
} else {

View file

@ -321,14 +321,14 @@ func ParseSignal(rawSignal string) (syscall.Signal, error) {
}
// ParseIDMapping takes idmappings and subuid and subgid maps and returns a storage mapping
func ParseIDMapping(mode namespaces.UsernsMode, UIDMapSlice, GIDMapSlice []string, subUIDMap, subGIDMap string) (*storage.IDMappingOptions, error) {
func ParseIDMapping(mode namespaces.UsernsMode, uidMapSlice, gidMapSlice []string, subUIDMap, subGIDMap string) (*storage.IDMappingOptions, error) {
options := storage.IDMappingOptions{
HostUIDMapping: true,
HostGIDMapping: true,
}
if mode.IsKeepID() {
if len(UIDMapSlice) > 0 || len(GIDMapSlice) > 0 {
if len(uidMapSlice) > 0 || len(gidMapSlice) > 0 {
return nil, errors.New("cannot specify custom mappings with --userns=keep-id")
}
if len(subUIDMap) > 0 || len(subGIDMap) > 0 {
@ -384,17 +384,17 @@ func ParseIDMapping(mode namespaces.UsernsMode, UIDMapSlice, GIDMapSlice []strin
if subUIDMap == "" && subGIDMap != "" {
subUIDMap = subGIDMap
}
if len(GIDMapSlice) == 0 && len(UIDMapSlice) != 0 {
GIDMapSlice = UIDMapSlice
if len(gidMapSlice) == 0 && len(uidMapSlice) != 0 {
gidMapSlice = uidMapSlice
}
if len(UIDMapSlice) == 0 && len(GIDMapSlice) != 0 {
UIDMapSlice = GIDMapSlice
if len(uidMapSlice) == 0 && len(gidMapSlice) != 0 {
uidMapSlice = gidMapSlice
}
if len(UIDMapSlice) == 0 && subUIDMap == "" && os.Getuid() != 0 {
UIDMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getuid())}
if len(uidMapSlice) == 0 && subUIDMap == "" && os.Getuid() != 0 {
uidMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getuid())}
}
if len(GIDMapSlice) == 0 && subGIDMap == "" && os.Getuid() != 0 {
GIDMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getgid())}
if len(gidMapSlice) == 0 && subGIDMap == "" && os.Getuid() != 0 {
gidMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getgid())}
}
if subUIDMap != "" && subGIDMap != "" {
@ -405,11 +405,11 @@ func ParseIDMapping(mode namespaces.UsernsMode, UIDMapSlice, GIDMapSlice []strin
options.UIDMap = mappings.UIDs()
options.GIDMap = mappings.GIDs()
}
parsedUIDMap, err := idtools.ParseIDMap(UIDMapSlice, "UID")
parsedUIDMap, err := idtools.ParseIDMap(uidMapSlice, "UID")
if err != nil {
return nil, err
}
parsedGIDMap, err := idtools.ParseIDMap(GIDMapSlice, "GID")
parsedGIDMap, err := idtools.ParseIDMap(gidMapSlice, "GID")
if err != nil {
return nil, err
}

View file

@ -1,10 +0,0 @@
language: go
go_import_path: github.com/pkg/profile
go:
- 1.12.x
- 1.13.x
- tip
script:
- go test github.com/pkg/profile
- go test -race github.com/pkg/profile

View file

@ -1 +0,0 @@
Dave Cheney <dave@cheney.net>

View file

@ -1,24 +0,0 @@
Copyright (c) 2013 Dave Cheney. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,54 +0,0 @@
profile
=======
Simple profiling support package for Go
[![Build Status](https://travis-ci.org/pkg/profile.svg?branch=master)](https://travis-ci.org/pkg/profile) [![GoDoc](http://godoc.org/github.com/pkg/profile?status.svg)](http://godoc.org/github.com/pkg/profile)
installation
------------
go get github.com/pkg/profile
usage
-----
Enabling profiling in your application is as simple as one line at the top of your main function
```go
import "github.com/pkg/profile"
func main() {
defer profile.Start().Stop()
...
}
```
options
-------
What to profile is controlled by config value passed to profile.Start.
By default CPU profiling is enabled.
```go
import "github.com/pkg/profile"
func main() {
// p.Stop() must be called before the program exits to
// ensure profiling information is written to disk.
p := profile.Start(profile.MemProfile, profile.ProfilePath("."), profile.NoShutdownHook)
...
}
```
Several convenience package level values are provided for cpu, memory, and block (contention) profiling.
For more complex options, consult the [documentation](http://godoc.org/github.com/pkg/profile).
contributing
------------
We welcome pull requests, bug fixes and issue reports.
Before proposing a change, please discuss it first by raising an issue.

View file

@ -1,3 +0,0 @@
module github.com/pkg/profile
go 1.12

View file

@ -1,284 +0,0 @@
// Package profile provides a simple way to manage runtime/pprof
// profiling of your Go application.
package profile
import (
"io/ioutil"
"log"
"os"
"os/signal"
"path/filepath"
"runtime"
"runtime/pprof"
"runtime/trace"
"sync/atomic"
)
const (
cpuMode = iota
memMode
mutexMode
blockMode
traceMode
threadCreateMode
goroutineMode
)
// Profile represents an active profiling session.
type Profile struct {
// quiet suppresses informational messages during profiling.
quiet bool
// noShutdownHook controls whether the profiling package should
// hook SIGINT to write profiles cleanly.
noShutdownHook bool
// mode holds the type of profiling that will be made
mode int
// path holds the base path where various profiling files are written.
// If blank, the base path will be generated by ioutil.TempDir.
path string
// memProfileRate holds the rate for the memory profile.
memProfileRate int
// closer holds a cleanup function that run after each profile
closer func()
// stopped records if a call to profile.Stop has been made
stopped uint32
}
// NoShutdownHook controls whether the profiling package should
// hook SIGINT to write profiles cleanly.
// Programs with more sophisticated signal handling should set
// this to true and ensure the Stop() function returned from Start()
// is called during shutdown.
func NoShutdownHook(p *Profile) { p.noShutdownHook = true }
// Quiet suppresses informational messages during profiling.
func Quiet(p *Profile) { p.quiet = true }
// CPUProfile enables cpu profiling.
// It disables any previous profiling settings.
func CPUProfile(p *Profile) { p.mode = cpuMode }
// DefaultMemProfileRate is the default memory profiling rate.
// See also http://golang.org/pkg/runtime/#pkg-variables
const DefaultMemProfileRate = 4096
// MemProfile enables memory profiling.
// It disables any previous profiling settings.
func MemProfile(p *Profile) {
p.memProfileRate = DefaultMemProfileRate
p.mode = memMode
}
// MemProfileRate enables memory profiling at the preferred rate.
// It disables any previous profiling settings.
func MemProfileRate(rate int) func(*Profile) {
return func(p *Profile) {
p.memProfileRate = rate
p.mode = memMode
}
}
// MutexProfile enables mutex profiling.
// It disables any previous profiling settings.
func MutexProfile(p *Profile) { p.mode = mutexMode }
// BlockProfile enables block (contention) profiling.
// It disables any previous profiling settings.
func BlockProfile(p *Profile) { p.mode = blockMode }
// Trace profile enables execution tracing.
// It disables any previous profiling settings.
func TraceProfile(p *Profile) { p.mode = traceMode }
// ThreadcreationProfile enables thread creation profiling..
// It disables any previous profiling settings.
func ThreadcreationProfile(p *Profile) { p.mode = threadCreateMode }
// GoroutineProfile enables goroutine profiling.
// It disables any previous profiling settings.
func GoroutineProfile(p *Profile) { p.mode = goroutineMode }
// ProfilePath controls the base path where various profiling
// files are written. If blank, the base path will be generated
// by ioutil.TempDir.
func ProfilePath(path string) func(*Profile) {
return func(p *Profile) {
p.path = path
}
}
// Stop stops the profile and flushes any unwritten data.
func (p *Profile) Stop() {
if !atomic.CompareAndSwapUint32(&p.stopped, 0, 1) {
// someone has already called close
return
}
p.closer()
atomic.StoreUint32(&started, 0)
}
// started is non zero if a profile is running.
var started uint32
// Start starts a new profiling session.
// The caller should call the Stop method on the value returned
// to cleanly stop profiling.
func Start(options ...func(*Profile)) interface {
Stop()
} {
if !atomic.CompareAndSwapUint32(&started, 0, 1) {
log.Fatal("profile: Start() already called")
}
var prof Profile
for _, option := range options {
option(&prof)
}
path, err := func() (string, error) {
if p := prof.path; p != "" {
return p, os.MkdirAll(p, 0777)
}
return ioutil.TempDir("", "profile")
}()
if err != nil {
log.Fatalf("profile: could not create initial output directory: %v", err)
}
logf := func(format string, args ...interface{}) {
if !prof.quiet {
log.Printf(format, args...)
}
}
switch prof.mode {
case cpuMode:
fn := filepath.Join(path, "cpu.pprof")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create cpu profile %q: %v", fn, err)
}
logf("profile: cpu profiling enabled, %s", fn)
pprof.StartCPUProfile(f)
prof.closer = func() {
pprof.StopCPUProfile()
f.Close()
logf("profile: cpu profiling disabled, %s", fn)
}
case memMode:
fn := filepath.Join(path, "mem.pprof")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create memory profile %q: %v", fn, err)
}
old := runtime.MemProfileRate
runtime.MemProfileRate = prof.memProfileRate
logf("profile: memory profiling enabled (rate %d), %s", runtime.MemProfileRate, fn)
prof.closer = func() {
pprof.Lookup("heap").WriteTo(f, 0)
f.Close()
runtime.MemProfileRate = old
logf("profile: memory profiling disabled, %s", fn)
}
case mutexMode:
fn := filepath.Join(path, "mutex.pprof")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create mutex profile %q: %v", fn, err)
}
runtime.SetMutexProfileFraction(1)
logf("profile: mutex profiling enabled, %s", fn)
prof.closer = func() {
if mp := pprof.Lookup("mutex"); mp != nil {
mp.WriteTo(f, 0)
}
f.Close()
runtime.SetMutexProfileFraction(0)
logf("profile: mutex profiling disabled, %s", fn)
}
case blockMode:
fn := filepath.Join(path, "block.pprof")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create block profile %q: %v", fn, err)
}
runtime.SetBlockProfileRate(1)
logf("profile: block profiling enabled, %s", fn)
prof.closer = func() {
pprof.Lookup("block").WriteTo(f, 0)
f.Close()
runtime.SetBlockProfileRate(0)
logf("profile: block profiling disabled, %s", fn)
}
case threadCreateMode:
fn := filepath.Join(path, "threadcreation.pprof")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create thread creation profile %q: %v", fn, err)
}
logf("profile: thread creation profiling enabled, %s", fn)
prof.closer = func() {
if mp := pprof.Lookup("threadcreate"); mp != nil {
mp.WriteTo(f, 0)
}
f.Close()
logf("profile: thread creation profiling disabled, %s", fn)
}
case traceMode:
fn := filepath.Join(path, "trace.out")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create trace output file %q: %v", fn, err)
}
if err := trace.Start(f); err != nil {
log.Fatalf("profile: could not start trace: %v", err)
}
logf("profile: trace enabled, %s", fn)
prof.closer = func() {
trace.Stop()
logf("profile: trace disabled, %s", fn)
}
case goroutineMode:
fn := filepath.Join(path, "goroutine.pprof")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create goroutine profile %q: %v", fn, err)
}
logf("profile: goroutine profiling enabled, %s", fn)
prof.closer = func() {
if mp := pprof.Lookup("goroutine"); mp != nil {
mp.WriteTo(f, 0)
}
f.Close()
logf("profile: goroutine profiling disabled, %s", fn)
}
}
if !prof.noShutdownHook {
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
log.Println("profile: caught interrupt, stopping profiles")
prof.Stop()
os.Exit(0)
}()
}
return &prof
}

2
vendor/modules.txt vendored
View file

@ -423,8 +423,6 @@ github.com/ostreedev/ostree-go/pkg/glibobject
github.com/ostreedev/ostree-go/pkg/otbuiltin
# github.com/pkg/errors v0.8.1
github.com/pkg/errors
# github.com/pkg/profile v1.4.0
github.com/pkg/profile
# github.com/pmezard/go-difflib v1.0.0
github.com/pmezard/go-difflib/difflib
# github.com/pquerna/ffjson v0.0.0-20190813045741-dac163c6c0a9