diff --git a/lib/ops/opsservice/utils.go b/lib/ops/opsservice/utils.go index 1053007058..c020e0053f 100644 --- a/lib/ops/opsservice/utils.go +++ b/lib/ops/opsservice/utils.go @@ -145,11 +145,14 @@ func newMount(m schema.Volume) storage.Mount { // chownExpr generates chown expression in the form used by chown command // based on uid and gid parameters func chownExpr(uid, gid *int) string { + // When both uid and gid are specified, the syntax is "chown : " if uid != nil && gid != nil { return fmt.Sprintf("%v:%v", *uid, *gid) } + // When only uid is specified, the syntax is "chown " if uid != nil { - return fmt.Sprintf("%v:", *uid) + return fmt.Sprintf("%v", *uid) } + // When only gid is specified, the syntax is "chown : " return fmt.Sprintf(":%v", *gid) } diff --git a/lib/ops/opsservice/utils_test.go b/lib/ops/opsservice/utils_test.go new file mode 100644 index 0000000000..4393b7f107 --- /dev/null +++ b/lib/ops/opsservice/utils_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2020 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package opsservice + +import ( + "github.com/gravitational/gravity/lib/utils" + + "gopkg.in/check.v1" +) + +type UtilsSuite struct { +} + +var _ = check.Suite(&UtilsSuite{}) + +func (s *UtilsSuite) TestChownExpr(c *check.C) { + tests := []struct { + uid *int + gid *int + result string + comment string + }{ + { + uid: utils.IntPtr(1000), + result: "1000", + comment: "only uid is specified", + }, + { + gid: utils.IntPtr(2000), + result: ":2000", + comment: "only gid is specified", + }, + { + uid: utils.IntPtr(1000), + gid: utils.IntPtr(2000), + result: "1000:2000", + comment: "both uid and gid are specified", + }, + } + for _, t := range tests { + c.Assert(chownExpr(t.uid, t.gid), check.Equals, t.result, + check.Commentf(t.comment)) + } +} diff --git a/lib/storage/utils.go b/lib/storage/utils.go index 0779901961..32229a93f8 100644 --- a/lib/storage/utils.go +++ b/lib/storage/utils.go @@ -250,23 +250,37 @@ func DisableAccess(backend Backend, name string, delay time.Duration) error { Type: teleservices.UserCA, DomainName: name, }, true) - if err != nil { + if err != nil && !trace.IsNotFound(err) { return trace.Wrap(err) } - ca.SetTTL(backend, delay) - if err := backend.UpsertCertAuthority(ca); err != nil { - return trace.Wrap(err) + // User authority may have already been deleted if one of the calls below + // failed and this is being retried. + if trace.IsNotFound(err) { + log.WithField("name", name).Warn("User authority not found.") + } + if ca != nil { + ca.SetTTL(backend, delay) + if err := backend.UpsertCertAuthority(ca); err != nil { + return trace.Wrap(err) + } } ca, err = backend.GetCertAuthority(teleservices.CertAuthID{ Type: teleservices.HostCA, DomainName: name, }, true) - if err != nil { + if err != nil && !trace.IsNotFound(err) { return trace.Wrap(err) } - ca.SetTTL(backend, delay) - if err := backend.UpsertCertAuthority(ca); err != nil { - return trace.Wrap(err) + // Host authority may have already been deleted if one of the calls below + // failed and this is being retried. + if trace.IsNotFound(err) { + log.WithField("name", name).Warn("Host authority not found.") + } + if ca != nil { + ca.SetTTL(backend, delay) + if err := backend.UpsertCertAuthority(ca); err != nil { + return trace.Wrap(err) + } } cluster, err := backend.GetTrustedCluster(name) if err != nil {