diff options
99 files changed, 925 insertions, 578 deletions
diff --git a/.gitlab/issue_templates/Team Member Onboarding.md b/.gitlab/issue_templates/Team Member Onboarding.md index 165e97818..04ee9a4cf 100644 --- a/.gitlab/issue_templates/Team Member Onboarding.md +++ b/.gitlab/issue_templates/Team Member Onboarding.md @@ -27,6 +27,8 @@ Please complete all but the "Reading material" section in your first few working - [ ] update your [Team page entry](https://about.gitlab.com/handbook/git-page-update/#12-add-yourself-to-the-team-page) - [ ] update your Slack profile ("What I do") - [ ] update your Zoom title +- Integrate Your PTO with the Gitaly Team Calendar + - [ ] [follow these instructions](https://about.gitlab.com/handbook/people-group/engineering/team-pto-calendar/#steps), and use `gitlab.com_mc911ncuk38bfngud133tjb4m8@group.calendar.google.com` as the Calendar ID. - Reading material - [ ] check out the [README](https://gitlab.com/gitlab-org/gitaly/-/blob/master/README.md) at https://gitlab.com/gitlab-org/gitaly, without getting lost in too much detail - [ ] watch video [presentations](https://gitlab.com/gitlab-org/gitaly/-/blob/master/README.md#presentations) linked in README @@ -1 +1 @@ -15.9.0-rc2
\ No newline at end of file +15.9.0-rc3
\ No newline at end of file diff --git a/cmd/gitaly-wrapper/main_test.go b/cmd/gitaly-wrapper/main_test.go index 5a78f90a1..9eb53340d 100644 --- a/cmd/gitaly-wrapper/main_test.go +++ b/cmd/gitaly-wrapper/main_test.go @@ -16,6 +16,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/bootstrap" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) @@ -69,7 +70,7 @@ func TestFindProcess(t *testing.T) { t.Parallel() path := filepath.Join(testhelper.TempDir(t), "pid") - require.NoError(t, os.WriteFile(path, []byte("garbage"), 0o644)) + require.NoError(t, os.WriteFile(path, []byte("garbage"), perm.SharedFile)) _, err := findProcess(path) _, expectedErr := strconv.Atoi("garbage") @@ -82,7 +83,7 @@ func TestFindProcess(t *testing.T) { // The below PID can exist, but chances are sufficiently low to hopefully not matter // in practice. path := filepath.Join(testhelper.TempDir(t), "pid") - require.NoError(t, os.WriteFile(path, []byte("7777777"), 0o644)) + require.NoError(t, os.WriteFile(path, []byte("7777777"), perm.SharedFile)) // The process isn't alive, so we expect neither an error nor a process to be // returned. @@ -117,7 +118,7 @@ func TestFindProcess(t *testing.T) { require.NoError(t, err) path := filepath.Join(testhelper.TempDir(t), "pid") - require.NoError(t, os.WriteFile(path, []byte(strconv.FormatInt(int64(cmd.Process.Pid), 10)), 0o644)) + require.NoError(t, os.WriteFile(path, []byte(strconv.FormatInt(int64(cmd.Process.Pid), 10)), perm.SharedFile)) process, err := findProcess(path) require.NotNil(t, process) @@ -175,7 +176,7 @@ func TestReadPIDFile(t *testing.T) { t.Parallel() path := filepath.Join(testhelper.TempDir(t), "pid") - require.NoError(t, os.WriteFile(path, nil, 0o644)) + require.NoError(t, os.WriteFile(path, nil, perm.SharedFile)) _, err := readPIDFile(path) _, expectedErr := strconv.Atoi("") require.Equal(t, expectedErr, err) @@ -185,7 +186,7 @@ func TestReadPIDFile(t *testing.T) { t.Parallel() path := filepath.Join(testhelper.TempDir(t), "pid") - require.NoError(t, os.WriteFile(path, []byte("invalid"), 0o644)) + require.NoError(t, os.WriteFile(path, []byte("invalid"), perm.SharedFile)) _, err := readPIDFile(path) _, expectedErr := strconv.Atoi("invalid") require.Equal(t, expectedErr, err) @@ -195,7 +196,7 @@ func TestReadPIDFile(t *testing.T) { t.Parallel() path := filepath.Join(testhelper.TempDir(t), "pid") - require.NoError(t, os.WriteFile(path, []byte("12345"), 0o644)) + require.NoError(t, os.WriteFile(path, []byte("12345"), perm.SharedFile)) pid, err := readPIDFile(path) require.NoError(t, err) require.Equal(t, 12345, pid) @@ -348,7 +349,7 @@ func TestRun(t *testing.T) { // Write the PID of the running process into the PID file. As a result, it should // get adopted by gitaly-wrapper, which means it wouldn't try to execute it anew. pidPath := filepath.Join(testhelper.TempDir(t), "pid") - require.NoError(t, os.WriteFile(pidPath, []byte(strconv.FormatInt(int64(scriptCmd.Process.Pid), 10)), 0o644)) + require.NoError(t, os.WriteFile(pidPath, []byte(strconv.FormatInt(int64(scriptCmd.Process.Pid), 10)), perm.SharedFile)) // Run gitaly-script with a binary path whose basename matches, but which ultimately // doesn't exist. This proves that it doesn't try to execute the script again. @@ -412,7 +413,7 @@ func TestRun(t *testing.T) { `)) pidPath := filepath.Join(testhelper.TempDir(t), "pid") - require.NoError(t, os.WriteFile(pidPath, []byte("12345"), 0o644)) + require.NoError(t, os.WriteFile(pidPath, []byte("12345"), perm.SharedFile)) cmd := exec.CommandContext(ctx, binary, script) cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", bootstrap.EnvPidFile, pidPath)) @@ -443,7 +444,7 @@ func TestRun(t *testing.T) { require.NoError(t, err) pidPath := filepath.Join(testhelper.TempDir(t), "pid") - require.NoError(t, os.WriteFile(pidPath, []byte(strconv.FormatInt(int64(scriptCmd.Process.Pid), 10)), 0o644)) + require.NoError(t, os.WriteFile(pidPath, []byte(strconv.FormatInt(int64(scriptCmd.Process.Pid), 10)), perm.SharedFile)) cmd := exec.CommandContext(ctx, binary, script) cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", bootstrap.EnvPidFile, pidPath)) diff --git a/cmd/gitaly/check_test.go b/cmd/gitaly/check_test.go index 19f5a3ea1..b880e5275 100644 --- a/cmd/gitaly/check_test.go +++ b/cmd/gitaly/check_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) @@ -113,7 +114,7 @@ func writeTemporaryGitalyConfigFile(tb testing.TB, cfg config.Cfg) string { contents, err := toml.Marshal(cfg) require.NoError(tb, err) - require.NoError(tb, os.WriteFile(path, contents, 0o644)) + require.NoError(tb, os.WriteFile(path, contents, perm.SharedFile)) return path } @@ -34,7 +34,7 @@ require ( github.com/pelletier/go-toml/v2 v2.0.6 github.com/prometheus/client_golang v1.14.0 github.com/prometheus/client_model v0.3.0 - github.com/rubenv/sql-migrate v1.3.0 + github.com/rubenv/sql-migrate v1.3.1 github.com/sirupsen/logrus v1.9.0 github.com/stretchr/testify v1.8.1 github.com/uber/jaeger-client-go v2.30.0+incompatible @@ -42,7 +42,7 @@ require ( go.uber.org/goleak v1.2.0 gocloud.dev v0.28.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.4.0 + golang.org/x/sys v0.5.0 golang.org/x/time v0.3.0 google.golang.org/grpc v1.52.3 google.golang.org/protobuf v1.28.1 @@ -115,7 +115,7 @@ require ( github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/go-billy/v5 v5.3.1 // indirect github.com/go-git/go-git/v5 v5.4.2 // indirect - github.com/go-gorp/gorp/v3 v3.0.2 // indirect + github.com/go-gorp/gorp/v3 v3.0.5 // indirect github.com/go-ole/go-ole v1.2.4 // indirect github.com/godbus/dbus/v5 v5.0.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -509,6 +509,7 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/a8m/expect v1.0.0/go.mod h1:4IwSCMumY49ScypDnjNbYEjgVeqy1/U2cEs3Lat96eA= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= @@ -961,8 +962,8 @@ github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gorp/gorp/v3 v3.0.2 h1:ULqJXIekoqMx29FI5ekXXFoH1dT2Vc8UhnRzBg+Emz4= -github.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmncaR6rwBY= +github.com/go-gorp/gorp/v3 v3.0.5 h1:PUjzYdYu3HBOh8LE+UUmRG2P0IRDak9XMeGNvaeq4Ow= +github.com/go-gorp/gorp/v3 v3.0.5/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -1020,8 +1021,6 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -1501,7 +1500,6 @@ github.com/leonelquinteros/gotext v1.5.0/go.mod h1:OCiUVHuhP9LGFBQ1oAmdtNCHJCiHi github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= @@ -1565,9 +1563,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= -github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= +github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -1640,6 +1637,8 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/nelsam/hel/v2 v2.3.2/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy+rL3w= +github.com/nelsam/hel/v2 v2.3.3/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy+rL3w= github.com/neurosnap/sentences v1.0.6 h1:iBVUivNtlwGkYsJblWV8GGVFmXzZzak907Ci8aA0VTE= github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -1765,8 +1764,9 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8C/OCy0zs9906d/VUru+bqg= -github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU= +github.com/poy/onpar v0.0.0-20200406201722-06f95a1c68e8/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU= +github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= +github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/alertmanager v0.24.0/go.mod h1:r6fy/D7FRuZh5YbnX6J3MBY0eI4Pb5yPYS7/bPSXXqI= @@ -1849,8 +1849,8 @@ github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rubenv/sql-migrate v1.3.0 h1:4/aYosSBTTDYKxRKdftREUV21d9hPc24mfIKZBosMsQ= -github.com/rubenv/sql-migrate v1.3.0/go.mod h1:rmTcbW9Xfv90gWPRV4stgofRrAagqmzlm6bQQzghoz0= +github.com/rubenv/sql-migrate v1.3.1 h1:Vx+n4Du8X8VTYuXbhNxdEUoh6wiJERA0GlWocR5FrbA= +github.com/rubenv/sql-migrate v1.3.1/go.mod h1:YzG/Vh82CwyhTFXy+Mf5ahAiiEOpAlHurg+23VEzcsk= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086 h1:mncRSDOqYCng7jOD+Y6+IivdRI6Kzv2BLWYkWkdQfu0= github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -1917,6 +1917,7 @@ github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155 github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= @@ -2029,8 +2030,6 @@ github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/gitlab-org/labkit v1.17.0 h1:mEkoLzXorLNdt8NkfgYS5xMDhdqCsIJaeEVtSf7d8cU= gitlab.com/gitlab-org/labkit v1.17.0/go.mod h1:nlLJvKgXcIclqWMI+rga2TckNBVHOtRCHMxBoVByNoE= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -2521,11 +2520,13 @@ golang.org/x/sys v0.0.0-20220908150016-7ac13a9a928d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2621,6 +2622,7 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200313205530-4303120df7d8/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= diff --git a/internal/backup/backup_test.go b/internal/backup/backup_test.go index 8bf225ff1..753af831e 100644 --- a/internal/backup/backup_test.go +++ b/internal/backup/backup_test.go @@ -61,7 +61,7 @@ func TestManager_Create(t *testing.T) { Seed: gittest.SeedGitLabTest, }) require.NoError(tb, os.Mkdir(filepath.Join(hooksRepoPath, "custom_hooks"), perm.PublicDir)) - require.NoError(tb, os.WriteFile(filepath.Join(hooksRepoPath, "custom_hooks/pre-commit.sample"), []byte("Some hooks"), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(hooksRepoPath, "custom_hooks/pre-commit.sample"), []byte("Some hooks"), perm.PublicFile)) return hooksRepo, hooksRepoPath }, createsBundle: true, @@ -122,11 +122,11 @@ func TestManager_Create(t *testing.T) { dirInfo, err := os.Stat(filepath.Dir(bundlePath)) require.NoError(t, err) - require.Equal(t, os.FileMode(0o700), dirInfo.Mode().Perm(), "expecting restricted directory permissions") + require.Equal(t, perm.PrivateDir, dirInfo.Mode().Perm(), "expecting restricted directory permissions") bundleInfo, err := os.Stat(bundlePath) require.NoError(t, err) - require.Equal(t, os.FileMode(0o600), bundleInfo.Mode().Perm(), "expecting restricted file permissions") + require.Equal(t, perm.PrivateFile, bundleInfo.Mode().Perm(), "expecting restricted file permissions") output := gittest.Exec(t, cfg, "-C", repoPath, "bundle", "verify", bundlePath) require.Contains(t, string(output), "The bundle records a complete history") @@ -189,10 +189,10 @@ func TestManager_Create_incremental(t *testing.T) { gittest.Exec(tb, cfg, "-C", repoPath, "bundle", "create", bundlePath, "--all") refs := gittest.Exec(tb, cfg, "-C", repoPath, "show-ref", "--head") - require.NoError(tb, os.WriteFile(refsPath, refs, os.ModePerm)) + require.NoError(tb, os.WriteFile(refsPath, refs, perm.PublicFile)) - require.NoError(tb, os.WriteFile(filepath.Join(backupRepoPath, "LATEST"), []byte(backupID), os.ModePerm)) - require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(backupRepoPath, "LATEST"), []byte(backupID), perm.PublicFile)) + require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), perm.PublicFile)) return repo, repoPath }, @@ -214,10 +214,10 @@ func TestManager_Create_incremental(t *testing.T) { gittest.Exec(tb, cfg, "-C", repoPath, "bundle", "create", bundlePath, "--all") refs := gittest.Exec(tb, cfg, "-C", repoPath, "show-ref", "--head") - require.NoError(tb, os.WriteFile(refsPath, refs, os.ModePerm)) + require.NoError(tb, os.WriteFile(refsPath, refs, perm.PublicFile)) - require.NoError(tb, os.WriteFile(filepath.Join(backupRepoPath, "LATEST"), []byte(backupID), os.ModePerm)) - require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(backupRepoPath, "LATEST"), []byte(backupID), perm.PublicFile)) + require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), perm.PublicFile)) gittest.WriteCommit(tb, cfg, repoPath, gittest.WithBranch("master")) @@ -381,8 +381,8 @@ func testManagerRestore(t *testing.T, ctx context.Context) { repoBackupPath := joinBackupPath(tb, backupRoot, repo) backupPath := filepath.Join(repoBackupPath, backupID) require.NoError(tb, os.MkdirAll(backupPath, perm.PublicDir)) - require.NoError(tb, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), os.ModePerm)) - require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), perm.PublicFile)) + require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), perm.PublicFile)) bundlePath := filepath.Join(backupPath, "001.bundle") gittest.BundleRepo(tb, cfg, repoPath, bundlePath) @@ -402,8 +402,8 @@ func testManagerRestore(t *testing.T, ctx context.Context) { repoBackupPath := joinBackupPath(tb, backupRoot, repo) backupPath := filepath.Join(repoBackupPath, backupID) require.NoError(tb, os.MkdirAll(backupPath, perm.PublicDir)) - require.NoError(tb, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), os.ModePerm)) - require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("002"), os.ModePerm)) + require.NoError(tb, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), perm.PublicFile)) + require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("002"), perm.PublicFile)) root := gittest.WriteCommit(tb, cfg, expectedRepoPath, gittest.WithBranch("master"), @@ -533,7 +533,7 @@ func TestResolveSink(t *testing.T) { "token_uri": "https://accounts.google.com/o/oauth2/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/303724477529-compute%40developer.gserviceaccount.com" -}`), 0o655)) +}`), perm.SharedFile)) for _, tc := range []struct { desc string diff --git a/internal/backup/filesystem_sink.go b/internal/backup/filesystem_sink.go index e9dad6188..f97a409e9 100644 --- a/internal/backup/filesystem_sink.go +++ b/internal/backup/filesystem_sink.go @@ -32,7 +32,7 @@ func (fs *FilesystemSink) Write(ctx context.Context, relativePath string, r io.R return fmt.Errorf("create directory structure %q: %w", dir, err) } - f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600) + f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm.PrivateFile) if err != nil { return fmt.Errorf("write file %q: %w", path, err) } diff --git a/internal/backup/filesystem_sink_test.go b/internal/backup/filesystem_sink_test.go index 7e4025851..fbb6b67b7 100644 --- a/internal/backup/filesystem_sink_test.go +++ b/internal/backup/filesystem_sink_test.go @@ -24,7 +24,7 @@ func TestFilesystemSink_GetReader(t *testing.T) { dir := testhelper.TempDir(t) const relativePath = "test.dat" - require.NoError(t, os.WriteFile(filepath.Join(dir, relativePath), []byte("test"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(dir, relativePath), []byte("test"), perm.SharedFile)) fsSink := NewFilesystemSink(dir) reader, err := fsSink.GetReader(ctx, relativePath) @@ -79,7 +79,7 @@ func TestFilesystemSink_Write(t *testing.T) { fullPath := filepath.Join(dir, relativePath) require.NoError(t, os.MkdirAll(filepath.Dir(fullPath), perm.SharedDir)) - require.NoError(t, os.WriteFile(fullPath, []byte("initial"), 0o655)) + require.NoError(t, os.WriteFile(fullPath, []byte("initial"), perm.SharedFile)) fsSink := NewFilesystemSink(dir) require.NoError(t, fsSink.Write(ctx, relativePath, strings.NewReader("test"))) @@ -96,7 +96,7 @@ func TestFilesystemSink_Write(t *testing.T) { dir := testhelper.TempDir(t) const relativePath = "nested/test.dat" - require.NoError(t, os.WriteFile(filepath.Join(dir, "nested"), []byte("lock"), os.ModePerm)) + require.NoError(t, os.WriteFile(filepath.Join(dir, "nested"), []byte("lock"), perm.PublicFile)) fsSink := NewFilesystemSink(dir) err := fsSink.Write(ctx, relativePath, strings.NewReader("test")) diff --git a/internal/backup/locator_test.go b/internal/backup/locator_test.go index fb8802b6c..4096cb135 100644 --- a/internal/backup/locator_test.go +++ b/internal/backup/locator_test.go @@ -193,8 +193,8 @@ func TestPointerLocator(t *testing.T) { require.ErrorIs(t, err, ErrDoesntExist) require.NoError(t, os.MkdirAll(filepath.Join(backupPath, repo.RelativePath, backupID), perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, "LATEST"), []byte(backupID), 0o644)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, backupID, "LATEST"), []byte("003"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, "LATEST"), []byte(backupID), perm.SharedFile)) + require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, backupID, "LATEST"), []byte("003"), perm.SharedFile)) expected := &Backup{ Steps: []Step{ { @@ -247,8 +247,8 @@ func TestPointerLocator(t *testing.T) { require.Equal(t, expectedFallback, fallbackFull) require.NoError(t, os.MkdirAll(filepath.Join(backupPath, repo.RelativePath, backupID), perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, "LATEST"), []byte(backupID), 0o644)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, backupID, "LATEST"), []byte("001"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, "LATEST"), []byte(backupID), perm.SharedFile)) + require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, backupID, "LATEST"), []byte("001"), perm.SharedFile)) expected := &Backup{ Steps: []Step{ { @@ -276,7 +276,7 @@ func TestPointerLocator(t *testing.T) { require.ErrorIs(t, err, ErrDoesntExist) require.NoError(t, os.MkdirAll(filepath.Join(backupPath, repo.RelativePath), perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, "LATEST"), []byte("invalid"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, "LATEST"), []byte("invalid"), perm.SharedFile)) _, err = l.FindLatest(ctx, repo) require.EqualError(t, err, "pointer locator: find latest: find: find latest ID: filesystem sink: get reader for \"TestPointerLocator/invalid/LATEST\": doesn't exist") }) @@ -293,8 +293,8 @@ func TestPointerLocator(t *testing.T) { require.ErrorIs(t, err, ErrDoesntExist) require.NoError(t, os.MkdirAll(filepath.Join(backupPath, repo.RelativePath, backupID), perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, "LATEST"), []byte(backupID), 0o644)) - require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, backupID, "LATEST"), []byte("invalid"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, "LATEST"), []byte(backupID), perm.SharedFile)) + require.NoError(t, os.WriteFile(filepath.Join(backupPath, repo.RelativePath, backupID, "LATEST"), []byte("invalid"), perm.SharedFile)) _, err = l.FindLatest(ctx, repo) require.EqualError(t, err, "pointer locator: find latest: find: determine increment ID: strconv.Atoi: parsing \"invalid\": invalid syntax") diff --git a/internal/bootstrap/bootstrap_test.go b/internal/bootstrap/bootstrap_test.go index 0b3eae895..61f1f0efd 100644 --- a/internal/bootstrap/bootstrap_test.go +++ b/internal/bootstrap/bootstrap_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) @@ -77,7 +78,7 @@ func TestBootstrap_unixListener(t *testing.T) { require.NoError(t, err) if tc.preexistingSocket { - require.NoError(t, os.WriteFile(socketPath, nil, 0o755)) + require.NoError(t, os.WriteFile(socketPath, nil, perm.SharedExecutable)) } listener, err := b.listen("unix", socketPath) diff --git a/internal/cache/walker_test.go b/internal/cache/walker_test.go index d587dae74..0d1722fc5 100644 --- a/internal/cache/walker_test.go +++ b/internal/cache/walker_test.go @@ -79,7 +79,7 @@ func TestDiskCacheInitialClear(t *testing.T) { canary := filepath.Join(cacheDir, "canary.txt") require.NoError(t, os.MkdirAll(filepath.Dir(canary), perm.SharedDir)) - require.NoError(t, os.WriteFile(canary, []byte("chirp chirp"), 0o755)) + require.NoError(t, os.WriteFile(canary, []byte("chirp chirp"), perm.SharedExecutable)) cache := New(cfg, locator, withDisabledWalker()) require.NoError(t, cache.StartWalkers()) @@ -116,7 +116,7 @@ func TestCleanWalkEmptyDirs(t *testing.T) { if strings.HasSuffix(tt.path, "/") { require.NoError(t, os.MkdirAll(p, perm.SharedDir)) } else { - require.NoError(t, os.WriteFile(p, nil, 0o655)) + require.NoError(t, os.WriteFile(p, nil, perm.SharedFile)) if tt.stale { require.NoError(t, os.Chtimes(p, time.Now(), time.Now().Add(-time.Hour))) } diff --git a/internal/cgroups/mock_linux_test.go b/internal/cgroups/mock_linux_test.go index 6857429c7..d54add8d0 100644 --- a/internal/cgroups/mock_linux_test.go +++ b/internal/cgroups/mock_linux_test.go @@ -101,7 +101,7 @@ func (m *mockCgroup) setupMockCgroupFiles( for filename, content := range contentByFilename { controlFilePath := filepath.Join(cgroupPath, filename) - require.NoError(t, os.WriteFile(controlFilePath, []byte(content), 0o644)) + require.NoError(t, os.WriteFile(controlFilePath, []byte(content), perm.SharedFile)) } for shard := uint(0); shard < manager.cfg.Repositories.Count; shard++ { @@ -110,7 +110,7 @@ func (m *mockCgroup) setupMockCgroupFiles( for filename, content := range contentByFilename { shardControlFilePath := filepath.Join(shardPath, filename) - require.NoError(t, os.WriteFile(shardControlFilePath, []byte(content), 0o644)) + require.NoError(t, os.WriteFile(shardControlFilePath, []byte(content), perm.SharedFile)) } } } diff --git a/internal/cgroups/v1_linux_test.go b/internal/cgroups/v1_linux_test.go index cb249f64d..7f56d87e1 100644 --- a/internal/cgroups/v1_linux_test.go +++ b/internal/cgroups/v1_linux_test.go @@ -15,6 +15,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) @@ -221,7 +222,7 @@ func readCgroupFile(t *testing.T, path string) []byte { // The cgroups package defaults to permission 0 as it expects the file to be existing (the kernel creates the file) // and its testing override the permission private variable to something sensible, hence we have to chmod ourselves // so we can read the file. - require.NoError(t, os.Chmod(path, 0o666)) + require.NoError(t, os.Chmod(path, perm.PublicFile)) return testhelper.MustReadFile(t, path) } diff --git a/internal/git/command_factory.go b/internal/git/command_factory.go index a7ceca341..e130cc630 100644 --- a/internal/git/command_factory.go +++ b/internal/git/command_factory.go @@ -1,6 +1,7 @@ package git import ( + "bytes" "context" "errors" "fmt" @@ -362,20 +363,24 @@ func (cf *ExecCommandFactory) GitVersion(ctx context.Context) (Version, error) { // Furthermore, note that we're not using `newCommand()` but instead hand-craft the command. // This is required to avoid a cyclic dependency when we need to check the version in // `newCommand()` itself. - cmd, err := command.New(ctx, []string{execEnv.BinaryPath, "version"}, command.WithEnvironment(execEnv.EnvironmentVariables)) + var versionBuffer bytes.Buffer + cmd, err := command.New(ctx, []string{execEnv.BinaryPath, "version"}, + command.WithEnvironment(execEnv.EnvironmentVariables), + command.WithStdout(&versionBuffer), + ) if err != nil { return Version{}, fmt.Errorf("spawning version command: %w", err) } - gitVersion, err := parseVersionFromCommand(cmd) - if err != nil { - return Version{}, err - } - if err := cmd.Wait(); err != nil { return Version{}, fmt.Errorf("waiting for version: %w", err) } + gitVersion, err := parseVersionOutput(versionBuffer.Bytes()) + if err != nil { + return Version{}, err + } + cf.cachedGitVersionByBinary[gitBinary] = cachedGitVersion{ version: gitVersion, stat: stat, diff --git a/internal/git/conflict/parser_test.go b/internal/git/conflict/parser_test.go index 52c308320..5b3eccff6 100644 --- a/internal/git/conflict/parser_test.go +++ b/internal/git/conflict/parser_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" ) func TestFile_Resolve(t *testing.T) { @@ -111,7 +112,7 @@ we can both agree on this line though t.Run(tt.name, func(t *testing.T) { entry := Entry{ Path: tt.path, - Mode: 0o644, + Mode: uint(perm.SharedFile), Contents: []byte("something-with-trailing-newline\n"), } diff --git a/internal/git/dirs_test.go b/internal/git/dirs_test.go index ae1d7c138..0ebe4292d 100644 --- a/internal/git/dirs_test.go +++ b/internal/git/dirs_test.go @@ -73,7 +73,7 @@ func TestObjectDirsOutsideStorage(t *testing.T) { t.Run(tc.desc, func(t *testing.T) { ctx := testhelper.Context(t) - require.NoError(t, os.WriteFile(alternatesFile, []byte(tc.alternates), 0o600)) + require.NoError(t, os.WriteFile(alternatesFile, []byte(tc.alternates), perm.PrivateFile)) out, err := ObjectDirectories(ctx, storageRoot, repoPath) require.Equal(t, expectedErr, err) require.Nil(t, out) diff --git a/internal/git/execution_environment_test.go b/internal/git/execution_environment_test.go index a4b8987c7..59aea70bd 100644 --- a/internal/git/execution_environment_test.go +++ b/internal/git/execution_environment_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) @@ -73,7 +74,7 @@ func TestBundledGitEnvironmentConstructor(t *testing.T) { seedDirWithExecutables := func(t *testing.T, executableNames ...string) string { dir := testhelper.TempDir(t) for _, executableName := range executableNames { - require.NoError(t, os.WriteFile(filepath.Join(dir, executableName), nil, 0o777)) + require.NoError(t, os.WriteFile(filepath.Join(dir, executableName), nil, perm.PublicExecutable)) } return dir } @@ -241,7 +242,7 @@ func TestFallbackGitEnvironmentConstructor(t *testing.T) { t.Run("successfully resolved executable", func(t *testing.T) { tempDir := testhelper.TempDir(t) gitPath := filepath.Join(tempDir, "git") - require.NoError(t, os.WriteFile(gitPath, nil, 0o755)) + require.NoError(t, os.WriteFile(gitPath, nil, perm.SharedExecutable)) t.Setenv("PATH", "/does/not/exist:"+tempDir) diff --git a/internal/git/gitattributes/check_attr_test.go b/internal/git/gitattributes/check_attr_test.go index b39003110..3b2a0fd01 100644 --- a/internal/git/gitattributes/check_attr_test.go +++ b/internal/git/gitattributes/check_attr_test.go @@ -139,7 +139,7 @@ func TestCheckAttrCmd_Check(t *testing.T) { }, } { t.Run(tc.desc, func(t *testing.T) { - require.NoError(t, os.WriteFile(attrPath, []byte(tc.attrContent), 0o644)) + require.NoError(t, os.WriteFile(attrPath, []byte(tc.attrContent), perm.SharedFile)) checkCmd, finish, err := CheckAttr(ctx, repo, []string{"foo", "bar"}) require.NoError(t, err) diff --git a/internal/git/gittest/http_server.go b/internal/git/gittest/http_server.go index ef3fd14fd..c69c9aa6f 100644 --- a/internal/git/gittest/http_server.go +++ b/internal/git/gittest/http_server.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) @@ -18,7 +19,7 @@ import ( // prepared such that git-http-backend(1) will serve it by creating the "git-daemon-export-ok" magic // file. func HTTPServer(tb testing.TB, ctx context.Context, gitCmdFactory git.CommandFactory, repoPath string, middleware func(http.ResponseWriter, *http.Request, http.Handler)) int { - require.NoError(tb, os.WriteFile(filepath.Join(repoPath, "git-daemon-export-ok"), nil, 0o644)) + require.NoError(tb, os.WriteFile(filepath.Join(repoPath, "git-daemon-export-ok"), nil, perm.SharedFile)) listener, err := net.Listen("tcp", "127.0.0.1:0") require.NoError(tb, err) diff --git a/internal/git/housekeeping/clean_stale_data.go b/internal/git/housekeeping/clean_stale_data.go index 4c5911643..5d896ea4f 100644 --- a/internal/git/housekeeping/clean_stale_data.go +++ b/internal/git/housekeeping/clean_stale_data.go @@ -15,6 +15,7 @@ import ( log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/safe" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "google.golang.org/grpc/codes" @@ -24,7 +25,7 @@ const ( emptyRefsGracePeriod = 24 * time.Hour deleteTempFilesOlderThanDuration = 7 * 24 * time.Hour brokenRefsGracePeriod = 24 * time.Hour - minimumDirPerm = 0o700 + minimumDirPerm = perm.PrivateDir lockfileGracePeriod = 15 * time.Minute referenceLockfileGracePeriod = 1 * time.Hour packedRefsLockGracePeriod = 1 * time.Hour diff --git a/internal/git/housekeeping/clean_stale_data_test.go b/internal/git/housekeeping/clean_stale_data_test.go index 3352764da..3a7c468d8 100644 --- a/internal/git/housekeeping/clean_stale_data_test.go +++ b/internal/git/housekeeping/clean_stale_data_test.go @@ -49,7 +49,7 @@ func (f *fileEntry) create(t *testing.T, parent string) { t.Helper() filename := filepath.Join(parent, f.name) - ff, err := os.OpenFile(filename, os.O_RDONLY|os.O_CREATE, 0o700) + ff, err := os.OpenFile(filename, os.O_RDONLY|os.O_CREATE, perm.PrivateFile) assert.NoError(t, err, "file creation failed: %v", filename) err = ff.Close() assert.NoError(t, err, "file close failed: %v", filename) @@ -185,18 +185,18 @@ func TestRepositoryManager_CleanStaleData(t *testing.T) { { name: "clean", entries: []entry{ - d("objects", 0o700, 240*time.Hour, Keep, - f("a", 0o700, 24*time.Hour, Keep), - f("b", 0o700, 24*time.Hour, Keep), - f("c", 0o700, 24*time.Hour, Keep), + d("objects", perm.PrivateDir, 240*time.Hour, Keep, + f("a", perm.PrivateFile, 24*time.Hour, Keep), + f("b", perm.PrivateFile, 24*time.Hour, Keep), + f("c", perm.PrivateFile, 24*time.Hour, Keep), ), }, }, { name: "emptyperms", entries: []entry{ - d("objects", 0o700, 240*time.Hour, Keep, - f("b", 0o700, 24*time.Hour, Keep), + d("objects", perm.PrivateDir, 240*time.Hour, Keep, + f("b", perm.PrivateFile, 24*time.Hour, Keep), f("tmp_a", 0o000, 2*time.Hour, Keep), ), }, @@ -204,18 +204,18 @@ func TestRepositoryManager_CleanStaleData(t *testing.T) { { name: "emptytempdir", entries: []entry{ - d("objects", 0o700, 240*time.Hour, Keep, + d("objects", perm.PrivateDir, 240*time.Hour, Keep, d("tmp_d", 0o000, 240*time.Hour, Keep), - f("b", 0o700, 24*time.Hour, Keep), + f("b", perm.PrivateFile, 24*time.Hour, Keep), ), }, }, { name: "oldtempfile", entries: []entry{ - d("objects", 0o700, 240*time.Hour, Keep, - f("tmp_a", 0o770, 240*time.Hour, Delete), - f("b", 0o700, 24*time.Hour, Keep), + d("objects", perm.PrivateDir, 240*time.Hour, Keep, + f("tmp_a", perm.SharedFile, 240*time.Hour, Delete), + f("b", perm.PrivateFile, 24*time.Hour, Keep), ), }, expectedMetrics: cleanStaleDataMetrics{ @@ -225,9 +225,9 @@ func TestRepositoryManager_CleanStaleData(t *testing.T) { { name: "subdir temp file", entries: []entry{ - d("objects", 0o700, 240*time.Hour, Keep, - d("a", 0o770, 240*time.Hour, Keep, - f("tmp_b", 0o700, 240*time.Hour, Delete), + d("objects", perm.PrivateDir, 240*time.Hour, Keep, + d("a", perm.GroupPrivateDir, 240*time.Hour, Keep, + f("tmp_b", perm.PrivateFile, 240*time.Hour, Delete), ), ), }, @@ -238,9 +238,9 @@ func TestRepositoryManager_CleanStaleData(t *testing.T) { { name: "inaccessible tmp directory", entries: []entry{ - d("objects", 0o700, 240*time.Hour, Keep, + d("objects", perm.PrivateDir, 240*time.Hour, Keep, d("tmp_a", 0o000, 240*time.Hour, Keep, - f("tmp_b", 0o700, 240*time.Hour, Delete), + f("tmp_b", perm.PrivateFile, 240*time.Hour, Delete), ), ), }, @@ -248,9 +248,9 @@ func TestRepositoryManager_CleanStaleData(t *testing.T) { { name: "deeply nested inaccessible tmp directory", entries: []entry{ - d("objects", 0o700, 240*time.Hour, Keep, - d("tmp_a", 0o700, 240*time.Hour, Keep, - d("tmp_a", 0o700, 24*time.Hour, Keep, + d("objects", perm.PrivateDir, 240*time.Hour, Keep, + d("tmp_a", perm.PrivateDir, 240*time.Hour, Keep, + d("tmp_a", perm.PrivateDir, 24*time.Hour, Keep, f("tmp_b", 0o000, 240*time.Hour, Delete), ), ), @@ -263,9 +263,9 @@ func TestRepositoryManager_CleanStaleData(t *testing.T) { { name: "files outside of object database", entries: []entry{ - f("tmp_a", 0o770, 240*time.Hour, Keep), - d("info", 0o700, 240*time.Hour, Keep, - f("tmp_a", 0o770, 240*time.Hour, Keep), + f("tmp_a", perm.SharedFile, 240*time.Hour, Keep), + d("info", perm.PrivateDir, 240*time.Hour, Keep, + f("tmp_a", perm.SharedFile, 240*time.Hour, Keep), ), }, }, @@ -395,7 +395,7 @@ func TestRepositoryManager_CleanStaleData_references(t *testing.T) { path := filepath.Join(repoPath, ref.name) require.NoError(t, os.MkdirAll(filepath.Dir(path), perm.SharedDir)) - require.NoError(t, os.WriteFile(path, bytes.Repeat([]byte{0}, ref.size), 0o644)) + require.NoError(t, os.WriteFile(path, bytes.Repeat([]byte{0}, ref.size), perm.SharedFile)) filetime := time.Now().Add(-ref.age) require.NoError(t, os.Chtimes(path, filetime, filetime)) } @@ -431,30 +431,30 @@ func TestRepositoryManager_CleanStaleData_emptyRefDirs(t *testing.T) { { name: "unrelated empty directories", entries: []entry{ - d("objects", 0o700, 240*time.Hour, Keep, - d("empty", 0o700, 240*time.Hour, Keep), + d("objects", perm.PrivateDir, 240*time.Hour, Keep, + d("empty", perm.PrivateDir, 240*time.Hour, Keep), ), }, }, { name: "empty ref dir gets retained", entries: []entry{ - d("refs", 0o700, 240*time.Hour, Keep), + d("refs", perm.PrivateDir, 240*time.Hour, Keep), }, }, { name: "empty nested non-stale ref dir gets kept", entries: []entry{ - d("refs", 0o700, 240*time.Hour, Keep, - d("nested", 0o700, 23*time.Hour, Keep), + d("refs", perm.PrivateDir, 240*time.Hour, Keep, + d("nested", perm.PrivateDir, 23*time.Hour, Keep), ), }, }, { name: "empty nested stale ref dir gets pruned", entries: []entry{ - d("refs", 0o700, 240*time.Hour, Keep, - d("nested", 0o700, 240*time.Hour, Delete), + d("refs", perm.PrivateDir, 240*time.Hour, Keep, + d("nested", perm.PrivateDir, 240*time.Hour, Delete), ), }, expectedMetrics: cleanStaleDataMetrics{ @@ -464,9 +464,9 @@ func TestRepositoryManager_CleanStaleData_emptyRefDirs(t *testing.T) { { name: "hierarchy of nested stale ref dirs gets pruned", entries: []entry{ - d("refs", 0o700, 240*time.Hour, Keep, - d("first", 0o700, 240*time.Hour, Delete, - d("second", 0o700, 240*time.Hour, Delete), + d("refs", perm.PrivateDir, 240*time.Hour, Keep, + d("first", perm.PrivateDir, 240*time.Hour, Delete, + d("second", perm.PrivateDir, 240*time.Hour, Delete), ), ), }, @@ -477,10 +477,10 @@ func TestRepositoryManager_CleanStaleData_emptyRefDirs(t *testing.T) { { name: "hierarchy with intermediate non-stale ref dir gets kept", entries: []entry{ - d("refs", 0o700, 240*time.Hour, Keep, - d("first", 0o700, 240*time.Hour, Keep, - d("second", 0o700, 1*time.Hour, Keep, - d("third", 0o700, 24*time.Hour, Delete), + d("refs", perm.PrivateDir, 240*time.Hour, Keep, + d("first", perm.PrivateDir, 240*time.Hour, Keep, + d("second", perm.PrivateDir, 1*time.Hour, Keep, + d("third", perm.PrivateDir, 24*time.Hour, Delete), ), ), ), @@ -492,13 +492,13 @@ func TestRepositoryManager_CleanStaleData_emptyRefDirs(t *testing.T) { { name: "stale hierrachy with refs gets partially retained", entries: []entry{ - d("refs", 0o700, 240*time.Hour, Keep, - d("first", 0o700, 240*time.Hour, Keep, - d("second", 0o700, 240*time.Hour, Delete, - d("third", 0o700, 24*time.Hour, Delete), + d("refs", perm.PrivateDir, 240*time.Hour, Keep, + d("first", perm.PrivateDir, 240*time.Hour, Keep, + d("second", perm.PrivateDir, 240*time.Hour, Delete, + d("third", perm.PrivateDir, 24*time.Hour, Delete), ), - d("other", 0o700, 240*time.Hour, Keep, - f("ref", 0o700, 1*time.Hour, Keep), + d("other", perm.PrivateDir, 240*time.Hour, Keep, + f("ref", perm.PrivateFile, 1*time.Hour, Keep), ), ), ), @@ -550,7 +550,7 @@ func TestRepositoryManager_CleanStaleData_withSpecificFile(t *testing.T) { var topLevelDir, currentDir *dirEntry for _, subdir := range subdirs { - dir := d(subdir, 0o700, 1*time.Hour, Keep) + dir := d(subdir, perm.PrivateDir, 1*time.Hour, Keep) if topLevelDir == nil { topLevelDir = dir } @@ -662,32 +662,32 @@ func TestRepositoryManager_CleanStaleData_withSpecificFile(t *testing.T) { }{ { desc: fmt.Sprintf("fresh %s is kept", tc.file), - entry: f(tc.file, 0o700, 10*time.Minute, Keep), + entry: f(tc.file, perm.PrivateFile, 10*time.Minute, Keep), }, { desc: fmt.Sprintf("stale %s in subdir is kept", tc.file), - entry: d("subdir", 0o700, 240*time.Hour, Keep, - f(tc.file, 0o700, 24*time.Hour, Keep), + entry: d("subdir", perm.PrivateDir, 240*time.Hour, Keep, + f(tc.file, perm.PrivateFile, 24*time.Hour, Keep), ), }, { desc: fmt.Sprintf("stale %s is deleted", tc.file), - entry: f(tc.file, 0o700, 61*time.Minute, Delete), + entry: f(tc.file, perm.PrivateFile, 61*time.Minute, Delete), expectedFiles: []string{ filepath.Join(append([]string{repoPath}, append(tc.subdirs, tc.file)...)...), }, }, { desc: fmt.Sprintf("%q is kept", tc.file[:len(tc.file)-1]), - entry: f(tc.file[:len(tc.file)-1], 0o700, 61*time.Minute, Keep), + entry: f(tc.file[:len(tc.file)-1], perm.PrivateFile, 61*time.Minute, Keep), }, { desc: fmt.Sprintf("%q is kept", "~"+tc.file), - entry: f("~"+tc.file, 0o700, 61*time.Minute, Keep), + entry: f("~"+tc.file, perm.PrivateFile, 61*time.Minute, Keep), }, { desc: fmt.Sprintf("%q is kept", tc.file+"~"), - entry: f(tc.file+"~", 0o700, 61*time.Minute, Keep), + entry: f(tc.file+"~", perm.PrivateFile, 61*time.Minute, Keep), }, } { t.Run(subcase.desc, func(t *testing.T) { @@ -721,18 +721,18 @@ func TestRepositoryManager_CleanStaleData_serverInfo(t *testing.T) { repo := localrepo.NewTestRepo(t, cfg, repoProto) entries := []entry{ - d("info", 0o755, 0, Keep, - f("ref", 0, 0o644, Keep), - f("refs", 0, 0o644, Delete), - f("refsx", 0, 0o644, Keep), - f("refs_123456", 0, 0o644, Delete), + d("info", perm.SharedDir, 0, Keep, + f("ref", perm.SharedFile, 0, Keep), + f("refs", perm.SharedFile, 0, Delete), + f("refsx", perm.SharedFile, 0, Keep), + f("refs_123456", perm.SharedFile, 0, Delete), ), - d("objects", 0o755, 0, Keep, - d("info", 0o755, 0, Keep, - f("pack", 0, 0o644, Keep), - f("packs", 0, 0o644, Delete), - f("packsx", 0, 0o644, Keep), - f("packs_123456", 0, 0o644, Delete), + d("objects", perm.SharedDir, 0, Keep, + d("info", perm.SharedDir, 0, Keep, + f("pack", perm.SharedFile, 0, Keep), + f("packs", perm.SharedFile, 0, Delete), + f("packsx", perm.SharedFile, 0, Keep), + f("packs_123456", perm.SharedFile, 0, Delete), ), ), } @@ -776,18 +776,18 @@ func TestRepositoryManager_CleanStaleData_referenceLocks(t *testing.T) { { desc: "fresh lock is kept", entries: []entry{ - d("refs", 0o755, 0*time.Hour, Keep, - f("main", 0o755, 10*time.Minute, Keep), - f("main.lock", 0o755, 10*time.Minute, Keep), + d("refs", perm.SharedDir, 0*time.Hour, Keep, + f("main", perm.SharedExecutable, 10*time.Minute, Keep), + f("main.lock", perm.SharedExecutable, 10*time.Minute, Keep), ), }, }, { desc: "stale lock is deleted", entries: []entry{ - d("refs", 0o755, 0*time.Hour, Keep, - f("main", 0o755, 1*time.Hour, Keep), - f("main.lock", 0o755, 1*time.Hour, Delete), + d("refs", perm.SharedDir, 0*time.Hour, Keep, + f("main", perm.SharedExecutable, 1*time.Hour, Keep), + f("main.lock", perm.SharedExecutable, 1*time.Hour, Delete), ), }, expectedReferenceLocks: []string{ @@ -800,18 +800,18 @@ func TestRepositoryManager_CleanStaleData_referenceLocks(t *testing.T) { { desc: "nested reference locks are deleted", entries: []entry{ - d("refs", 0o755, 0*time.Hour, Keep, - d("tags", 0o755, 0*time.Hour, Keep, - f("main", 0o755, 1*time.Hour, Keep), - f("main.lock", 0o755, 1*time.Hour, Delete), + d("refs", perm.SharedDir, 0*time.Hour, Keep, + d("tags", perm.SharedDir, 0*time.Hour, Keep, + f("main", perm.SharedExecutable, 1*time.Hour, Keep), + f("main.lock", perm.SharedExecutable, 1*time.Hour, Delete), ), - d("heads", 0o755, 0*time.Hour, Keep, - f("main", 0o755, 1*time.Hour, Keep), - f("main.lock", 0o755, 1*time.Hour, Delete), + d("heads", perm.SharedDir, 0*time.Hour, Keep, + f("main", perm.SharedExecutable, 1*time.Hour, Keep), + f("main.lock", perm.SharedExecutable, 1*time.Hour, Delete), ), - d("foobar", 0o755, 0*time.Hour, Keep, - f("main", 0o755, 1*time.Hour, Keep), - f("main.lock", 0o755, 1*time.Hour, Delete), + d("foobar", perm.SharedDir, 0*time.Hour, Keep, + f("main", perm.SharedExecutable, 1*time.Hour, Keep), + f("main.lock", perm.SharedExecutable, 1*time.Hour, Delete), ), ), }, @@ -1001,7 +1001,7 @@ func TestRepositoryManager_CleanStaleData_unsetConfiguration(t *testing.T) { else = untouched [totally] unrelated = untouched -`), 0o644)) +`), perm.SharedFile)) mgr := NewManager(cfg.Prometheus, nil) @@ -1092,7 +1092,7 @@ func TestRepositoryManager_CleanStaleData_pruneEmptyConfigSections(t *testing.T) [remote "tmp-03b5e8c765135b343214d471843a062a"] [remote "tmp-f57338181aca1d599669dbb71ce9ce57"] [remote "tmp-8c948ca94832c2725733e48cb2902287"] -`), 0o644)) +`), perm.SharedFile)) mgr := NewManager(cfg.Prometheus, nil) @@ -1240,7 +1240,7 @@ func TestPruneEmptyConfigSections(t *testing.T) { }, } { t.Run(tc.desc, func(t *testing.T) { - require.NoError(t, os.WriteFile(configPath, []byte(tc.configData), 0o644)) + require.NoError(t, os.WriteFile(configPath, []byte(tc.configData), perm.SharedFile)) skippedSections, err := pruneEmptyConfigSections(ctx, repo) require.NoError(t, err) diff --git a/internal/git/housekeeping/optimize_repository_test.go b/internal/git/housekeeping/optimize_repository_test.go index 831d22f85..318995475 100644 --- a/internal/git/housekeeping/optimize_repository_test.go +++ b/internal/git/housekeeping/optimize_repository_test.go @@ -423,7 +423,7 @@ func testOptimizeRepository(t *testing.T, ctx context.Context) { for i := 0; i < looseObjectLimit+1; i++ { blobPath := filepath.Join(repoPath, "objects", "17", fmt.Sprintf("%d", i)) - require.NoError(t, os.WriteFile(blobPath, nil, 0o644)) + require.NoError(t, os.WriteFile(blobPath, nil, perm.SharedFile)) require.NoError(t, os.Chtimes(blobPath, almostTwoWeeksAgo, almostTwoWeeksAgo)) } @@ -463,7 +463,7 @@ func testOptimizeRepository(t *testing.T, ctx context.Context) { for i := 0; i < looseObjectLimit+1; i++ { blobPath := filepath.Join(repoPath, "objects", "17", fmt.Sprintf("%d", i)) - require.NoError(t, os.WriteFile(blobPath, nil, 0o644)) + require.NoError(t, os.WriteFile(blobPath, nil, perm.SharedFile)) require.NoError(t, os.Chtimes(blobPath, moreThanTwoWeeksAgo, moreThanTwoWeeksAgo)) } diff --git a/internal/git/localrepo/objects_test.go b/internal/git/localrepo/objects_test.go index 2edca3cd0..3727a574e 100644 --- a/internal/git/localrepo/objects_test.go +++ b/internal/git/localrepo/objects_test.go @@ -81,7 +81,7 @@ func testRepoWriteBlob(t *testing.T, ctx context.Context) { t.Run(tc.desc, func(t *testing.T) { attributesPath := filepath.Join(repoPath, "info", "attributes") require.NoError(t, os.MkdirAll(filepath.Dir(attributesPath), perm.SharedDir)) - require.NoError(t, os.WriteFile(attributesPath, []byte(tc.attributes), os.ModePerm)) + require.NoError(t, os.WriteFile(attributesPath, []byte(tc.attributes), perm.PublicFile)) sha, err := repo.WriteBlob(ctx, "file-path", tc.input) require.Equal(t, tc.error, err) diff --git a/internal/git/localrepo/refs_test.go b/internal/git/localrepo/refs_test.go index a98009fdf..71866b02e 100644 --- a/internal/git/localrepo/refs_test.go +++ b/internal/git/localrepo/refs_test.go @@ -19,6 +19,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v15/internal/safe" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" @@ -582,7 +583,7 @@ func TestRepo_SetDefaultBranch_errors(t *testing.T) { path, err := repo.Path() require.NoError(t, err) - require.NoError(t, os.WriteFile(filepath.Join(path, "HEAD.lock"), []byte(""), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(path, "HEAD.lock"), []byte(""), perm.SharedFile)) err = repo.SetDefaultBranch(ctx, &transaction.MockManager{}, "refs/heads/branch") require.ErrorIs(t, err, safe.ErrFileAlreadyLocked) diff --git a/internal/git/localrepo/repo_test.go b/internal/git/localrepo/repo_test.go index 25d7f9986..4c69cb599 100644 --- a/internal/git/localrepo/repo_test.go +++ b/internal/git/localrepo/repo_test.go @@ -13,6 +13,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" @@ -235,7 +236,7 @@ func TestSize(t *testing.T) { require.NoError(t, os.WriteFile( filepath.Join(repoPath, "objects", "info", "alternates"), []byte(filepath.Join(poolPath, "objects")), - os.ModePerm, + perm.PublicFile, )) for _, path := range []string{repoPath, poolPath} { @@ -269,7 +270,7 @@ func TestSize(t *testing.T) { require.NoError(t, os.WriteFile( filepath.Join(repoPath, "objects", "info", "alternates"), []byte(filepath.Join(poolPath, "objects")), - os.ModePerm, + perm.PublicFile, )) // We write the same object into both repositories, so we should @@ -304,7 +305,7 @@ func TestSize(t *testing.T) { require.NoError(t, os.WriteFile( filepath.Join(repoPath, "objects", "info", "alternates"), []byte(filepath.Join(poolPath, "objects")), - os.ModePerm, + perm.PublicFile, )) for i, path := range []string{repoPath, poolPath} { diff --git a/internal/git/objectpool/link_test.go b/internal/git/objectpool/link_test.go index 2c691164c..eb8074dc7 100644 --- a/internal/git/objectpool/link_test.go +++ b/internal/git/objectpool/link_test.go @@ -12,6 +12,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" "google.golang.org/grpc/peer" @@ -117,7 +118,7 @@ func TestLink_absoluteLinkExists(t *testing.T) { altPath, err := repo.InfoAlternatesPath() require.NoError(t, err) - require.NoError(t, os.WriteFile(altPath, []byte(poolObjectsPath), 0o644)) + require.NoError(t, os.WriteFile(altPath, []byte(poolObjectsPath), perm.SharedFile)) require.NoError(t, pool.Link(ctx, repo), "we expect this call to change the absolute link to a relative link") diff --git a/internal/git/objectpool/pool_test.go b/internal/git/objectpool/pool_test.go index 13e5b4798..57c1d6071 100644 --- a/internal/git/objectpool/pool_test.go +++ b/internal/git/objectpool/pool_test.go @@ -110,7 +110,7 @@ func TestFromRepo_failures(t *testing.T) { require.NoError(t, os.MkdirAll(filepath.Join(repoPath, "objects", "info"), perm.SharedDir)) alternateFilePath := filepath.Join(repoPath, "objects", "info", "alternates") - require.NoError(t, os.WriteFile(alternateFilePath, tc.fileContent, 0o644)) + require.NoError(t, os.WriteFile(alternateFilePath, tc.fileContent, perm.SharedFile)) poolFromRepo, err := FromRepo(locator, pool.gitCmdFactory, nil, nil, nil, repo) require.Equal(t, tc.expectedErr, err) require.Nil(t, poolFromRepo) diff --git a/internal/git/quarantine/quarantine_test.go b/internal/git/quarantine/quarantine_test.go index 390bdf9e1..4d372fcc2 100644 --- a/internal/git/quarantine/quarantine_test.go +++ b/internal/git/quarantine/quarantine_test.go @@ -34,7 +34,7 @@ func (e entry) create(t *testing.T, root string) { child.create(t, filepath.Join(root, name)) } } else { - require.NoError(t, os.WriteFile(root, []byte(e.contents), 0o666)) + require.NoError(t, os.WriteFile(root, []byte(e.contents), perm.PublicFile)) } } @@ -122,7 +122,7 @@ func TestQuarantine_Migrate(t *testing.T) { quarantine, err := New(ctx, repo, locator) require.NoError(t, err) - require.NoError(t, os.WriteFile(filepath.Join(quarantine.dir.Path(), "file"), []byte("foobar"), 0o666)) + require.NoError(t, os.WriteFile(filepath.Join(quarantine.dir.Path(), "file"), []byte("foobar"), perm.PublicFile)) require.NoError(t, quarantine.Migrate()) newContents := listEntries(t, repoPath) @@ -337,7 +337,7 @@ func TestFinalizeObjectFile(t *testing.T) { source := filepath.Join(dir, "a") target := filepath.Join(dir, "b") - require.NoError(t, os.WriteFile(source, []byte("a"), 0o777)) + require.NoError(t, os.WriteFile(source, []byte("a"), perm.PublicExecutable)) require.NoError(t, finalizeObjectFile(source, target)) require.NoFileExists(t, source) @@ -350,7 +350,7 @@ func TestFinalizeObjectFile(t *testing.T) { source := filepath.Join(sourceDir, "a") target := filepath.Join(targetDir, "a") - require.NoError(t, os.WriteFile(source, []byte("a"), 0o777)) + require.NoError(t, os.WriteFile(source, []byte("a"), perm.PublicExecutable)) require.NoError(t, finalizeObjectFile(source, target)) require.NoFileExists(t, source) @@ -361,10 +361,10 @@ func TestFinalizeObjectFile(t *testing.T) { dir := testhelper.TempDir(t) source := filepath.Join(dir, "a") - require.NoError(t, os.WriteFile(source, []byte("a"), 0o777)) + require.NoError(t, os.WriteFile(source, []byte("a"), perm.PublicExecutable)) target := filepath.Join(dir, "b") - require.NoError(t, os.WriteFile(target, []byte("b"), 0o777)) + require.NoError(t, os.WriteFile(target, []byte("b"), perm.PublicExecutable)) // We do not expect an error in case the target file exists: given that objects and // packs are content addressable, a file with the same name should have the same diff --git a/internal/git/remoterepo/repository_test.go b/internal/git/remoterepo/repository_test.go index b5dfa4616..f2e4865f9 100644 --- a/internal/git/remoterepo/repository_test.go +++ b/internal/git/remoterepo/repository_test.go @@ -14,6 +14,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" @@ -113,7 +114,7 @@ func TestRepository_ObjectHash(t *testing.T) { "[extensions]", "objectFormat = blake2b", }, "\n"), - ), 0o644)) + ), perm.SharedFile)) repo, err := remoterepo.New(ctx, repoProto, pool) require.NoError(t, err) diff --git a/internal/git/ssh.go b/internal/git/ssh.go index be411576f..93f312597 100644 --- a/internal/git/ssh.go +++ b/internal/git/ssh.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" ) // BuildSSHInvocation builds a command line to invoke SSH with the provided key and known hosts. @@ -32,7 +33,7 @@ func BuildSSHInvocation(ctx context.Context, sshKey, knownHosts string) (string, args := []string{sshCommand} if sshKey != "" { sshKeyFile := filepath.Join(tmpDir, "ssh-key") - if err := os.WriteFile(sshKeyFile, []byte(sshKey), 0o400); err != nil { + if err := os.WriteFile(sshKeyFile, []byte(sshKey), perm.PrivateWriteOnceFile); err != nil { cleanup() return "", nil, fmt.Errorf("create ssh key file: %w", err) } @@ -42,7 +43,7 @@ func BuildSSHInvocation(ctx context.Context, sshKey, knownHosts string) (string, if knownHosts != "" { knownHostsFile := filepath.Join(tmpDir, "known-hosts") - if err := os.WriteFile(knownHostsFile, []byte(knownHosts), 0o400); err != nil { + if err := os.WriteFile(knownHostsFile, []byte(knownHosts), perm.PrivateWriteOnceFile); err != nil { cleanup() return "", nil, fmt.Errorf("create known hosts file: %w", err) } diff --git a/internal/git/stats/repository_info_test.go b/internal/git/stats/repository_info_test.go index 3e11904f5..faafc1be2 100644 --- a/internal/git/stats/repository_info_test.go +++ b/internal/git/stats/repository_info_test.go @@ -257,7 +257,7 @@ func TestRepositoryInfoForRepository(t *testing.T) { desc: "garbage", setup: func(t *testing.T, repoPath string) { garbagePath := filepath.Join(repoPath, "objects", "pack", "garbage") - require.NoError(t, os.WriteFile(garbagePath, []byte("x"), 0o600)) + require.NoError(t, os.WriteFile(garbagePath, []byte("x"), perm.PrivateFile)) }, expectedInfo: RepositoryInfo{ Packfiles: PackfilesInfo{ @@ -270,7 +270,7 @@ func TestRepositoryInfoForRepository(t *testing.T) { desc: "alternates", setup: func(t *testing.T, repoPath string) { infoAlternatesPath := filepath.Join(repoPath, "objects", "info", "alternates") - require.NoError(t, os.WriteFile(infoAlternatesPath, []byte(alternatePath), 0o600)) + require.NoError(t, os.WriteFile(infoAlternatesPath, []byte(alternatePath), perm.PrivateFile)) }, expectedInfo: RepositoryInfo{ Alternates: []string{ @@ -355,7 +355,7 @@ func TestRepositoryInfoForRepository(t *testing.T) { desc: "all together", setup: func(t *testing.T, repoPath string) { infoAlternatesPath := filepath.Join(repoPath, "objects", "info", "alternates") - require.NoError(t, os.WriteFile(infoAlternatesPath, []byte(alternatePath), 0o600)) + require.NoError(t, os.WriteFile(infoAlternatesPath, []byte(alternatePath), perm.PrivateFile)) // We write a single packed blob. blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("x")) @@ -370,7 +370,7 @@ func TestRepositoryInfoForRepository(t *testing.T) { // everywhere. for _, file := range []string{"garbage1", "garbage2", "garbage3"} { garbagePath := filepath.Join(repoPath, "objects", "pack", file) - require.NoError(t, os.WriteFile(garbagePath, []byte("x"), 0o600)) + require.NoError(t, os.WriteFile(garbagePath, []byte("x"), perm.PrivateFile)) } }, expectedInfo: RepositoryInfo{ @@ -444,7 +444,7 @@ func TestReferencesInfoForRepository(t *testing.T) { // We just write some random garbage -- we don't verify contents // anyway, but just the size. And testing like that is at least // deterministic as we don't have to special-case hash sizes. - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "packed-refs"), []byte("content"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "packed-refs"), []byte("content"), perm.SharedFile)) }, expectedInfo: ReferencesInfo{ PackedReferencesSize: 7, @@ -464,7 +464,7 @@ func TestReferencesInfoForRepository(t *testing.T) { // We just write some random garbage -- we don't verify contents // anyway, but just the size. And testing like that is at least // deterministic as we don't have to special-case hash sizes. - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "packed-refs"), []byte("content"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "packed-refs"), []byte("content"), perm.SharedFile)) }, expectedInfo: ReferencesInfo{ LooseReferencesCount: 3, @@ -515,7 +515,7 @@ func TestCountLooseObjects(t *testing.T) { differentShard := filepath.Join(repoPath, "objects", "a0") require.NoError(t, os.MkdirAll(differentShard, perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(differentShard, "123456"), []byte("foobar"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(differentShard, "123456"), []byte("foobar"), perm.SharedFile)) requireLooseObjectsInfo(t, repo, time.Now(), LooseObjectsInfo{ Count: 1, @@ -531,7 +531,7 @@ func TestCountLooseObjects(t *testing.T) { for i, shard := range []string{"00", "17", "32", "ff"} { shardPath := filepath.Join(repoPath, "objects", shard) require.NoError(t, os.MkdirAll(shardPath, perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(shardPath, "123456"), make([]byte, i), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(shardPath, "123456"), make([]byte, i), perm.SharedFile)) } requireLooseObjectsInfo(t, repo, time.Now(), LooseObjectsInfo{ @@ -558,7 +558,7 @@ func TestCountLooseObjects(t *testing.T) { beforeCutoffDate := cutoffDate.Add(-1 * time.Minute) for _, objectPath := range objectPaths { - require.NoError(t, os.WriteFile(objectPath, []byte("1"), 0o644)) + require.NoError(t, os.WriteFile(objectPath, []byte("1"), perm.SharedFile)) require.NoError(t, os.Chtimes(objectPath, afterCutoffDate, afterCutoffDate)) } @@ -587,8 +587,8 @@ func TestCountLooseObjects(t *testing.T) { shard := filepath.Join(repoPath, "objects", "17") require.NoError(t, os.MkdirAll(shard, perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(shard, "012345"), []byte("valid"), 0o644)) - require.NoError(t, os.WriteFile(filepath.Join(shard, "garbage"), []byte("garbage"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(shard, "012345"), []byte("valid"), perm.SharedFile)) + require.NoError(t, os.WriteFile(filepath.Join(shard, "garbage"), []byte("garbage"), perm.SharedFile)) requireLooseObjectsInfo(t, repo, time.Now(), LooseObjectsInfo{ Count: 1, @@ -627,7 +627,7 @@ func BenchmarkCountLooseObjects(b *testing.B) { objectPath := filepath.Join(repoPath, "objects", "17", "12345") require.NoError(b, os.Mkdir(filepath.Dir(objectPath), perm.SharedDir)) - require.NoError(b, os.WriteFile(objectPath, nil, 0o644)) + require.NoError(b, os.WriteFile(objectPath, nil, perm.SharedFile)) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -642,7 +642,7 @@ func BenchmarkCountLooseObjects(b *testing.B) { for i := 0; i < 256; i++ { objectPath := filepath.Join(repoPath, "objects", fmt.Sprintf("%02x", i), "12345") require.NoError(b, os.Mkdir(filepath.Dir(objectPath), perm.SharedDir)) - require.NoError(b, os.WriteFile(objectPath, nil, 0o644)) + require.NoError(b, os.WriteFile(objectPath, nil, perm.SharedFile)) } b.ResetTimer() @@ -671,7 +671,7 @@ func BenchmarkCountLooseObjects(b *testing.B) { for j := 0; j < looseObjectCount; j++ { objectPath := filepath.Join(shardPath, fmt.Sprintf("%d", j)) - require.NoError(b, os.WriteFile(objectPath, nil, 0o644)) + require.NoError(b, os.WriteFile(objectPath, nil, perm.SharedFile)) } } @@ -691,7 +691,7 @@ func BenchmarkCountLooseObjects(b *testing.B) { for j := 0; j < 1000; j++ { objectPath := filepath.Join(shardPath, fmt.Sprintf("%d", j)) - require.NoError(b, os.WriteFile(objectPath, nil, 0o644)) + require.NoError(b, os.WriteFile(objectPath, nil, perm.SharedFile)) } } @@ -725,7 +725,7 @@ func TestPackfileInfoForRepository(t *testing.T) { seedRepository: func(t *testing.T, repoPath string) { packfileDir := filepath.Join(repoPath, "objects", "pack") require.NoError(t, os.MkdirAll(packfileDir, perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.pack"), []byte("foobar"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.pack"), []byte("foobar"), perm.SharedFile)) }, expectedInfo: PackfilesInfo{ Count: 1, @@ -737,8 +737,8 @@ func TestPackfileInfoForRepository(t *testing.T) { seedRepository: func(t *testing.T, repoPath string) { packfileDir := filepath.Join(repoPath, "objects", "pack") require.NoError(t, os.MkdirAll(packfileDir, perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.pack"), []byte("foobar"), 0o644)) - require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.keep"), []byte("foobar"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.pack"), []byte("foobar"), perm.SharedFile)) + require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.keep"), []byte("foobar"), perm.SharedFile)) }, expectedInfo: PackfilesInfo{ KeepCount: 1, @@ -750,8 +750,8 @@ func TestPackfileInfoForRepository(t *testing.T) { seedRepository: func(t *testing.T, repoPath string) { packfileDir := filepath.Join(repoPath, "objects", "pack") require.NoError(t, os.MkdirAll(packfileDir, perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.pack"), []byte("foobar"), 0o644)) - require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.mtimes"), []byte("foobar"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.pack"), []byte("foobar"), perm.SharedFile)) + require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.mtimes"), []byte("foobar"), perm.SharedFile)) }, expectedInfo: PackfilesInfo{ CruftCount: 1, @@ -763,8 +763,8 @@ func TestPackfileInfoForRepository(t *testing.T) { seedRepository: func(t *testing.T, repoPath string) { packfileDir := filepath.Join(repoPath, "objects", "pack") require.NoError(t, os.MkdirAll(packfileDir, perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.pack"), []byte("foobar"), 0o644)) - require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-bar.pack"), []byte("123"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-foo.pack"), []byte("foobar"), perm.SharedFile)) + require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "pack-bar.pack"), []byte("123"), perm.SharedFile)) }, expectedInfo: PackfilesInfo{ Count: 2, @@ -793,7 +793,7 @@ func TestPackfileInfoForRepository(t *testing.T) { seedRepository: func(t *testing.T, repoPath string) { packfileDir := filepath.Join(repoPath, "objects", "pack") require.NoError(t, os.MkdirAll(packfileDir, perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "multi-pack-index"), nil, 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(packfileDir, "multi-pack-index"), nil, perm.SharedFile)) }, expectedInfo: PackfilesInfo{ HasMultiPackIndex: true, @@ -824,7 +824,7 @@ func TestPackfileInfoForRepository(t *testing.T) { gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("second"), gittest.WithBranch("second")) gittest.Exec(t, cfg, "-C", repoPath, "repack", "-db", "--write-midx") - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "objects", "pack", "garbage"), []byte("1"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "objects", "pack", "garbage"), []byte("1"), perm.SharedFile)) }, expectedInfo: PackfilesInfo{ Count: 2, @@ -1139,7 +1139,7 @@ func TestBitmapInfoForPath(t *testing.T) { desc: "header is too short", setup: func(t *testing.T) string { bitmapPath := filepath.Join(testhelper.TempDir(t), "bitmap") - require.NoError(t, os.WriteFile(bitmapPath, []byte{0, 0, 0}, 0o644)) + require.NoError(t, os.WriteFile(bitmapPath, []byte{0, 0, 0}, perm.SharedFile)) return bitmapPath }, expectedErr: fmt.Errorf("reading bitmap header: %w", io.ErrUnexpectedEOF), @@ -1150,7 +1150,7 @@ func TestBitmapInfoForPath(t *testing.T) { bitmapPath := filepath.Join(testhelper.TempDir(t), "bitmap") require.NoError(t, os.WriteFile(bitmapPath, []byte{ 'B', 'I', 'T', 'O', 0, 0, 0, 0, - }, 0o644)) + }, perm.SharedFile)) return bitmapPath }, expectedErr: fmt.Errorf("invalid bitmap signature: %q", "BITO"), @@ -1161,7 +1161,7 @@ func TestBitmapInfoForPath(t *testing.T) { bitmapPath := filepath.Join(testhelper.TempDir(t), "bitmap") require.NoError(t, os.WriteFile(bitmapPath, []byte{ 'B', 'I', 'T', 'M', 0, 2, 0, 0, - }, 0o644)) + }, perm.SharedFile)) return bitmapPath }, expectedErr: fmt.Errorf("unsupported version: 2"), diff --git a/internal/git/updateref/updateref.go b/internal/git/updateref/updateref.go index 7a078f978..a161d8435 100644 --- a/internal/git/updateref/updateref.go +++ b/internal/git/updateref/updateref.go @@ -4,11 +4,13 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" "regexp" "gitlab.com/gitlab-org/gitaly/v15/internal/command" "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" ) // ErrAlreadyLocked indicates a reference cannot be locked because another @@ -317,13 +319,7 @@ func (u *Updater) Close() error { func (u *Updater) write(format string, args ...interface{}) error { if _, err := fmt.Fprintf(u.cmd, format, args...); err != nil { - // We need to explicitly cancel the command here and wait for it to terminate such - // that we can retrieve the command's stderr in a race-free manner. - _ = u.Close() - // The update-ref process may have already exited due to an error. In such cases, - // the write errors are not meaningful. If we find one of the typed errors in - // stderr, we'll return it instead. - return parseStderrError(u.stderr.Bytes(), fmt.Errorf("%w: %q", err, u.stderr)) + return u.handleIOError(err) } return nil @@ -350,11 +346,7 @@ func (u *Updater) setState(state string) error { // raised. line, err := u.stdout.ReadString('\n') if err != nil { - // We need to explicitly cancel the command here and wait for it to - // terminate such that we can retrieve the command's stderr in a race-free - // manner. - _ = u.Close() - return parseStderrError(u.stderr.Bytes(), fmt.Errorf("state update to %q failed: %w, stderr: %q", state, err, u.stderr)) + return u.handleIOError(fmt.Errorf("state update to %q failed: %w", state, err)) } if line != fmt.Sprintf("%s: ok\n", state) { @@ -365,9 +357,28 @@ func (u *Updater) setState(state string) error { return nil } -// parseStderrError returns any typed error that might be present in stderr. If -// the error message does not match any typed error, defaultErr is returned instead. -func parseStderrError(stderr []byte, defaultErr error) error { +// handleIOError handles errors after reading from or writing to git-update-ref(1) has failed. +// It makes sure to properly tear down the process so that the stderr gets synchronized and handles +// well-known errors. If the error message is not a well-known error then this function returns the +// fallback error provided by the caller. +func (u *Updater) handleIOError(fallbackErr error) error { + // We need to explicitly cancel the command here and wait for it to terminate such that we + // can retrieve the command's stderr in a race-free manner. + // + // Furthermore, if I/O has failed because we cancelled the process then we don't want to + // return a converted error, but instead want to return the actual context cancellation + // error. + if err := u.Close(); err != nil { + switch { + case errors.Is(err, context.Canceled): + return err + case errors.Is(err, context.DeadlineExceeded): + return err + } + } + + stderr := u.stderr.Bytes() + matches := refLockedRegex.FindSubmatch(stderr) if len(matches) > 1 { return &ErrAlreadyLocked{Ref: string(matches[1])} @@ -410,5 +421,5 @@ func parseStderrError(stderr []byte, defaultErr error) error { } } - return defaultErr + return structerr.New("%w", fallbackErr).WithMetadata("stderr", string(stderr)) } diff --git a/internal/git/updateref/updateref_test.go b/internal/git/updateref/updateref_test.go index addafa2da..ce04344a8 100644 --- a/internal/git/updateref/updateref_test.go +++ b/internal/git/updateref/updateref_test.go @@ -3,7 +3,9 @@ package updateref import ( "context" "encoding/hex" + "errors" "fmt" + "io" "os" "path/filepath" "testing" @@ -14,6 +16,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) @@ -325,7 +328,10 @@ func TestUpdater_update(t *testing.T) { // when the old commit ID doesn't match. require.NoError(t, updater.Start()) require.NoError(t, updater.Update("refs/heads/main", newCommitID, otherCommitID)) - require.ErrorContains(t, updater.Commit(), fmt.Sprintf("fatal: commit: cannot lock ref 'refs/heads/main': is at %s but expected %s", oldCommitID, otherCommitID)) + + require.Equal(t, structerr.New("%w", fmt.Errorf("state update to %q failed: %w", "commit", io.EOF)).WithMetadata( + "stderr", fmt.Sprintf("fatal: commit: cannot lock ref 'refs/heads/main': is at %s but expected %s\n", oldCommitID, otherCommitID), + ), updater.Commit()) require.Equal(t, invalidStateTransitionError{expected: stateIdle, actual: stateClosed}, updater.Start()) require.Equal(t, gittest.ResolveRevision(t, cfg, repoPath, "refs/heads/main"), oldCommitID) @@ -515,7 +521,14 @@ func TestUpdater_cancel(t *testing.T) { require.NoError(t, failingUpdater.Start()) require.NoError(t, failingUpdater.Delete(git.ReferenceName("refs/heads/main"))) - require.ErrorContains(t, failingUpdater.Commit(), "fatal: commit: cannot lock ref 'refs/heads/main'") + + err = failingUpdater.Commit() + require.EqualError(t, err, fmt.Sprintf("state update to %q failed: %v", "commit", io.EOF)) + var structErr structerr.Error + require.True(t, errors.As(err, &structErr)) + // The error message returned by git-update-ref(1) is simply too long to fully verify it, so + // we just check that it matches a specific substring. + require.Contains(t, structErr.Metadata()["stderr"], "fatal: commit: cannot lock ref 'refs/heads/main'") // We now cancel the initial updater. Afterwards, it should be possible again to update the // ref because locks should have been released. @@ -569,7 +582,9 @@ func TestUpdater_capturesStderr(t *testing.T) { _, err := updater.cmd.Write([]byte("garbage input")) require.NoError(t, err) - require.EqualError(t, updater.Commit(), `state update to "commit" failed: EOF, stderr: "fatal: unknown command: garbage inputcommit\n"`) + require.Equal(t, structerr.New("%w", fmt.Errorf("state update to %q failed: %w", "commit", io.EOF)).WithMetadata( + "stderr", "fatal: unknown command: garbage inputcommit\n", + ), updater.Commit()) } func BenchmarkUpdater(b *testing.B) { diff --git a/internal/git/version.go b/internal/git/version.go index 2d13c1187..4690e96aa 100644 --- a/internal/git/version.go +++ b/internal/git/version.go @@ -1,12 +1,10 @@ package git import ( + "bytes" "fmt" - "io" "strconv" "strings" - - "gitlab.com/gitlab-org/gitaly/v15/internal/command" ) // minimumVersion is the minimum required Git version. If updating this version, be sure to @@ -38,17 +36,10 @@ type Version struct { gl uint32 } -func parseVersionFromCommand(cmd *command.Command) (Version, error) { - versionOutput, err := io.ReadAll(cmd) - if err != nil { - return Version{}, fmt.Errorf("reading version output: %w", err) - } - - if err := cmd.Wait(); err != nil { - return Version{}, fmt.Errorf("waiting for version command: %w", err) - } - - trimmedVersionOutput := strings.Trim(string(versionOutput), " \n") +// parseVersionOutput parses output returned by git-version(1). It is expected to be in the format +// "git version 2.39.1.gl1". +func parseVersionOutput(versionOutput []byte) (Version, error) { + trimmedVersionOutput := string(bytes.Trim(versionOutput, " \n")) versionString := strings.SplitN(trimmedVersionOutput, " ", 3) if len(versionString) != 3 { return Version{}, fmt.Errorf("invalid version format: %q", string(versionOutput)) diff --git a/internal/gitaly/config/config_test.go b/internal/gitaly/config/config_test.go index 3f3a3e05b..c6bb4d32a 100644 --- a/internal/gitaly/config/config_test.go +++ b/internal/gitaly/config/config_test.go @@ -185,7 +185,7 @@ func TestValidateStorages(t *testing.T) { require.NoError(t, os.MkdirAll(nestedRepositories, perm.PublicDir)) filePath := filepath.Join(testhelper.TempDir(t), "temporary-file") - require.NoError(t, os.WriteFile(filePath, []byte{}, 0o666)) + require.NoError(t, os.WriteFile(filePath, []byte{}, perm.PublicFile)) invalidDir := filepath.Join(repositories, t.Name()) @@ -427,7 +427,7 @@ func TestValidateShellPath(t *testing.T) { require.NoError(t, os.MkdirAll(filepath.Join(tmpDir, "bin"), perm.SharedDir)) tmpFile := filepath.Join(tmpDir, "my-file") - require.NoError(t, os.WriteFile(tmpFile, []byte{}, 0o666)) + require.NoError(t, os.WriteFile(tmpFile, []byte{}, perm.PublicFile)) testCases := []struct { desc string @@ -473,7 +473,7 @@ func TestConfigureRuby(t *testing.T) { tmpDir := testhelper.TempDir(t) tmpFile := filepath.Join(tmpDir, "file") - require.NoError(t, os.WriteFile(tmpFile, nil, 0o644)) + require.NoError(t, os.WriteFile(tmpFile, nil, perm.SharedFile)) testCases := []struct { desc string @@ -1264,7 +1264,7 @@ func TestSetupRuntimeDirectory(t *testing.T) { t.Run("validation", func(t *testing.T) { dirPath := testhelper.TempDir(t) filePath := filepath.Join(dirPath, "file") - require.NoError(t, os.WriteFile(filePath, nil, 0o644)) + require.NoError(t, os.WriteFile(filePath, nil, perm.SharedFile)) for _, tc := range []struct { desc string diff --git a/internal/gitaly/config/temp_dir_test.go b/internal/gitaly/config/temp_dir_test.go index 2e809363a..62b188776 100644 --- a/internal/gitaly/config/temp_dir_test.go +++ b/internal/gitaly/config/temp_dir_test.go @@ -62,7 +62,7 @@ func TestPruneOldGitalyProcessDirectories(t *testing.T) { // Create an unexpected file in the runtime directory unexpectedFilePath := filepath.Join(baseDir, "unexpected-file") - require.NoError(t, os.WriteFile(unexpectedFilePath, []byte(""), os.ModePerm)) + require.NoError(t, os.WriteFile(unexpectedFilePath, []byte(""), perm.PublicFile)) expectedLogs[unexpectedFilePath] = "ignoring file found in gitaly process directory" nonPrunableDirs := []string{ownRuntimeDir} diff --git a/internal/gitaly/hook/custom_test.go b/internal/gitaly/hook/custom_test.go index 6f109998b..52febe6bb 100644 --- a/internal/gitaly/hook/custom_test.go +++ b/internal/gitaly/hook/custom_test.go @@ -445,7 +445,7 @@ type customHookResults struct { func writeCustomHook(t *testing.T, hookName, dir string, content []byte) func() { require.NoError(t, os.MkdirAll(dir, perm.SharedDir)) - require.NoError(t, os.WriteFile(filepath.Join(dir, hookName), content, 0o755)) + require.NoError(t, os.WriteFile(filepath.Join(dir, hookName), content, perm.SharedExecutable)) return func() { require.NoError(t, os.RemoveAll(dir)) diff --git a/internal/gitaly/linguist/language_stats_test.go b/internal/gitaly/linguist/language_stats_test.go index 74f66a568..fa296e4bf 100644 --- a/internal/gitaly/linguist/language_stats_test.go +++ b/internal/gitaly/linguist/language_stats_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) @@ -49,7 +50,7 @@ func TestInitLanguageStats(t *testing.T) { { desc: "corrupt cache", run: func(t *testing.T, repo *localrepo.Repo, repoPath string) { - require.NoError(t, os.WriteFile(filepath.Join(repoPath, languageStatsFilename), []byte("garbage"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, languageStatsFilename), []byte("garbage"), perm.SharedFile)) stats, err := initLanguageStats(repo) require.Errorf(t, err, "new language stats zlib reader: invalid header") @@ -67,7 +68,7 @@ func TestInitLanguageStats(t *testing.T) { stats.Version = "faulty" // Copy save() behavior, but with a faulty version - file, err := os.OpenFile(filepath.Join(repoPath, languageStatsFilename), os.O_WRONLY|os.O_CREATE, 0o755) + file, err := os.OpenFile(filepath.Join(repoPath, languageStatsFilename), os.O_WRONLY|os.O_CREATE, perm.SharedExecutable) require.NoError(t, err) w := zlib.NewWriter(file) require.NoError(t, json.NewEncoder(w).Encode(stats)) diff --git a/internal/gitaly/linguist/linguist_test.go b/internal/gitaly/linguist/linguist_test.go index 1fd1bb633..6de1d52fe 100644 --- a/internal/gitaly/linguist/linguist_test.go +++ b/internal/gitaly/linguist/linguist_test.go @@ -460,7 +460,7 @@ func TestInstance_Stats(t *testing.T) { gittest.TreeEntry{Path: "application.rb", Mode: "100644", Content: strings.Repeat("a", 2943)}, )) - require.NoError(t, os.WriteFile(filepath.Join(repoPath, languageStatsFilename), []byte("garbage"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, languageStatsFilename), []byte("garbage"), perm.SharedFile)) return repoProto, repoPath, commitID }, @@ -532,7 +532,7 @@ func TestInstance_Stats(t *testing.T) { require.NoError(t, os.MkdirAll(infoPath, perm.SharedDir)) attrData, err := gittest.NewCommand(t, cfg, "-C", repoPath, "cat-file", "blob", objectID.String()+":.gitattributes").Output() if err == nil { - require.NoError(t, os.WriteFile(filepath.Join(infoPath, "attributes"), attrData, 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(infoPath, "attributes"), attrData, perm.SharedFile)) } repo := localrepo.NewTestRepo(t, cfg, repoProto) diff --git a/internal/gitaly/maintenance/randomwalker_test.go b/internal/gitaly/maintenance/randomwalker_test.go index 0b6a8e7bf..22f406572 100644 --- a/internal/gitaly/maintenance/randomwalker_test.go +++ b/internal/gitaly/maintenance/randomwalker_test.go @@ -156,7 +156,7 @@ func TestRandomWalk(t *testing.T) { } for _, file := range tc.files { - require.NoError(t, os.WriteFile(filepath.Join(root, file), []byte{}, 0o777)) + require.NoError(t, os.WriteFile(filepath.Join(root, file), []byte{}, perm.PublicExecutable)) } walker := newRandomWalker(root, rand.New(rand.NewSource(1))) diff --git a/internal/gitaly/repoutil/create_test.go b/internal/gitaly/repoutil/create_test.go index 838970617..97e2fbb07 100644 --- a/internal/gitaly/repoutil/create_test.go +++ b/internal/gitaly/repoutil/create_test.go @@ -219,14 +219,14 @@ func TestCreate(t *testing.T) { // indeterministic data that's different across replicas and would // thus cause us to not reach quorum. require.NoError(t, os.Mkdir(filepath.Join(repoPath, "objects"), perm.PublicDir)) - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "objects", "object"), []byte("object"), 0o666)) - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "FETCH_HEAD"), []byte("fetch-head"), 0o666)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "objects", "object"), []byte("object"), perm.PublicFile)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "FETCH_HEAD"), []byte("fetch-head"), perm.PublicFile)) // All the other files should be hashed though. - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "HEAD"), []byte("head"), 0o666)) - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "config"), []byte("cfg"), 0o666)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "HEAD"), []byte("head"), perm.PublicFile)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "config"), []byte("cfg"), perm.PublicFile)) require.NoError(t, os.MkdirAll(filepath.Join(repoPath, "refs", "heads"), perm.PublicDir)) - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "refs", "heads", "foo"), []byte("foo"), 0o666)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "refs", "heads", "foo"), []byte("foo"), perm.PublicFile)) return nil }, diff --git a/internal/gitaly/rubyserver/rubyserver.go b/internal/gitaly/rubyserver/rubyserver.go index 34f3e80c6..d047f8707 100644 --- a/internal/gitaly/rubyserver/rubyserver.go +++ b/internal/gitaly/rubyserver/rubyserver.go @@ -162,7 +162,7 @@ func (s *Server) start() error { // Git configuration. Otherwise, Rugged wouldn't find it. if err := os.WriteFile(filepath.Join(gitconfigDir, "gitconfig"), []byte( "[core]\n\tfsyncObjectFiles = true\n", - ), 0o666); err != nil { + ), perm.PublicFile); err != nil { return fmt.Errorf("writing gitconfig: %w", err) } diff --git a/internal/gitaly/rubyserver/rubyserver_test.go b/internal/gitaly/rubyserver/rubyserver_test.go index a52e3f4fb..15e0c905d 100644 --- a/internal/gitaly/rubyserver/rubyserver_test.go +++ b/internal/gitaly/rubyserver/rubyserver_test.go @@ -16,6 +16,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" "gitlab.com/gitlab-org/gitaly/v15/internal/helper" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" "gitlab.com/gitlab-org/gitaly/v15/internal/version" @@ -171,7 +172,7 @@ func TestServer_gitconfig(t *testing.T) { setup: func(t *testing.T) (config.Cfg, string) { gitconfigDir := testhelper.TempDir(t) expectedPath := filepath.Join(gitconfigDir, "gitconfig") - require.NoError(t, os.WriteFile(expectedPath, []byte("garbage"), 0o666)) + require.NoError(t, os.WriteFile(expectedPath, []byte("garbage"), perm.PublicFile)) cfg := testcfg.Build(t, testcfg.WithBase(config.Cfg{ Ruby: config.Ruby{ diff --git a/internal/gitaly/server/server.go b/internal/gitaly/server/server.go index 94f11279b..c529a9038 100644 --- a/internal/gitaly/server/server.go +++ b/internal/gitaly/server/server.go @@ -20,6 +20,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/cache" "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/commandstatshandler" "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/featureflag" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler" "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/metadatahandler" "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/panichandler" "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/sentryhandler" @@ -111,6 +112,7 @@ func (s *GitalyServerFactory) New(secure bool, opts ...Option) (*grpc.Server, er grpcstats.FieldsProducer, featureflag.FieldsProducer, structerr.FieldsProducer, + limithandler.FieldsProducer, ), ) @@ -120,6 +122,7 @@ func (s *GitalyServerFactory) New(secure bool, opts ...Option) (*grpc.Server, er metadatahandler.StreamInterceptor, grpcprometheus.StreamServerInterceptor, commandstatshandler.StreamInterceptor, + limithandler.StatsStreamInterceptor, grpcmwlogrus.StreamServerInterceptor(s.logger, grpcmwlogrus.WithTimestampFormat(gitalylog.LogTimestampFormat), logMsgProducer, @@ -136,6 +139,7 @@ func (s *GitalyServerFactory) New(secure bool, opts ...Option) (*grpc.Server, er metadatahandler.UnaryInterceptor, grpcprometheus.UnaryServerInterceptor, commandstatshandler.UnaryInterceptor, + limithandler.StatsUnaryInterceptor, grpcmwlogrus.UnaryServerInterceptor(s.logger, grpcmwlogrus.WithTimestampFormat(gitalylog.LogTimestampFormat), logMsgProducer, diff --git a/internal/gitaly/service/conflicts/resolve_conflicts_test.go b/internal/gitaly/service/conflicts/resolve_conflicts_test.go index 5efe7f6b9..948880ab5 100644 --- a/internal/gitaly/service/conflicts/resolve_conflicts_test.go +++ b/internal/gitaly/service/conflicts/resolve_conflicts_test.go @@ -20,6 +20,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" @@ -474,7 +475,7 @@ func TestResolveConflictsIdenticalContent(t *testing.T) { } { contents := gittest.Exec(t, cfg, "-C", repoPath, "cat-file", "-p", rev+":files/ruby/popen.rb") path := filepath.Join(tempDir, rev) - require.NoError(t, os.WriteFile(path, contents, 0o644)) + require.NoError(t, os.WriteFile(path, contents, perm.SharedFile)) conflictingPaths = append(conflictingPaths, path) } diff --git a/internal/gitaly/service/objectpool/alternates_test.go b/internal/gitaly/service/objectpool/alternates_test.go index 8b9a9205c..99687d6c5 100644 --- a/internal/gitaly/service/objectpool/alternates_test.go +++ b/internal/gitaly/service/objectpool/alternates_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" @@ -115,7 +116,7 @@ func testDisconnectGitAlternatesUnexpectedAlternates(t *testing.T, ctx context.C altPath, err := repo.InfoAlternatesPath() require.NoError(t, err) - require.NoError(t, os.WriteFile(altPath, []byte(tc.altContent), 0o644)) + require.NoError(t, os.WriteFile(altPath, []byte(tc.altContent), perm.SharedFile)) _, err = client.DisconnectGitAlternates(ctx, &gitalypb.DisconnectGitAlternatesRequest{Repository: repoProto}) require.Error(t, err) @@ -149,7 +150,7 @@ func testRemoveAlternatesIfOk(t *testing.T, ctx context.Context) { altPath, err := repo.InfoAlternatesPath() require.NoError(t, err) altContent := testhelper.TempDir(t) + "\n" - require.NoError(t, os.WriteFile(altPath, []byte(altContent), 0o644)) + require.NoError(t, os.WriteFile(altPath, []byte(altContent), perm.SharedFile)) // Intentionally break the repository so that the consistency check will cause an // error. @@ -177,7 +178,7 @@ func testRemoveAlternatesIfOk(t *testing.T, ctx context.Context) { altPath, err := repo.InfoAlternatesPath() require.NoError(t, err) altContent := testhelper.TempDir(t) + "\n" - require.NoError(t, os.WriteFile(altPath, []byte(altContent), 0o644)) + require.NoError(t, os.WriteFile(altPath, []byte(altContent), perm.SharedFile)) // In order to test the scenario where a commit is in a commit graph but not in the // object database, we will first write a new commit, write the commit graph, then diff --git a/internal/gitaly/service/objectpool/create_test.go b/internal/gitaly/service/objectpool/create_test.go index b4dba6096..edad5de8a 100644 --- a/internal/gitaly/service/objectpool/create_test.go +++ b/internal/gitaly/service/objectpool/create_test.go @@ -90,7 +90,7 @@ func TestCreate_unsuccessful(t *testing.T) { lockedRelativePath := gittest.NewObjectPoolName(t) lockedFullPath := filepath.Join(cfg.Storages[0].Path, lockedRelativePath+".lock") require.NoError(t, os.MkdirAll(filepath.Dir(lockedFullPath), perm.SharedDir)) - require.NoError(t, os.WriteFile(lockedFullPath, nil, 0o644)) + require.NoError(t, os.WriteFile(lockedFullPath, nil, perm.SharedFile)) // Create a preexisting object pool. preexistingPool := &gitalypb.ObjectPool{ diff --git a/internal/gitaly/service/objectpool/fetch_into_object_pool_test.go b/internal/gitaly/service/objectpool/fetch_into_object_pool_test.go index 1e73ef205..5c25adbeb 100644 --- a/internal/gitaly/service/objectpool/fetch_into_object_pool_test.go +++ b/internal/gitaly/service/objectpool/fetch_into_object_pool_test.go @@ -82,7 +82,7 @@ func testFetchIntoObjectPoolSuccess(t *testing.T, ctx context.Context) { // references though and thus be able to recover. brokenRef := filepath.Join(poolPath, "refs", "heads", "broken") require.NoError(t, os.MkdirAll(filepath.Dir(brokenRef), perm.SharedDir)) - require.NoError(t, os.WriteFile(brokenRef, []byte{}, 0o777)) + require.NoError(t, os.WriteFile(brokenRef, []byte{}, perm.PublicExecutable)) oldTime := time.Now().Add(-25 * time.Hour) require.NoError(t, os.Chtimes(brokenRef, oldTime, oldTime)) diff --git a/internal/gitaly/service/objectpool/get_test.go b/internal/gitaly/service/objectpool/get_test.go index c9789a607..aef3df684 100644 --- a/internal/gitaly/service/objectpool/get_test.go +++ b/internal/gitaly/service/objectpool/get_test.go @@ -57,7 +57,7 @@ func TestGetObjectPoolBadFile(t *testing.T) { alternatesFilePath := filepath.Join(repoPath, "objects", "info", "alternates") require.NoError(t, os.MkdirAll(filepath.Dir(alternatesFilePath), perm.SharedDir)) - require.NoError(t, os.WriteFile(alternatesFilePath, []byte("not-a-directory"), 0o644)) + require.NoError(t, os.WriteFile(alternatesFilePath, []byte("not-a-directory"), perm.SharedFile)) resp, err := client.GetObjectPool(ctx, &gitalypb.GetObjectPoolRequest{ Repository: repo, diff --git a/internal/gitaly/service/objectpool/link_test.go b/internal/gitaly/service/objectpool/link_test.go index b1f453450..aeb75de38 100644 --- a/internal/gitaly/service/objectpool/link_test.go +++ b/internal/gitaly/service/objectpool/link_test.go @@ -11,6 +11,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" @@ -106,7 +107,7 @@ func TestLink_noClobber(t *testing.T) { require.NoFileExists(t, alternatesFile) contentBefore := "mock/objects\n" - require.NoError(t, os.WriteFile(alternatesFile, []byte(contentBefore), 0o644)) + require.NoError(t, os.WriteFile(alternatesFile, []byte(contentBefore), perm.SharedFile)) request := &gitalypb.LinkRepositoryToObjectPoolRequest{ Repository: repoProto, diff --git a/internal/gitaly/service/repository/apply_gitattributes.go b/internal/gitaly/service/repository/apply_gitattributes.go index 6b10b13aa..79a12259a 100644 --- a/internal/gitaly/service/repository/apply_gitattributes.go +++ b/internal/gitaly/service/repository/apply_gitattributes.go @@ -22,7 +22,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) -const attributesFileMode os.FileMode = 0o644 +const attributesFileMode os.FileMode = perm.SharedFile func (s *server) applyGitattributes(ctx context.Context, repo *localrepo.Repo, objectReader catfile.ObjectContentReader, repoPath string, revision []byte) (returnedErr error) { infoPath := filepath.Join(repoPath, "info") diff --git a/internal/gitaly/service/repository/apply_gitattributes_test.go b/internal/gitaly/service/repository/apply_gitattributes_test.go index 0eeb7ecb5..227d8e36e 100644 --- a/internal/gitaly/service/repository/apply_gitattributes_test.go +++ b/internal/gitaly/service/repository/apply_gitattributes_test.go @@ -69,7 +69,7 @@ func TestApplyGitattributes_successful(t *testing.T) { t.Run("with preexisting 'info/attributes'", func(t *testing.T) { require.NoError(t, os.RemoveAll(infoPath)) require.NoError(t, os.Mkdir(infoPath, perm.SharedDir)) - require.NoError(t, os.WriteFile(attributesPath, []byte("*.docx diff=word"), 0o644)) + require.NoError(t, os.WriteFile(attributesPath, []byte("*.docx diff=word"), perm.SharedFile)) requireApplyGitattributes(t, ctx, client, repo, attributesPath, tc.revision, tc.expectedContent) }) }) diff --git a/internal/gitaly/service/repository/archive_test.go b/internal/gitaly/service/repository/archive_test.go index fa1c1a1aa..e48111ac0 100644 --- a/internal/gitaly/service/repository/archive_test.go +++ b/internal/gitaly/service/repository/archive_test.go @@ -18,6 +18,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/smudge" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" @@ -551,7 +552,7 @@ func TestGetArchive_environment(t *testing.T) { func compressedFileContents(t *testing.T, format gitalypb.GetArchiveRequest_Format, contents []byte) string { path := filepath.Join(testhelper.TempDir(t), "archive") - require.NoError(t, os.WriteFile(path, contents, 0o644)) + require.NoError(t, os.WriteFile(path, contents, perm.SharedFile)) switch format { case gitalypb.GetArchiveRequest_TAR: diff --git a/internal/gitaly/service/repository/backup_custom_hooks_test.go b/internal/gitaly/service/repository/backup_custom_hooks_test.go index 9c897bcd2..62d42ddbc 100644 --- a/internal/gitaly/service/repository/backup_custom_hooks_test.go +++ b/internal/gitaly/service/repository/backup_custom_hooks_test.go @@ -36,7 +36,7 @@ func TestBackupCustomHooks_successful(t *testing.T) { } require.NoError(t, os.Mkdir(filepath.Join(repoPath, "custom_hooks"), perm.PrivateDir), "Could not create custom_hooks dir") for _, fileName := range expectedTarResponse[1:] { - require.NoError(t, os.WriteFile(filepath.Join(repoPath, fileName), []byte("Some hooks"), 0o700), fmt.Sprintf("Could not create %s", fileName)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, fileName), []byte("Some hooks"), perm.PrivateExecutable), fmt.Sprintf("Could not create %s", fileName)) } backupRequest := &gitalypb.BackupCustomHooksRequest{Repository: repo} diff --git a/internal/gitaly/service/repository/create_fork_test.go b/internal/gitaly/service/repository/create_fork_test.go index 9b40586b3..cb936e263 100644 --- a/internal/gitaly/service/repository/create_fork_test.go +++ b/internal/gitaly/service/repository/create_fork_test.go @@ -244,7 +244,7 @@ func TestCreateFork_targetExists(t *testing.T) { require.NoError(t, os.WriteFile( filepath.Join(targetPath, "config"), nil, - 0o644, + perm.SharedFile, )) }, expectedErrWithAtomicCreation: structerr.NewAlreadyExists("creating fork: repository exists already"), @@ -253,7 +253,7 @@ func TestCreateFork_targetExists(t *testing.T) { desc: "target file", seed: func(t *testing.T, targetPath string) { require.NoError(t, os.MkdirAll(filepath.Dir(targetPath), perm.GroupPrivateDir)) - require.NoError(t, os.WriteFile(targetPath, nil, 0o644)) + require.NoError(t, os.WriteFile(targetPath, nil, perm.SharedFile)) }, expectedErrWithAtomicCreation: structerr.NewAlreadyExists("creating fork: repository exists already"), }, diff --git a/internal/gitaly/service/repository/create_repository_from_url_test.go b/internal/gitaly/service/repository/create_repository_from_url_test.go index d06eec7ae..63df6ae02 100644 --- a/internal/gitaly/service/repository/create_repository_from_url_test.go +++ b/internal/gitaly/service/repository/create_repository_from_url_test.go @@ -134,7 +134,7 @@ func TestCreateRepositoryFromURL_existingTarget(t *testing.T) { require.NoError(t, os.MkdirAll(importedRepoPath, perm.GroupPrivateDir)) } else { require.NoError(t, os.MkdirAll(filepath.Dir(importedRepoPath), perm.PublicDir)) - require.NoError(t, os.WriteFile(importedRepoPath, nil, 0o644)) + require.NoError(t, os.WriteFile(importedRepoPath, nil, perm.SharedFile)) } t.Cleanup(func() { require.NoError(t, os.RemoveAll(importedRepoPath)) }) diff --git a/internal/gitaly/service/repository/fetch_remote_test.go b/internal/gitaly/service/repository/fetch_remote_test.go index 36c596379..22d52137c 100644 --- a/internal/gitaly/service/repository/fetch_remote_test.go +++ b/internal/gitaly/service/repository/fetch_remote_test.go @@ -15,6 +15,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" @@ -1121,7 +1122,7 @@ func TestFetchRemote_pooledRepository(t *testing.T) { // Create the pooled repository and link it to its pool. This is the // repository we're fetching into. pooledRepoProto, pooledRepoPath := gittest.CreateRepository(t, ctx, cfg) - require.NoError(t, os.WriteFile(filepath.Join(pooledRepoPath, "objects", "info", "alternates"), []byte(filepath.Join(poolRepoPath, "objects")), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(pooledRepoPath, "objects", "info", "alternates"), []byte(filepath.Join(poolRepoPath, "objects")), perm.SharedFile)) // And then finally create a third repository that emulates the remote side // we're fetching from. We need to create at least one reference so that Git diff --git a/internal/gitaly/service/repository/fsck_test.go b/internal/gitaly/service/repository/fsck_test.go index 6bf337388..bbaf8e617 100644 --- a/internal/gitaly/service/repository/fsck_test.go +++ b/internal/gitaly/service/repository/fsck_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" @@ -77,7 +78,7 @@ func TestFsck(t *testing.T) { // This makes the repo severely broken so that `git` does not // identify it as a proper repository anymore. require.NoError(t, os.RemoveAll(filepath.Join(repoPath, "objects"))) - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "objects"), nil, 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "objects"), nil, perm.SharedFile)) return setupData{ repo: repo, diff --git a/internal/gitaly/service/repository/gc_test.go b/internal/gitaly/service/repository/gc_test.go index 97ea88b17..b6fe71cee 100644 --- a/internal/gitaly/service/repository/gc_test.go +++ b/internal/gitaly/service/repository/gc_test.go @@ -557,11 +557,11 @@ func testCleanupInvalidKeepAroundRefs(t *testing.T, ctx context.Context) { // Create an invalid ref that should should be removed with the testcase bogusSha := "b3f5e4adf6277b571b7943a4f0405a6dd7ee7e15" bogusPath := filepath.Join(repoPath, fmt.Sprintf("refs/keep-around/%s", bogusSha)) - require.NoError(t, os.WriteFile(bogusPath, []byte(bogusSha), 0o644)) + require.NoError(t, os.WriteFile(bogusPath, []byte(bogusSha), perm.SharedFile)) // Creating the keeparound without using git so we can create invalid ones in testcases refPath := filepath.Join(repoPath, fmt.Sprintf("refs/keep-around/%s", testcase.refName)) - require.NoError(t, os.WriteFile(refPath, []byte(testcase.refContent), 0o644)) + require.NoError(t, os.WriteFile(refPath, []byte(testcase.refContent), perm.SharedFile)) // Perform the request req := &gitalypb.GarbageCollectRequest{Repository: repo} @@ -591,7 +591,7 @@ func mustCreateFileWithTimes(tb testing.TB, path string, mTime time.Time) { tb.Helper() require.NoError(tb, os.MkdirAll(filepath.Dir(path), perm.SharedDir)) - require.NoError(tb, os.WriteFile(path, nil, 0o644)) + require.NoError(tb, os.WriteFile(path, nil, perm.SharedFile)) require.NoError(tb, os.Chtimes(path, mTime, mTime)) } diff --git a/internal/gitaly/service/repository/info_attributes_test.go b/internal/gitaly/service/repository/info_attributes_test.go index 7c5ea034d..d8fe03690 100644 --- a/internal/gitaly/service/repository/info_attributes_test.go +++ b/internal/gitaly/service/repository/info_attributes_test.go @@ -30,7 +30,7 @@ func TestGetInfoAttributesExisting(t *testing.T) { buffSize := streamio.WriteBufferSize + 1 data := bytes.Repeat([]byte("*.pbxproj binary\n"), buffSize) attrsPath := filepath.Join(infoPath, "attributes") - err := os.WriteFile(attrsPath, data, 0o644) + err := os.WriteFile(attrsPath, data, perm.SharedFile) require.NoError(t, err) request := &gitalypb.GetInfoAttributesRequest{Repository: repo} diff --git a/internal/gitaly/service/repository/midx_test.go b/internal/gitaly/service/repository/midx_test.go index ce5fc108f..5d7e15c4e 100644 --- a/internal/gitaly/service/repository/midx_test.go +++ b/internal/gitaly/service/repository/midx_test.go @@ -23,6 +23,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/stats" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" @@ -64,7 +65,7 @@ func TestMidxRewrite(t *testing.T) { // Create an invalid multi-pack-index file // with mtime update being the basis for comparison - require.NoError(t, os.WriteFile(midxPath, nil, 0o644)) + require.NoError(t, os.WriteFile(midxPath, nil, perm.SharedFile)) require.NoError(t, os.Chtimes(midxPath, time.Time{}, time.Time{})) info, err := os.Stat(midxPath) require.NoError(t, err) diff --git a/internal/gitaly/service/repository/object_format_test.go b/internal/gitaly/service/repository/object_format_test.go index 2cc8e738a..80d41c36f 100644 --- a/internal/gitaly/service/repository/object_format_test.go +++ b/internal/gitaly/service/repository/object_format_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/errors" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" @@ -144,7 +145,7 @@ func TestObjectFormat(t *testing.T) { "[extensions]", "objectFormat = blake2b", }, "\n"), - ), 0o644)) + ), perm.SharedFile)) return setupData{ request: &gitalypb.ObjectFormatRequest{ diff --git a/internal/gitaly/service/repository/remove_test.go b/internal/gitaly/service/repository/remove_test.go index 06e54c58c..d777ecdfa 100644 --- a/internal/gitaly/service/repository/remove_test.go +++ b/internal/gitaly/service/repository/remove_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" @@ -67,7 +68,7 @@ func TestRemoveRepository_locking(t *testing.T) { // Simulate a concurrent RPC holding the repository lock. lockPath := repoPath + ".lock" - require.NoError(t, os.WriteFile(lockPath, []byte{}, 0o644)) + require.NoError(t, os.WriteFile(lockPath, []byte{}, perm.SharedFile)) defer func() { require.NoError(t, os.RemoveAll(lockPath)) }() _, err := client.RemoveRepository(ctx, &gitalypb.RemoveRepositoryRequest{Repository: repo}) diff --git a/internal/gitaly/service/repository/replicate.go b/internal/gitaly/service/repository/replicate.go index a5eb1ab11..5d442e1a2 100644 --- a/internal/gitaly/service/repository/replicate.go +++ b/internal/gitaly/service/repository/replicate.go @@ -279,7 +279,7 @@ func (s *server) syncGitconfig(ctx context.Context, in *gitalypb.ReplicateReposi } configPath := filepath.Join(repoPath, "config") - if err := s.writeFile(ctx, configPath, 0o644, streamio.NewReader(func() ([]byte, error) { + if err := s.writeFile(ctx, configPath, perm.SharedFile, streamio.NewReader(func() ([]byte, error) { resp, err := stream.Recv() return resp.GetData(), err })); err != nil { diff --git a/internal/gitaly/service/repository/replicate_test.go b/internal/gitaly/service/repository/replicate_test.go index ca10e838f..8e87ae0cd 100644 --- a/internal/gitaly/service/repository/replicate_test.go +++ b/internal/gitaly/service/repository/replicate_test.go @@ -66,7 +66,7 @@ func TestReplicateRepository(t *testing.T) { attrFilePath := filepath.Join(repoPath, "info", "attributes") require.NoError(t, os.MkdirAll(filepath.Dir(attrFilePath), perm.SharedDir)) attrData := []byte("*.pbxproj binary\n") - require.NoError(t, os.WriteFile(attrFilePath, attrData, 0o644)) + require.NoError(t, os.WriteFile(attrFilePath, attrData, perm.SharedFile)) // Write a modified gitconfig gittest.Exec(t, cfg, "-C", repoPath, "config", "please.replicate", "me") @@ -489,7 +489,7 @@ func TestReplicateRepository_FailedFetchInternalRemote(t *testing.T) { }) // We corrupt the repository by writing garbage into HEAD. - require.NoError(t, os.WriteFile(filepath.Join(sourceRepoPath, "HEAD"), []byte("garbage"), 0o666)) + require.NoError(t, os.WriteFile(filepath.Join(sourceRepoPath, "HEAD"), []byte("garbage"), perm.PublicFile)) ctx = testhelper.MergeOutgoingMetadata(ctx, testcfg.GitalyServersMetadataFromCfg(t, cfg)) @@ -532,7 +532,7 @@ func listenGitalySSHCalls(t *testing.T, conf config.Cfg) func() gitalySSHParams echo "$@" >%[1]q/arguments exec %[2]q "$@"`, tmpDir, updatedPath) - require.NoError(t, os.WriteFile(initialPath, []byte(script), 0o755)) + require.NoError(t, os.WriteFile(initialPath, []byte(script), perm.SharedExecutable)) return func() gitalySSHParams { arguments := testhelper.MustReadFile(t, filepath.Join(tmpDir, "arguments")) diff --git a/internal/gitaly/service/repository/restore_custom_hooks_test.go b/internal/gitaly/service/repository/restore_custom_hooks_test.go index f9bee0ba1..10a3a5c5e 100644 --- a/internal/gitaly/service/repository/restore_custom_hooks_test.go +++ b/internal/gitaly/service/repository/restore_custom_hooks_test.go @@ -178,32 +178,32 @@ func TestNewDirectoryVote(t *testing.T) { { desc: "generated hash matches", files: []testFile{ - {name: "pre-commit.sample", content: "foo", mode: 0o755}, - {name: "pre-push.sample", content: "bar", mode: 0o755}, + {name: "pre-commit.sample", content: "foo", mode: perm.SharedExecutable}, + {name: "pre-push.sample", content: "bar", mode: perm.SharedExecutable}, }, expectedHash: "8ca11991268de4c9278488a674fc1a88db449566", }, { desc: "generated hash matches with changed file name", files: []testFile{ - {name: "pre-commit.sample.diff", content: "foo", mode: 0o755}, - {name: "pre-push.sample", content: "bar", mode: 0o755}, + {name: "pre-commit.sample.diff", content: "foo", mode: perm.SharedExecutable}, + {name: "pre-push.sample", content: "bar", mode: perm.SharedExecutable}, }, expectedHash: "b5ed58ced84103da1ed9d7813a9e39b3b5daf7d7", }, { desc: "generated hash matches with changed file content", files: []testFile{ - {name: "pre-commit.sample", content: "foo", mode: 0o755}, - {name: "pre-push.sample", content: "bar.diff", mode: 0o755}, + {name: "pre-commit.sample", content: "foo", mode: perm.SharedExecutable}, + {name: "pre-push.sample", content: "bar.diff", mode: perm.SharedExecutable}, }, expectedHash: "178083848c8a08e36c4f86c2d318a84b0bb845f2", }, { desc: "generated hash matches with changed file mode", files: []testFile{ - {name: "pre-commit.sample", content: "foo", mode: 0o644}, - {name: "pre-push.sample", content: "bar", mode: 0o755}, + {name: "pre-commit.sample", content: "foo", mode: perm.SharedFile}, + {name: "pre-push.sample", content: "bar", mode: perm.SharedExecutable}, }, expectedHash: "c69574241b83496bb4005b4f7a0dfcda96cb317e", }, diff --git a/internal/gitaly/service/repository/snapshot_test.go b/internal/gitaly/service/repository/snapshot_test.go index 8a543c400..fe0780f08 100644 --- a/internal/gitaly/service/repository/snapshot_test.go +++ b/internal/gitaly/service/repository/snapshot_test.go @@ -46,7 +46,7 @@ func getSnapshot(tb testing.TB, client gitalypb.RepositoryServiceClient, req *gi func touch(t *testing.T, format string, args ...interface{}) { path := fmt.Sprintf(format, args...) - require.NoError(t, os.WriteFile(path, nil, 0o644)) + require.NoError(t, os.WriteFile(path, nil, perm.SharedFile)) } func TestGetSnapshotSuccess(t *testing.T) { @@ -137,7 +137,7 @@ func TestGetSnapshotWithDedupe(t *testing.T) { // Write alternates file to point to alt objects folder. alternatesPath, err := repo.InfoAlternatesPath() require.NoError(t, err) - require.NoError(t, os.WriteFile(alternatesPath, []byte(fmt.Sprintf("%s\n", alternateObjDir)), 0o644)) + require.NoError(t, os.WriteFile(alternatesPath, []byte(fmt.Sprintf("%s\n", alternateObjDir)), perm.SharedFile)) // Write another commit into the alternate object directory. secondCommitID := gittest.WriteCommit(t, cfg, repoPath, @@ -178,7 +178,7 @@ func TestGetSnapshot_alternateObjectDirectory(t *testing.T) { t.Run("nonexistent", func(t *testing.T) { alternateObjectDir := filepath.Join(repoPath, "does-not-exist") - require.NoError(t, os.WriteFile(alternatesFile, []byte(fmt.Sprintf("%s\n", alternateObjectDir)), 0o644)) + require.NoError(t, os.WriteFile(alternatesFile, []byte(fmt.Sprintf("%s\n", alternateObjectDir)), perm.SharedFile)) defer func() { require.NoError(t, os.Remove(alternatesFile)) }() @@ -193,7 +193,7 @@ func TestGetSnapshot_alternateObjectDirectory(t *testing.T) { alternateObjectDir := filepath.Join(storageRoot, "..") - require.NoError(t, os.WriteFile(alternatesFile, []byte(alternateObjectDir), 0o600)) + require.NoError(t, os.WriteFile(alternatesFile, []byte(alternateObjectDir), perm.PrivateFile)) defer func() { require.NoError(t, os.Remove(alternatesFile)) }() @@ -224,7 +224,7 @@ func TestGetSnapshot_alternateObjectDirectory(t *testing.T) { gittest.WithBranch("some-branch"), ) - require.NoError(t, os.WriteFile(alternatesFile, []byte(alternateObjectDir), 0o644)) + require.NoError(t, os.WriteFile(alternatesFile, []byte(alternateObjectDir), perm.SharedFile)) defer func() { require.NoError(t, os.Remove(alternatesFile)) }() diff --git a/internal/gitaly/service/server/info.go b/internal/gitaly/service/server/info.go index 59bd88269..bc3663ba8 100644 --- a/internal/gitaly/service/server/info.go +++ b/internal/gitaly/service/server/info.go @@ -8,6 +8,7 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/fstype" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "gitlab.com/gitlab-org/gitaly/v15/internal/version" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" @@ -55,7 +56,7 @@ func shardCheck(shardPath string) (readable bool, writeable bool) { testPath := filepath.Join(shardPath, "+testWrite") content := []byte("testWrite") - if err := os.WriteFile(testPath, content, 0o644); err == nil { + if err := os.WriteFile(testPath, content, perm.SharedFile); err == nil { writeable = true } _ = os.Remove(testPath) diff --git a/internal/gitaly/service/smarthttp/inforefs_test.go b/internal/gitaly/service/smarthttp/inforefs_test.go index 6fabe6a21..2c08a5e88 100644 --- a/internal/gitaly/service/smarthttp/inforefs_test.go +++ b/internal/gitaly/service/smarthttp/inforefs_test.go @@ -545,7 +545,7 @@ func createInvalidRepo(tb testing.TB, repoDir string) func() { func replaceCachedResponse(tb testing.TB, ctx context.Context, cache *cache.DiskCache, req *gitalypb.InfoRefsRequest, newContents string) { path := pathToCachedResponse(tb, ctx, cache, req) - require.NoError(tb, os.WriteFile(path, []byte(newContents), 0o644)) + require.NoError(tb, os.WriteFile(path, []byte(newContents), perm.SharedFile)) } func setInfoRefsUploadPackMethod(ctx context.Context) context.Context { diff --git a/internal/gitaly/service/ssh/receive_pack_test.go b/internal/gitaly/service/ssh/receive_pack_test.go index 20d951445..8d3e7fbbe 100644 --- a/internal/gitaly/service/ssh/receive_pack_test.go +++ b/internal/gitaly/service/ssh/receive_pack_test.go @@ -12,7 +12,6 @@ import ( "path/filepath" "strings" "testing" - "time" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" @@ -24,7 +23,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" - "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" @@ -143,11 +142,10 @@ func TestReceivePack_success(t *testing.T) { cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(gitCmdFactory)) - repo, repoPath := gittest.CreateRepository(t, ctx, cfg) - gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) - - glRepository := "project-456" - glProjectPath := "project/path" + remoteRepo, remoteRepoPath := gittest.CreateRepository(t, ctx, cfg) + gittest.WriteCommit(t, cfg, remoteRepoPath, gittest.WithBranch("main")) + remoteRepo.GlProjectPath = "project/path" + remoteRepo.GlRepository = "project-456" // We're explicitly injecting feature flags here because if we didn't, then Praefect would // do so for us and inject them all with their default value. As a result, we'd see @@ -159,12 +157,11 @@ func TestReceivePack_success(t *testing.T) { ctx = featureflag.ContextWithFeatureFlag(ctx, featureFlag, true) } - lHead, rHead, err := testCloneAndPush(t, ctx, cfg, cfg.SocketPath, repo, repoPath, pushParams{ - storageName: cfg.Storages[0].Name, - glID: "123", - glUsername: "user", - glRepository: glRepository, - glProjectPath: glProjectPath, + lHead, rHead, err := setupRepoAndPush(t, ctx, cfg, &gitalypb.SSHReceivePackRequest{ + Repository: remoteRepo, + GlId: "123", + GlUsername: "user", + GlRepository: remoteRepo.GlRepository, }) require.NoError(t, err) require.Equal(t, lHead, rHead, "local and remote head not equal. push failed") @@ -177,9 +174,9 @@ func TestReceivePack_success(t *testing.T) { // the remaining values. testhelper.ProtoEqual(t, &gitalypb.Repository{ StorageName: cfg.Storages[0].Name, - RelativePath: gittest.GetReplicaPath(t, ctx, cfg, repo), - GlProjectPath: glProjectPath, - GlRepository: glRepository, + RelativePath: gittest.GetReplicaPath(t, ctx, cfg, remoteRepo), + GlProjectPath: remoteRepo.GlProjectPath, + GlRepository: remoteRepo.GlRepository, }, payload.Repo) payload.Repo = nil @@ -222,16 +219,16 @@ func TestReceivePack_invalidGitconfig(t *testing.T) { testcfg.BuildGitalySSH(t, cfg) testcfg.BuildGitalyHooks(t, cfg) - repo, repoPath := gittest.CreateRepository(t, ctx, cfg) - gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "config"), []byte("x x x foobar"), 0o644)) + remoteRepo, remoteRepoPath := gittest.CreateRepository(t, ctx, cfg) + gittest.WriteCommit(t, cfg, remoteRepoPath, gittest.WithBranch("main")) + require.NoError(t, os.WriteFile(filepath.Join(remoteRepoPath, "config"), []byte("x x x foobar"), perm.SharedFile)) + remoteRepo.GlProjectPath = "something" - lHead, rHead, err := testCloneAndPush(t, ctx, cfg, cfg.SocketPath, repo, repoPath, pushParams{ - storageName: cfg.Storages[0].Name, - glID: "123", - glUsername: "user", - glRepository: "something", - glProjectPath: "something", + lHead, rHead, err := setupRepoAndPush(t, ctx, cfg, &gitalypb.SSHReceivePackRequest{ + Repository: remoteRepo, + GlId: "123", + GlUsername: "user", + GlRepository: "something", }) require.Error(t, err) require.Equal(t, lHead, rHead, "local and remote head not equal. push failed") @@ -333,14 +330,14 @@ func TestReceive_gitProtocol(t *testing.T) { cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(protocolDetectingFactory)) - repo, repoPath := gittest.CreateRepository(t, ctx, cfg) - gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main")) + remoteRepo, remoteRepoPath := gittest.CreateRepository(t, ctx, cfg) + gittest.WriteCommit(t, cfg, remoteRepoPath, gittest.WithBranch("main")) - lHead, rHead, err := testCloneAndPush(t, ctx, cfg, cfg.SocketPath, repo, repoPath, pushParams{ - storageName: testhelper.DefaultStorageName, - glRepository: "project-123", - glID: "1", - gitProtocol: git.ProtocolV2, + lHead, rHead, err := setupRepoAndPush(t, ctx, cfg, &gitalypb.SSHReceivePackRequest{ + Repository: remoteRepo, + GlRepository: "project-123", + GlId: "1", + GitProtocol: git.ProtocolV2, }) require.NoError(t, err) require.Equal(t, lHead, rHead) @@ -360,12 +357,15 @@ func TestReceivePack_hookFailure(t *testing.T) { cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(gitCmdFactory)) - repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + remoteRepo, _ := gittest.CreateRepository(t, ctx, cfg) hookContent := []byte("#!/bin/sh\nexit 1") - require.NoError(t, os.WriteFile(filepath.Join(gitCmdFactory.HooksPath(ctx), "pre-receive"), hookContent, 0o755)) + require.NoError(t, os.WriteFile(filepath.Join(gitCmdFactory.HooksPath(ctx), "pre-receive"), hookContent, perm.SharedExecutable)) - _, _, err := testCloneAndPush(t, ctx, cfg, cfg.SocketPath, repo, repoPath, pushParams{storageName: cfg.Storages[0].Name, glID: "1"}) + _, _, err := setupRepoAndPush(t, ctx, cfg, &gitalypb.SSHReceivePackRequest{ + Repository: remoteRepo, + GlId: "1", + }) require.Error(t, err) require.Contains(t, err.Error(), "(pre-receive hook declined)") } @@ -380,20 +380,17 @@ func TestReceivePack_customHookFailure(t *testing.T) { testcfg.BuildGitalySSH(t, cfg) testcfg.BuildGitalyHooks(t, cfg) - repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + remoteRepo, remoteRepoPath := gittest.CreateRepository(t, ctx, cfg) - cloneDetails, cleanup := setupSSHClone(t, cfg, repo, repoPath) - defer cleanup() + localRepo := setupRepoWithChange(t, cfg) hookContent := []byte("#!/bin/sh\necho 'this is wrong' >&2;exit 1") - gittest.WriteCustomHook(t, cloneDetails.RemoteRepoPath, "pre-receive", hookContent) + gittest.WriteCustomHook(t, remoteRepoPath, "pre-receive", hookContent) - cmd := sshPushCommand(t, ctx, cfg, cloneDetails, cfg.SocketPath, - pushParams{ - storageName: cfg.Storages[0].Name, - glID: "1", - glRepository: repo.GlRepository, - }) + cmd := sshPushCommand(t, ctx, cfg, localRepo, &gitalypb.SSHReceivePackRequest{ + Repository: remoteRepo, + GlId: "1", + }) stdout, err := cmd.StdoutPipe() require.NoError(t, err) @@ -691,14 +688,13 @@ func TestReceivePack_objectExistsHook(t *testing.T) { protocolDetectingFactory := gittest.NewProtocolDetectingCommandFactory(t, ctx, cfg) cfg.SocketPath = runSSHServer(t, cfg, testserver.WithGitCommandFactory(protocolDetectingFactory)) - repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + remoteRepo, remoteRepoPath := gittest.CreateRepository(t, ctx, cfg) tempGitlabShellDir := testhelper.TempDir(t) cfg.GitlabShell.Dir = tempGitlabShellDir - cloneDetails, cleanup := setupSSHClone(t, cfg, repo, repoPath) - defer cleanup() + localRepo := setupRepoWithChange(t, cfg) serverURL, cleanup := gitlab.NewTestServer(t, gitlab.TestServerOptions{ User: "", @@ -706,7 +702,7 @@ func TestReceivePack_objectExistsHook(t *testing.T) { SecretToken: secretToken, GLID: glID, GLRepository: glRepository, - Changes: fmt.Sprintf("%s %s refs/heads/master\n", string(cloneDetails.OldHead), string(cloneDetails.NewHead)), + Changes: fmt.Sprintf("%s %s refs/heads/master\n", localRepo.oldHead, localRepo.newHead), PostReceiveCounterDecreased: true, Protocol: "ssh", }) @@ -717,13 +713,13 @@ func TestReceivePack_objectExistsHook(t *testing.T) { cfg.Gitlab.URL = serverURL cfg.Gitlab.SecretFile = filepath.Join(tempGitlabShellDir, ".gitlab_shell_secret") - gittest.WriteCheckNewObjectExistsHook(t, cloneDetails.RemoteRepoPath) + gittest.WriteCheckNewObjectExistsHook(t, remoteRepoPath) - lHead, rHead, err := sshPush(t, ctx, cfg, cloneDetails, cfg.SocketPath, pushParams{ - storageName: cfg.Storages[0].Name, - glID: glID, - glRepository: glRepository, - gitProtocol: git.ProtocolV2, + lHead, rHead, err := sshPush(t, ctx, cfg, localRepo, &gitalypb.SSHReceivePackRequest{ + Repository: remoteRepo, + GlId: glID, + GlRepository: glRepository, + GitProtocol: git.ProtocolV2, }) require.NoError(t, err) require.Equal(t, lHead, rHead, "local and remote head not equal. push failed") @@ -732,60 +728,44 @@ func TestReceivePack_objectExistsHook(t *testing.T) { require.Contains(t, envData, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2)) } -// SSHCloneDetails encapsulates values relevant for a test clone -type SSHCloneDetails struct { - LocalRepoPath, RemoteRepoPath, TempRepo string - OldHead []byte - NewHead []byte +// repoWithChange represents a repository with two commits representing an "old" and "new" state. +type repoWithChange struct { + path string + oldHead git.ObjectID + newHead git.ObjectID } -// setupSSHClone sets up a test clone -func setupSSHClone(t *testing.T, cfg config.Cfg, remoteRepo *gitalypb.Repository, remoteRepoPath string) (SSHCloneDetails, func()) { +// setupRepoWithChange sets up a new Git repository with an "old" and a "new" commit that represent +// a single change. +func setupRepoWithChange(t *testing.T, cfg config.Cfg) repoWithChange { ctx := testhelper.Context(t) - _, localRepoPath := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{ - Seed: gittest.SeedGitLabTest, - }) + _, localRepoPath := gittest.CreateRepository(t, ctx, cfg) - oldHead := text.ChompBytes(gittest.Exec(t, cfg, "-C", localRepoPath, "rev-parse", "HEAD")) + oldHead := gittest.WriteCommit(t, cfg, localRepoPath, + gittest.WithMessage("old message"), + gittest.WithTreeEntries(gittest.TreeEntry{ + Path: "foo.txt", Mode: "100644", Content: "old content", + }), + ) newHead := gittest.WriteCommit(t, cfg, localRepoPath, - gittest.WithMessage(fmt.Sprintf("Testing ReceivePack RPC around %d", time.Now().Unix())), + gittest.WithMessage("new message"), gittest.WithTreeEntries(gittest.TreeEntry{ - Path: "foo.txt", - Mode: "100644", - Content: "foo bar", + Path: "foo.txt", Mode: "100644", Content: "new content", }), gittest.WithBranch("master"), - gittest.WithParents(git.ObjectID(oldHead)), + gittest.WithParents(oldHead), ) - return SSHCloneDetails{ - OldHead: []byte(oldHead), - NewHead: []byte(newHead.String()), - LocalRepoPath: localRepoPath, - RemoteRepoPath: remoteRepoPath, - TempRepo: remoteRepo.GetRelativePath(), - }, func() { - require.NoError(t, os.RemoveAll(remoteRepoPath)) - require.NoError(t, os.RemoveAll(localRepoPath)) - } + return repoWithChange{ + path: localRepoPath, + oldHead: oldHead, + newHead: newHead, + } } -func sshPushCommand(t *testing.T, ctx context.Context, cfg config.Cfg, cloneDetails SSHCloneDetails, serverSocketPath string, params pushParams) *exec.Cmd { - pbTempRepo := &gitalypb.Repository{ - StorageName: params.storageName, - RelativePath: cloneDetails.TempRepo, - GlProjectPath: params.glProjectPath, - GlRepository: params.glRepository, - } - payload, err := protojson.Marshal(&gitalypb.SSHReceivePackRequest{ - Repository: pbTempRepo, - GlRepository: params.glRepository, - GlId: params.glID, - GlUsername: params.glUsername, - GitConfigOptions: params.gitConfigOptions, - GitProtocol: params.gitProtocol, - }) +func sshPushCommand(t *testing.T, ctx context.Context, cfg config.Cfg, repo repoWithChange, request *gitalypb.SSHReceivePackRequest) *exec.Cmd { + payload, err := protojson.Marshal(request) require.NoError(t, err) var flagsWithValues []string @@ -793,10 +773,10 @@ func sshPushCommand(t *testing.T, ctx context.Context, cfg config.Cfg, cloneDeta flagsWithValues = append(flagsWithValues, flag.FormatWithValue(value)) } - cmd := gittest.NewCommand(t, cfg, "-C", cloneDetails.LocalRepoPath, "push", "-v", "git@localhost:test/test.git", "master") + cmd := gittest.NewCommand(t, cfg, "-C", repo.path, "push", "-v", "git@localhost:test/test.git", "master") cmd.Env = append(cmd.Env, fmt.Sprintf("GITALY_PAYLOAD=%s", payload), - fmt.Sprintf("GITALY_ADDRESS=%s", serverSocketPath), + fmt.Sprintf("GITALY_ADDRESS=%s", cfg.SocketPath), fmt.Sprintf("GITALY_FEATUREFLAGS=%s", strings.Join(flagsWithValues, ",")), fmt.Sprintf("GIT_SSH_COMMAND=%s receive-pack", cfg.BinaryPath("gitaly-ssh")), ) @@ -804,8 +784,8 @@ func sshPushCommand(t *testing.T, ctx context.Context, cfg config.Cfg, cloneDeta return cmd } -func sshPush(t *testing.T, ctx context.Context, cfg config.Cfg, cloneDetails SSHCloneDetails, serverSocketPath string, params pushParams) (string, string, error) { - cmd := sshPushCommand(t, ctx, cfg, cloneDetails, serverSocketPath, params) +func sshPush(t *testing.T, ctx context.Context, cfg config.Cfg, repo repoWithChange, request *gitalypb.SSHReceivePackRequest) (string, string, error) { + cmd := sshPushCommand(t, ctx, cfg, repo, request) out, err := cmd.CombinedOutput() if err != nil { @@ -816,17 +796,16 @@ func sshPush(t *testing.T, ctx context.Context, cfg config.Cfg, cloneDetails SSH return "", "", fmt.Errorf("failed to run `git push`: %q", out) } - localHead := bytes.TrimSpace(gittest.Exec(t, cfg, "-C", cloneDetails.LocalRepoPath, "rev-parse", "master")) - remoteHead := bytes.TrimSpace(gittest.Exec(t, cfg, "-C", cloneDetails.RemoteRepoPath, "rev-parse", "master")) + remoteRepoPath := filepath.Join(cfg.Storages[0].Path, gittest.GetReplicaPath(t, ctx, cfg, request.Repository)) + + localHead := bytes.TrimSpace(gittest.Exec(t, cfg, "-C", repo.path, "rev-parse", "master")) + remoteHead := bytes.TrimSpace(gittest.Exec(t, cfg, "-C", remoteRepoPath, "rev-parse", "master")) return string(localHead), string(remoteHead), nil } -func testCloneAndPush(t *testing.T, ctx context.Context, cfg config.Cfg, serverSocketPath string, remoteRepo *gitalypb.Repository, remoteRepoPath string, params pushParams) (string, string, error) { - cloneDetails, cleanup := setupSSHClone(t, cfg, remoteRepo, remoteRepoPath) - defer cleanup() - - return sshPush(t, ctx, cfg, cloneDetails, serverSocketPath, params) +func setupRepoAndPush(t *testing.T, ctx context.Context, cfg config.Cfg, request *gitalypb.SSHReceivePackRequest) (string, string, error) { + return sshPush(t, ctx, cfg, setupRepoWithChange(t, cfg), request) } func drainPostReceivePackResponse(stream gitalypb.SSHService_SSHReceivePackClient) error { @@ -836,13 +815,3 @@ func drainPostReceivePackResponse(stream gitalypb.SSHService_SSHReceivePackClien } return err } - -type pushParams struct { - storageName string - glID string - glUsername string - glRepository string - glProjectPath string - gitConfigOptions []string - gitProtocol string -} diff --git a/internal/gitaly/service/ssh/upload_pack_test.go b/internal/gitaly/service/ssh/upload_pack_test.go index 2dce494db..76aea6226 100644 --- a/internal/gitaly/service/ssh/upload_pack_test.go +++ b/internal/gitaly/service/ssh/upload_pack_test.go @@ -21,6 +21,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" @@ -781,7 +782,7 @@ func TestUploadPack_gitFailure(t *testing.T) { // Writing an invalid config will allow repo to pass the `IsGitDirectory` check but still // trigger an error when git tries to access the repo. - require.NoError(t, os.WriteFile(filepath.Join(repoPath, "config"), []byte("Not a valid gitconfig"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "config"), []byte("Not a valid gitconfig"), perm.SharedFile)) stream, err := client.SSHUploadPack(ctx) require.NoError(t, err) diff --git a/internal/gitaly/transaction/voting_test.go b/internal/gitaly/transaction/voting_test.go index 33a8ddccb..8431bc736 100644 --- a/internal/gitaly/transaction/voting_test.go +++ b/internal/gitaly/transaction/voting_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/safe" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo" @@ -207,7 +208,7 @@ func TestCommitLockedFile(t *testing.T) { VoteFn: func(context.Context, txinfo.Transaction, voting.Vote, voting.Phase) error { // This shouldn't typically happen given that the file is locked, // but we concurrently update the file after our first vote. - require.NoError(t, os.WriteFile(file, []byte("something"), 0o666)) + require.NoError(t, os.WriteFile(file, []byte("something"), perm.PublicFile)) return nil }, }, writer) diff --git a/internal/gitlab/test_server.go b/internal/gitlab/test_server.go index 89b0dad2d..c5b42ae28 100644 --- a/internal/gitlab/test_server.go +++ b/internal/gitlab/test_server.go @@ -29,7 +29,7 @@ func WriteShellSecretFile(tb testing.TB, dir, secretToken string) string { require.NoError(tb, os.MkdirAll(dir, perm.PublicDir)) filePath := filepath.Join(dir, ".gitlab_shell_secret") - require.NoError(tb, os.WriteFile(filePath, []byte(secretToken), 0o644)) + require.NoError(tb, os.WriteFile(filePath, []byte(secretToken), perm.SharedFile)) return filePath } diff --git a/internal/helper/perm/perm.go b/internal/helper/perm/perm.go index 4bb476949..869665384 100644 --- a/internal/helper/perm/perm.go +++ b/internal/helper/perm/perm.go @@ -22,4 +22,33 @@ const ( // PublicDir is the permission given for a directory that may be read or // written outside of gitaly. PublicDir fs.FileMode = 0o777 + + // PrivateWriteOnceFile is the most restrictive file permission. Given to + // files that are expected to be written only once and must be read only by + // gitaly. + PrivateWriteOnceFile fs.FileMode = 0o400 + + // PrivateFile is the permissions given for a file that must only be used + // by gitaly. + PrivateFile fs.FileMode = 0o600 + + // SharedFile is the permission given for a file that may be read outside + // of gitaly. + SharedFile fs.FileMode = 0o644 + + // PublicFile is the permission given for a file that may be read or + // written outside of gitaly. + PublicFile fs.FileMode = 0o666 + + // PrivateExecutable is the permissions given for an executable that must + // only be used by gitaly. + PrivateExecutable fs.FileMode = 0o700 + + // SharedExecutable is the permission given for an executable that may be + // executed outside of gitaly. + SharedExecutable fs.FileMode = 0o755 + + // PublicExecutable is the permission given for an executable that may be + // read or written outside of gitaly. + PublicExecutable fs.FileMode = 0o777 ) diff --git a/internal/log/hook.go b/internal/log/hook.go index 36a6c848d..96e348b42 100644 --- a/internal/log/hook.go +++ b/internal/log/hook.go @@ -7,6 +7,7 @@ import ( "path/filepath" "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" ) // HookLogger is a wrapper around *logrus.Logger @@ -24,7 +25,7 @@ func NewHookLogger() *HookLogger { return &HookLogger{logger: logger} } - logFile, err := os.OpenFile(filepath.Join(logDir, "gitaly_hooks.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644) + logFile, err := os.OpenFile(filepath.Join(logDir, "gitaly_hooks.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, perm.SharedFile) if err != nil { logger.SetOutput(io.Discard) } else { diff --git a/internal/middleware/commandstatshandler/commandstatshandler_test.go b/internal/middleware/commandstatshandler/commandstatshandler_test.go index 57e6e3a87..4caac7eee 100644 --- a/internal/middleware/commandstatshandler/commandstatshandler_test.go +++ b/internal/middleware/commandstatshandler/commandstatshandler_test.go @@ -32,6 +32,8 @@ func TestMain(m *testing.M) { } func createNewServer(t *testing.T, cfg config.Cfg, logger *logrus.Logger) *grpc.Server { + t.Helper() + logrusEntry := logrus.NewEntry(logger).WithField("test", t.Name()) opts := []grpc.ServerOption{ @@ -72,6 +74,8 @@ func getBufDialer(listener *bufconn.Listener) func(context.Context, string) (net } func TestInterceptor(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) cfg := testcfg.Build(t) @@ -86,19 +90,16 @@ func TestInterceptor(t *testing.T) { bufferSize := 1024 * 1024 listener := bufconn.Listen(bufferSize) - go func() { - err := s.Serve(listener) - require.NoError(t, err) - }() + go testhelper.MustServe(t, s, listener) tests := []struct { name string - performRPC func(ctx context.Context, client gitalypb.RefServiceClient) + performRPC func(t *testing.T, ctx context.Context, client gitalypb.RefServiceClient) expectedLogData map[string]interface{} }{ { name: "Unary", - performRPC: func(ctx context.Context, client gitalypb.RefServiceClient) { + performRPC: func(t *testing.T, ctx context.Context, client gitalypb.RefServiceClient) { req := &gitalypb.RefExistsRequest{Repository: repo, Ref: []byte("refs/foo")} _, err := client.RefExists(ctx, req) @@ -119,7 +120,7 @@ func TestInterceptor(t *testing.T) { }, { name: "Stream", - performRPC: func(ctx context.Context, client gitalypb.RefServiceClient) { + performRPC: func(t *testing.T, ctx context.Context, client gitalypb.RefServiceClient) { req := &gitalypb.ListRefsRequest{Repository: repo, Patterns: [][]byte{[]byte("refs/heads/")}} stream, err := client.ListRefs(ctx, req) @@ -148,7 +149,7 @@ func TestInterceptor(t *testing.T) { client := gitalypb.NewRefServiceClient(conn) - tt.performRPC(ctx, client) + tt.performRPC(t, ctx, client) logEntries := hook.AllEntries() require.Len(t, logEntries, 1) diff --git a/internal/middleware/limithandler/monitor.go b/internal/middleware/limithandler/monitor.go index 602ebcbb4..0c9ded13f 100644 --- a/internal/middleware/limithandler/monitor.go +++ b/internal/middleware/limithandler/monitor.go @@ -88,6 +88,10 @@ func (p *PromMonitor) Enter(ctx context.Context, acquireTime time.Duration) { } p.acquiringSecondsMetric.Observe(acquireTime.Seconds()) + + if stats := limitStatsFromContext(ctx); stats != nil { + stats.AddConcurrencyQueueMs(acquireTime.Milliseconds()) + } } // Exit is called when a request has finished processing diff --git a/internal/middleware/limithandler/stats.go b/internal/middleware/limithandler/stats.go new file mode 100644 index 000000000..5f77766fe --- /dev/null +++ b/internal/middleware/limithandler/stats.go @@ -0,0 +1,78 @@ +package limithandler + +import ( + "context" + "sync/atomic" + + grpcmw "github.com/grpc-ecosystem/go-grpc-middleware" + "github.com/sirupsen/logrus" + "google.golang.org/grpc" +) + +type limitStatsKey struct{} + +// LimitStats contains info about the concurrency limiter. +type LimitStats struct { + // concurrencyQueueMs milliseconds waiting in concurrency limit queue. + concurrencyQueueMs int64 +} + +// InitLimitStats initializes context with a per-RPC stats struct +func InitLimitStats(ctx context.Context) context.Context { + return context.WithValue(ctx, limitStatsKey{}, &LimitStats{}) +} + +// AddConcurrencyQueueMs adds queue time. +func (s *LimitStats) AddConcurrencyQueueMs(queueMs int64) { + atomic.AddInt64(&s.concurrencyQueueMs, queueMs) +} + +// Fields returns logging info. +func (s *LimitStats) Fields() logrus.Fields { + return logrus.Fields{ + "limit.concurrency_queue_ms": s.concurrencyQueueMs, + } +} + +// FieldsProducer extracts stats info from the context and returns it as a logging fields. +func FieldsProducer(ctx context.Context, _ error) logrus.Fields { + stats := limitStatsFromContext(ctx) + if stats != nil { + return stats.Fields() + } + return nil +} + +func limitStatsFromContext(ctx context.Context) *LimitStats { + v, ok := ctx.Value(limitStatsKey{}).(*LimitStats) + if !ok { + return nil + } + return v +} + +// stats interceptors are separate from middleware and serve one main purpose: +// initialize the stats object early, so that logrus can see it. +// it must be placed before the limithandler middleware + +// StatsUnaryInterceptor returns a Unary Interceptor that initializes the context +func StatsUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + ctx = InitLimitStats(ctx) + + res, err := handler(ctx, req) + + return res, err +} + +// StatsStreamInterceptor returns a Stream Interceptor +func StatsStreamInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + ctx := stream.Context() + ctx = InitLimitStats(ctx) + + wrapped := grpcmw.WrapServerStream(stream) + wrapped.WrappedContext = ctx + + err := handler(srv, wrapped) + + return err +} diff --git a/internal/middleware/limithandler/stats_interceptor_test.go b/internal/middleware/limithandler/stats_interceptor_test.go new file mode 100644 index 000000000..47274a7be --- /dev/null +++ b/internal/middleware/limithandler/stats_interceptor_test.go @@ -0,0 +1,154 @@ +//go:build !gitaly_test_sha256 + +package limithandler_test + +import ( + "context" + "io" + "net" + "testing" + + grpcmw "github.com/grpc-ecosystem/go-grpc-middleware" + grpcmwlogrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" + "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/ref" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/test/bufconn" +) + +func createNewServer(t *testing.T, cfg config.Cfg, logger *logrus.Logger) *grpc.Server { + t.Helper() + + logrusEntry := logrus.NewEntry(logger).WithField("test", t.Name()) + + concurrencyLimitHandler := limithandler.New( + cfg, + limithandler.LimitConcurrencyByRepo, + limithandler.WithConcurrencyLimiters, + ) + + opts := []grpc.ServerOption{ + grpc.StreamInterceptor(grpcmw.ChainStreamServer( + limithandler.StatsStreamInterceptor, + grpcmwlogrus.StreamServerInterceptor(logrusEntry, + grpcmwlogrus.WithTimestampFormat(log.LogTimestampFormat), + grpcmwlogrus.WithMessageProducer(log.MessageProducer(grpcmwlogrus.DefaultMessageProducer, limithandler.FieldsProducer))), + concurrencyLimitHandler.StreamInterceptor(), + )), + grpc.UnaryInterceptor(grpcmw.ChainUnaryServer( + limithandler.StatsUnaryInterceptor, + grpcmwlogrus.UnaryServerInterceptor(logrusEntry, + grpcmwlogrus.WithTimestampFormat(log.LogTimestampFormat), + grpcmwlogrus.WithMessageProducer(log.MessageProducer(grpcmwlogrus.DefaultMessageProducer, limithandler.FieldsProducer))), + concurrencyLimitHandler.UnaryInterceptor(), + )), + } + + server := grpc.NewServer(opts...) + + gitCommandFactory := gittest.NewCommandFactory(t, cfg) + catfileCache := catfile.NewCache(cfg) + t.Cleanup(catfileCache.Stop) + + gitalypb.RegisterRefServiceServer(server, ref.NewServer( + config.NewLocator(cfg), + gitCommandFactory, + transaction.NewManager(cfg, backchannel.NewRegistry()), + catfileCache, + )) + + return server +} + +func getBufDialer(listener *bufconn.Listener) func(context.Context, string) (net.Conn, error) { + return func(ctx context.Context, url string) (net.Conn, error) { + return listener.Dial() + } +} + +func TestInterceptor(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg := testcfg.Build(t) + + repo, _ := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + }) + + logger, hook := test.NewNullLogger() + + s := createNewServer(t, cfg, logger) + defer s.Stop() + + bufferSize := 1024 * 1024 + listener := bufconn.Listen(bufferSize) + go testhelper.MustServe(t, s, listener) + + tests := []struct { + name string + performRPC func(t *testing.T, ctx context.Context, client gitalypb.RefServiceClient) + expectedLogData []string + }{ + { + name: "Unary", + performRPC: func(t *testing.T, ctx context.Context, client gitalypb.RefServiceClient) { + req := &gitalypb.RefExistsRequest{Repository: repo, Ref: []byte("refs/foo")} + + _, err := client.RefExists(ctx, req) + require.NoError(t, err) + }, + expectedLogData: []string{"limit.concurrency_queue_ms"}, + }, + { + name: "Stream", + performRPC: func(t *testing.T, ctx context.Context, client gitalypb.RefServiceClient) { + req := &gitalypb.ListRefsRequest{Repository: repo, Patterns: [][]byte{[]byte("refs/heads/")}} + + stream, err := client.ListRefs(ctx, req) + require.NoError(t, err) + + for { + _, err := stream.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + } + }, + expectedLogData: []string{"limit.concurrency_queue_ms"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hook.Reset() + + conn, err := grpc.DialContext(ctx, "", grpc.WithContextDialer(getBufDialer(listener)), grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err) + defer conn.Close() + + client := gitalypb.NewRefServiceClient(conn) + + tt.performRPC(t, ctx, client) + + logEntries := hook.AllEntries() + require.Len(t, logEntries, 1) + for _, expectedLogKey := range tt.expectedLogData { + require.Contains(t, logEntries[0].Data, expectedLogKey) + } + }) + } +} diff --git a/internal/middleware/limithandler/stats_test.go b/internal/middleware/limithandler/stats_test.go new file mode 100644 index 000000000..e25fd16fb --- /dev/null +++ b/internal/middleware/limithandler/stats_test.go @@ -0,0 +1,23 @@ +//go:build !gitaly_test_sha256 + +package limithandler + +import ( + "testing" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestLimitStats(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + ctx = InitLimitStats(ctx) + + stats := limitStatsFromContext(ctx) + stats.AddConcurrencyQueueMs(13) + + assert.Equal(t, FieldsProducer(ctx, nil), logrus.Fields{"limit.concurrency_queue_ms": int64(13)}) +} diff --git a/internal/praefect/datastore/storage_cleanup_test.go b/internal/praefect/datastore/storage_cleanup_test.go index 568116727..2a9f3eeb1 100644 --- a/internal/praefect/datastore/storage_cleanup_test.go +++ b/internal/praefect/datastore/storage_cleanup_test.go @@ -163,7 +163,7 @@ func TestStorageCleanup_AcquireNextStorage(t *testing.T) { require.Len(t, check2, 1) require.True(t, check2[0].TriggeredAt.Valid) return check2[0].TriggeredAt.Time.After(check1[0].TriggeredAt.Time) - }, 2*time.Second, 200*time.Millisecond, "goroutine failed to update triggered_at column") + }, time.Minute, 200*time.Millisecond, "goroutine failed to update triggered_at column") require.NoError(t, release()) diff --git a/internal/safe/file_writer_test.go b/internal/safe/file_writer_test.go index dac76ff43..88e8f2107 100644 --- a/internal/safe/file_writer_test.go +++ b/internal/safe/file_writer_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/safe" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) @@ -48,7 +49,7 @@ func TestFileWriter_mode(t *testing.T) { dir := testhelper.TempDir(t) target := filepath.Join(dir, "file") - require.NoError(t, os.WriteFile(target, []byte("contents"), 0o600)) + require.NoError(t, os.WriteFile(target, []byte("contents"), perm.PrivateFile)) writer, err := safe.NewFileWriter(target, safe.FileWriterConfig{ FileMode: 0o060, diff --git a/internal/safe/locking_directory.go b/internal/safe/locking_directory.go index 2f51e5a8e..c3baa7340 100644 --- a/internal/safe/locking_directory.go +++ b/internal/safe/locking_directory.go @@ -6,6 +6,8 @@ import ( "io/fs" "os" "path/filepath" + + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" ) type lockingDirectoryState int @@ -50,7 +52,7 @@ func (ld *LockingDirectory) Lock() error { return errors.New("locking directory not lockable") } - lock, err := os.OpenFile(ld.lockPath(), os.O_CREATE|os.O_EXCL|os.O_RDONLY, 0o400) + lock, err := os.OpenFile(ld.lockPath(), os.O_CREATE|os.O_EXCL|os.O_RDONLY, perm.PrivateWriteOnceFile) if err != nil { if os.IsExist(err) { return ErrFileAlreadyLocked diff --git a/internal/safe/locking_directory_test.go b/internal/safe/locking_directory_test.go index 4d005f8d3..9af47a54b 100644 --- a/internal/safe/locking_directory_test.go +++ b/internal/safe/locking_directory_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/safe" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) @@ -28,7 +29,7 @@ func TestLockingDirectory(t *testing.T) { require.NoError(t, os.WriteFile( filepath.Join(path, "somefile"), []byte("data"), - 0o644), + perm.SharedFile), ) assert.ErrorIs(t, secondLockingDir.Lock(), safe.ErrFileAlreadyLocked) require.NoError(t, lockingDir.Unlock()) diff --git a/internal/safe/locking_file_writer.go b/internal/safe/locking_file_writer.go index c43720cbe..bb52de6b2 100644 --- a/internal/safe/locking_file_writer.go +++ b/internal/safe/locking_file_writer.go @@ -5,6 +5,8 @@ import ( "fmt" "io" "os" + + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" ) type lockingFileWriterState int @@ -136,7 +138,7 @@ func (fw *LockingFileWriter) Lock() error { return err } - lock, err := os.OpenFile(fw.lockPath(), os.O_CREATE|os.O_EXCL|os.O_RDONLY, 0o400) + lock, err := os.OpenFile(fw.lockPath(), os.O_CREATE|os.O_EXCL|os.O_RDONLY, perm.PrivateWriteOnceFile) if err != nil { if os.IsExist(err) { return ErrFileAlreadyLocked diff --git a/internal/safe/locking_file_writer_test.go b/internal/safe/locking_file_writer_test.go index ee75eb76d..150eba196 100644 --- a/internal/safe/locking_file_writer_test.go +++ b/internal/safe/locking_file_writer_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/safe" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" @@ -147,7 +148,7 @@ func TestLockingFileWriter_seedingWithExistingTarget(t *testing.T) { t.Parallel() target := filepath.Join(testhelper.TempDir(t), "file") - require.NoError(t, os.WriteFile(target, []byte("seed"), 0o644)) + require.NoError(t, os.WriteFile(target, []byte("seed"), perm.SharedFile)) writer, err := safe.NewLockingFileWriter(target, safe.LockingFileWriterConfig{ SeedContents: true, @@ -165,7 +166,7 @@ func TestLockingFileWriter_modifiesExistingFiles(t *testing.T) { t.Parallel() target := filepath.Join(testhelper.TempDir(t), "file") - require.NoError(t, os.WriteFile(target, []byte("preexisting"), 0o644)) + require.NoError(t, os.WriteFile(target, []byte("preexisting"), perm.SharedFile)) writer, err := safe.NewLockingFileWriter(target) require.NoError(t, err) @@ -181,7 +182,7 @@ func TestLockingFileWriter_modifiesExistingFilesWithMode(t *testing.T) { t.Parallel() target := filepath.Join(testhelper.TempDir(t), "file") - require.NoError(t, os.WriteFile(target, []byte("preexisting"), 0o644)) + require.NoError(t, os.WriteFile(target, []byte("preexisting"), perm.SharedFile)) writer, err := safe.NewLockingFileWriter(target, safe.LockingFileWriterConfig{ FileWriterConfig: safe.FileWriterConfig{FileMode: 0o060}, @@ -204,7 +205,7 @@ func TestLockingFileWriter_concurrentCreation(t *testing.T) { require.NoError(t, err) // Create file concurrently. - require.NoError(t, os.WriteFile(target, []byte("concurrent"), 0o644)) + require.NoError(t, os.WriteFile(target, []byte("concurrent"), perm.SharedFile)) require.Equal(t, fmt.Errorf("file concurrently created"), writer.Lock()) @@ -216,7 +217,7 @@ func TestLockingFileWriter_concurrentDeletion(t *testing.T) { target := filepath.Join(testhelper.TempDir(t), "file") - require.NoError(t, os.WriteFile(target, []byte("base"), 0o644)) + require.NoError(t, os.WriteFile(target, []byte("base"), perm.SharedFile)) writer, err := safe.NewLockingFileWriter(target) require.NoError(t, err) @@ -233,12 +234,12 @@ func TestLockingFileWriter_concurrentModification(t *testing.T) { target := filepath.Join(testhelper.TempDir(t), "file") - require.NoError(t, os.WriteFile(target, []byte("base"), 0o644)) + require.NoError(t, os.WriteFile(target, []byte("base"), perm.SharedFile)) writer, err := safe.NewLockingFileWriter(target) require.NoError(t, err) // Concurrently modify the file. - require.NoError(t, os.WriteFile(target, []byte("concurrent"), 0o644)) + require.NoError(t, os.WriteFile(target, []byte("concurrent"), perm.SharedFile)) require.Equal(t, fmt.Errorf("file concurrently modified"), writer.Lock()) @@ -271,13 +272,13 @@ func TestLockingFileWriter_locked(t *testing.T) { t.Parallel() target := filepath.Join(testhelper.TempDir(t), "file") - require.NoError(t, os.WriteFile(target, []byte("base"), 0o644)) + require.NoError(t, os.WriteFile(target, []byte("base"), perm.SharedFile)) writer, err := safe.NewLockingFileWriter(target) require.NoError(t, err) // Concurrently lock the file. - require.NoError(t, os.WriteFile(target+".lock", nil, 0o644)) + require.NoError(t, os.WriteFile(target+".lock", nil, perm.SharedFile)) require.Equal(t, safe.ErrFileAlreadyLocked, writer.Lock()) @@ -290,7 +291,7 @@ func TestLockingFileWriter_externalProcess(t *testing.T) { cfg := testcfg.Build(t) target := filepath.Join(testhelper.TempDir(t), "file") - require.NoError(t, os.WriteFile(target, []byte("base"), 0o644)) + require.NoError(t, os.WriteFile(target, []byte("base"), perm.SharedFile)) writer, err := safe.NewLockingFileWriter(target) require.NoError(t, err) diff --git a/internal/streamcache/cache_test.go b/internal/streamcache/cache_test.go index 46aab75b9..9a2bb3603 100644 --- a/internal/streamcache/cache_test.go +++ b/internal/streamcache/cache_test.go @@ -377,7 +377,7 @@ func TestCache_unWriteableFile(t *testing.T) { defer c.Stop() c.(*cache).createFile = func() (namedWriteCloser, error) { - return os.OpenFile(filepath.Join(tmp, "unwriteable"), os.O_RDONLY|os.O_CREATE|os.O_EXCL, 0o644) + return os.OpenFile(filepath.Join(tmp, "unwriteable"), os.O_RDONLY|os.O_CREATE|os.O_EXCL, perm.SharedFile) } r, created, err := c.FindOrCreate("key", func(w io.Writer) error { @@ -404,7 +404,7 @@ func TestCache_unCloseableFile(t *testing.T) { defer c.Stop() c.(*cache).createFile = func() (namedWriteCloser, error) { - f, err := os.OpenFile(filepath.Join(tmp, "uncloseable"), os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o644) + f, err := os.OpenFile(filepath.Join(tmp, "uncloseable"), os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm.SharedFile) if err != nil { return nil, err } @@ -430,7 +430,7 @@ func TestCache_cannotOpenFileForReading(t *testing.T) { defer c.Stop() c.(*cache).createFile = func() (namedWriteCloser, error) { - f, err := os.OpenFile(filepath.Join(tmp, "unopenable"), os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o644) + f, err := os.OpenFile(filepath.Join(tmp, "unopenable"), os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm.SharedFile) if err != nil { return nil, err } diff --git a/internal/streamcache/filestore.go b/internal/streamcache/filestore.go index acb756dab..03b623320 100644 --- a/internal/streamcache/filestore.go +++ b/internal/streamcache/filestore.go @@ -111,7 +111,7 @@ func (fs *filestore) Create() (namedWriteCloser, error) { return nil, fmt.Errorf("Create: mkdir: %w", err) } - f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o644) + f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm.SharedFile) if err != nil { return nil, fmt.Errorf("Create: %w", err) } diff --git a/internal/streamcache/filestore_test.go b/internal/streamcache/filestore_test.go index adcae98d6..cad141872 100644 --- a/internal/streamcache/filestore_test.go +++ b/internal/streamcache/filestore_test.go @@ -110,7 +110,7 @@ func TestFilestoreCleanwalk(t *testing.T) { file := filepath.Join(dir2, "file") require.NoError(t, os.Mkdir(dir1, perm.SharedDir)) require.NoError(t, os.Mkdir(dir2, perm.SharedDir)) - require.NoError(t, os.WriteFile(file, nil, 0o644)) + require.NoError(t, os.WriteFile(file, nil, perm.SharedFile)) require.NoError(t, os.Chmod(dir2, 0), "create dir with pathological permissions") require.NoError(t, fs.cleanWalk(time.Now().Add(time.Hour))) @@ -119,7 +119,7 @@ func TestFilestoreCleanwalk(t *testing.T) { fi, err := os.Stat(d) require.NoError(t, err, "directories do not get deleted") - const mask = 0o700 + const mask = perm.PrivateExecutable require.True(t, fi.Mode()&mask >= mask, "unexpected file mode %o", fi.Mode()) } diff --git a/internal/tempdir/clean_test.go b/internal/tempdir/clean_test.go index b309b178e..343d747d5 100644 --- a/internal/tempdir/clean_test.go +++ b/internal/tempdir/clean_test.go @@ -144,7 +144,7 @@ func makeFile(t *testing.T, locator storage.Locator, storage config.Storage, fil require.NoError(t, err) fullPath := filepath.Join(root, filePath) - require.NoError(t, os.WriteFile(fullPath, nil, 0o644)) + require.NoError(t, os.WriteFile(fullPath, nil, perm.SharedFile)) require.NoError(t, os.Chtimes(fullPath, mtime, mtime)) } diff --git a/internal/tempdir/tempdir_test.go b/internal/tempdir/tempdir_test.go index c0e499584..627859448 100644 --- a/internal/tempdir/tempdir_test.go +++ b/internal/tempdir/tempdir_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) @@ -27,7 +28,7 @@ func TestNewRepositorySuccess(t *testing.T) { require.NoError(t, err) require.Equal(t, tempDir.Path(), calculatedPath) - require.NoError(t, os.WriteFile(filepath.Join(tempDir.Path(), "test"), []byte("hello"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(tempDir.Path(), "test"), []byte("hello"), perm.SharedFile)) require.DirExists(t, tempDir.Path()) diff --git a/internal/testhelper/logger.go b/internal/testhelper/logger.go index c654f959d..71ec59306 100644 --- a/internal/testhelper/logger.go +++ b/internal/testhelper/logger.go @@ -33,7 +33,7 @@ func NewGitalyServerLogger(tb testing.TB) *logrus.Logger { } path := filepath.Join(logDir, "gitaly_server.log") - f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0o755) + f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_RDWR, perm.SharedExecutable) require.NoError(tb, err) tb.Cleanup(func() { require.NoError(tb, f.Close()) }) diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go index b24416a8f..71a995a22 100644 --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -258,7 +258,7 @@ func WriteExecutable(tb testing.TB, path string, content []byte) string { // // We thus need to perform file locking to ensure that all writeable references to this // file have been closed before returning. - executable, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o755) + executable, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, perm.SharedExecutable) require.NoError(tb, err) _, err = io.Copy(executable, bytes.NewReader(content)) require.NoError(tb, err) diff --git a/packed_binaries.go b/packed_binaries.go index f3b532aba..de99ec8b8 100644 --- a/packed_binaries.go +++ b/packed_binaries.go @@ -6,6 +6,8 @@ import ( "io" "os" "path/filepath" + + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" ) // buildDir is the directory path where our build target places the built binaries. @@ -46,7 +48,7 @@ func UnpackAuxiliaryBinaries(destinationDir string) error { }() unpackedPath := filepath.Join(destinationDir, entry.Name()) - unpackedFile, err := os.OpenFile(unpackedPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o700) + unpackedFile, err := os.OpenFile(unpackedPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, perm.PrivateExecutable) if err != nil { return err } diff --git a/packed_binaries_test.go b/packed_binaries_test.go index d904ab28b..1c9941305 100644 --- a/packed_binaries_test.go +++ b/packed_binaries_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" ) func TestUnpackAuxiliaryBinaries_success(t *testing.T) { @@ -21,7 +22,7 @@ func TestUnpackAuxiliaryBinaries_success(t *testing.T) { for _, entry := range entries { fileInfo, err := entry.Info() require.NoError(t, err) - require.Equal(t, fileInfo.Mode(), os.FileMode(0o700), "expected the owner to have rwx permissions on the unpacked binary") + require.Equal(t, fileInfo.Mode(), perm.PrivateExecutable, "expected the owner to have rwx permissions on the unpacked binary") sourceBinary, err := os.ReadFile(filepath.Join(buildDir, fileInfo.Name())) require.NoError(t, err) @@ -37,7 +38,7 @@ func TestUnpackAuxiliaryBinaries_alreadyExists(t *testing.T) { destinationDir := t.TempDir() existingFile := filepath.Join(destinationDir, "gitaly-hooks") - require.NoError(t, os.WriteFile(existingFile, []byte("existing file"), os.ModePerm)) + require.NoError(t, os.WriteFile(existingFile, []byte("existing file"), perm.PublicFile)) err := UnpackAuxiliaryBinaries(destinationDir) require.EqualError(t, err, fmt.Sprintf(`open %s: file exists`, existingFile), "expected unpacking to fail if destination binary already existed") diff --git a/tools/golangci-lint/go.mod b/tools/golangci-lint/go.mod index 5088c8a5e..f194b8e08 100644 --- a/tools/golangci-lint/go.mod +++ b/tools/golangci-lint/go.mod @@ -2,11 +2,12 @@ module gitlab.com/gitlab-org/gitaly/tools/golangci-lint go 1.18 -require github.com/golangci/golangci-lint v1.50.1 +require github.com/golangci/golangci-lint v1.51.1 require ( - 4d63.com/gochecknoglobals v0.1.0 // indirect - github.com/Abirdcfly/dupword v0.0.7 // indirect + 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect + 4d63.com/gochecknoglobals v0.2.1 // indirect + github.com/Abirdcfly/dupword v0.0.9 // indirect github.com/Antonboom/errname v0.1.7 // indirect github.com/Antonboom/nilnil v0.1.1 // indirect github.com/BurntSushi/toml v1.2.1 // indirect @@ -27,27 +28,27 @@ require ( github.com/butuzov/ireturn v0.1.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/charithe/durationcheck v0.0.9 // indirect - github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect + github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect - github.com/daixiang0/gci v0.8.1 // indirect + github.com/daixiang0/gci v0.9.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect github.com/esimonov/ifshort v1.0.4 // indirect github.com/ettle/strcase v0.1.1 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.14.1 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/go-critic/go-critic v0.6.5 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect - github.com/go-toolsmith/astcopy v1.0.2 // indirect + github.com/go-toolsmith/astcopy v1.0.3 // indirect github.com/go-toolsmith/astequal v1.0.3 // indirect github.com/go-toolsmith/astfmt v1.0.0 // indirect github.com/go-toolsmith/astp v1.0.0 // indirect github.com/go-toolsmith/strparse v1.0.0 // indirect github.com/go-toolsmith/typep v1.0.2 // indirect - github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect + github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/golang/protobuf v1.5.2 // indirect @@ -57,11 +58,11 @@ require ( github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // indirect github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect - github.com/golangci/misspell v0.3.5 // indirect + github.com/golangci/misspell v0.4.0 // indirect github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect + github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect @@ -76,40 +77,41 @@ require ( github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect github.com/julz/importas v0.1.0 // indirect - github.com/kisielk/errcheck v1.6.2 // indirect + github.com/junk1tm/musttag v0.4.4 // indirect + github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.3 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect - github.com/kyoh86/exportloopref v0.1.8 // indirect + github.com/kyoh86/exportloopref v0.1.11 // indirect github.com/ldez/gomoddirectives v0.2.3 // indirect - github.com/ldez/tagliatelle v0.3.1 // indirect - github.com/leonklingele/grouper v1.1.0 // indirect + github.com/ldez/tagliatelle v0.4.0 // indirect + github.com/leonklingele/grouper v1.1.1 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/maratori/testableexamples v1.0.0 // indirect github.com/maratori/testpackage v1.1.0 // indirect github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect - github.com/mgechev/revive v1.2.4 // indirect + github.com/mgechev/revive v1.2.5 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moricho/tparallel v0.2.1 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect - github.com/nishanths/exhaustive v0.8.3 // indirect + github.com/nishanths/exhaustive v0.9.5 // indirect github.com/nishanths/predeclared v0.2.2 // indirect + github.com/nunnatsa/ginkgolinter v0.8.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect - github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polyfloyd/go-errorlint v1.0.5 // indirect + github.com/polyfloyd/go-errorlint v1.0.6 // indirect github.com/prometheus/client_golang v1.12.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect @@ -118,35 +120,36 @@ require ( github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f // indirect github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect - github.com/ryancurrah/gomodguard v1.2.4 // indirect - github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect - github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect + github.com/ryancurrah/gomodguard v1.3.0 // indirect + github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect + github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect - github.com/sashamelentyev/usestdlibvars v1.20.0 // indirect - github.com/securego/gosec/v2 v2.13.1 // indirect + github.com/sashamelentyev/usestdlibvars v1.21.1 // indirect + github.com/securego/gosec/v2 v2.14.0 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/sivchari/containedctx v1.0.2 // indirect github.com/sivchari/nosnakecase v1.7.0 // indirect - github.com/sivchari/tenv v1.7.0 // indirect + github.com/sivchari/tenv v1.7.1 // indirect github.com/sonatard/noctx v0.0.1 // indirect - github.com/sourcegraph/go-diff v0.6.1 // indirect + github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.6.0 // indirect + github.com/spf13/cobra v1.6.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.12.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect - github.com/stretchr/objx v0.4.0 // indirect - github.com/stretchr/testify v1.8.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/testify v1.8.1 // indirect github.com/subosito/gotenv v1.4.1 // indirect + github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tdakkota/asciicheck v0.1.1 // indirect github.com/tetafro/godot v1.4.11 // indirect - github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect + github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e // indirect github.com/timonwong/loggercheck v0.9.3 // indirect - github.com/tomarrell/wrapcheck/v2 v2.7.0 // indirect + github.com/tomarrell/wrapcheck/v2 v2.8.0 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/ultraware/funlen v0.0.3 // indirect github.com/ultraware/whitespace v0.0.5 // indirect @@ -158,21 +161,21 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.17.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect - golang.org/x/mod v0.6.0 // indirect - golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect - golang.org/x/sys v0.1.0 // indirect - golang.org/x/text v0.3.8 // indirect - golang.org/x/tools v0.2.0 // indirect + golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect + golang.org/x/mod v0.7.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.4.0 // indirect + golang.org/x/text v0.6.0 // indirect + golang.org/x/tools v0.5.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.3.3 // indirect + honnef.co/go/tools v0.4.0 // indirect mvdan.cc/gofumpt v0.4.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect - mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect + mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect ) // https://github.com/spf13/viper/commit/5247643f02358b40d01385b0dbf743b659b0133f diff --git a/tools/golangci-lint/go.sum b/tools/golangci-lint/go.sum index db26e7ec0..6ab4dcdbd 100644 --- a/tools/golangci-lint/go.sum +++ b/tools/golangci-lint/go.sum @@ -1,5 +1,7 @@ -4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0= -4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA= +4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= +4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= +4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -38,8 +40,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Abirdcfly/dupword v0.0.7 h1:z14n0yytA3wNO2gpCD/jVtp/acEXPGmYu0esewpBt6Q= -github.com/Abirdcfly/dupword v0.0.7/go.mod h1:K/4M1kj+Zh39d2aotRwypvasonOyAMH1c/IZJzE0dmk= +github.com/Abirdcfly/dupword v0.0.9 h1:MxprGjKq3yDBICXDgEEsyGirIXfMYXkLNT/agPsE1tk= +github.com/Abirdcfly/dupword v0.0.9/go.mod h1:PzmHVLLZ27MvHSzV7eFmMXSFArWXZPZmfuuziuUrf2g= github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= @@ -91,8 +93,8 @@ github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cb github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= -github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI= -github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To= +github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348 h1:cy5GCEZLUCshCGCRRUjxHrDUqkB4l5cuUt3ShEckQEo= +github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348/go.mod h1:f/miWtG3SSuTxKsNK3o58H1xl+XV6ZIfbC6p7lPPB8U= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -105,8 +107,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= -github.com/daixiang0/gci v0.8.1 h1:T4xpSC+hmsi4CSyuYfIJdMZAr9o7xZmHpQVygMghGZ4= -github.com/daixiang0/gci v0.8.1/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= +github.com/daixiang0/gci v0.9.0 h1:t8XZ0vK6l0pwPoOmoGyqW2NwQlvbpAQNVvu/GRBgykM= +github.com/daixiang0/gci v0.9.0/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -122,8 +124,8 @@ github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStB github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= @@ -144,12 +146,12 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.2 h1:YnWf5Rnh1hUudj11kei53kI57quN/VH6Hp1n+erozn0= github.com/go-toolsmith/astcopy v1.0.2/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= +github.com/go-toolsmith/astcopy v1.0.3 h1:r0bgSRlMOAgO+BdQnVAcpMSMkrQCnV6ZJmIkrJgcJj0= +github.com/go-toolsmith/astcopy v1.0.3/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= github.com/go-toolsmith/astequal v1.0.2/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= github.com/go-toolsmith/astequal v1.0.3 h1:+LVdyRatFS+XO78SGV4I3TCEA0AC7fKEGma+fH+674o= @@ -164,8 +166,8 @@ github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUD github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= +github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= @@ -207,14 +209,14 @@ github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6 github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.50.1 h1:C829clMcZXEORakZlwpk7M4iDw2XiwxxKaG504SZ9zY= -github.com/golangci/golangci-lint v1.50.1/go.mod h1:AQjHBopYS//oB8xs0y0M/dtxdKHkdhl0RvmjUct0/4w= +github.com/golangci/golangci-lint v1.51.1 h1:N5HD/x0ZrhJYsgKWyz7yJxxQ8JKR0Acc+FOP7QtGSAA= +github.com/golangci/golangci-lint v1.51.1/go.mod h1:hnyNNO3fJ2Rjwo6HM+VXvcmLkKDOuBAnR9gVlS1mW1E= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= -github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/misspell v0.4.0 h1:KtVB/hTK4bbL/S6bs64rYyk8adjmh1BygbBiaAiX+a0= +github.com/golangci/misspell v0.4.0/go.mod h1:W6O/bwV6lGDxUCChm2ykw9NQdd5bYd1Xkjo88UcWyJc= github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ= github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= @@ -253,9 +255,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= -github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 h1:9alfqbrhuD+9fLZ4iaAVwhlp5PEhmnBt7yvK2Oy5C1U= +github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= @@ -293,7 +294,6 @@ github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjz github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -305,8 +305,10 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= -github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c= -github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= +github.com/junk1tm/musttag v0.4.4 h1:VK4L7v7lvWAhKDDx0cUJgbb0UBNipYinv8pPeHJzH9Q= +github.com/junk1tm/musttag v0.4.4/go.mod h1:XkcL/9O6RmD88JBXb+I15nYRl9W4ExhgQeCBEhfMC8U= +github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM8= +github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.3 h1:l4pNvrb8JSwRd51ojtcOxOeHJzHek+MtOyXbaR0uvmw= @@ -325,15 +327,14 @@ github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g= github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= -github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= -github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= +github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= -github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM= -github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= -github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= -github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/ldez/tagliatelle v0.4.0 h1:sylp7d9kh6AdXN2DpVGHBRb5guTVAgOxqNGhbqc4b1c= +github.com/ldez/tagliatelle v0.4.0/go.mod h1:mNtTfrHy2haaBAw+VT7IBV6VXBThS7TCreYWbBcJ87I= +github.com/leonklingele/grouper v1.1.1 h1:suWXRU57D4/Enn6pXR0QVqqWWrnJ9Osrz+5rjt8ivzU= +github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= @@ -346,22 +347,19 @@ github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7 github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mgechev/revive v1.2.4 h1:+2Hd/S8oO2H0Ikq2+egtNwQsVhAeELHjxjIUFX5ajLI= -github.com/mgechev/revive v1.2.4/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= +github.com/mgechev/revive v1.2.5 h1:UF9AR8pOAuwNmhXj2odp4mxv9Nx2qUIwVz8ZsU+Mbec= +github.com/mgechev/revive v1.2.5/go.mod h1:nFOXent79jMTISAfOAasKfy0Z2Ejq0WX7Qn/KAdYopI= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -381,14 +379,16 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6Fx github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.8.3 h1:pw5O09vwg8ZaditDp/nQRqVnrMczSJDxRDJMowvhsrM= -github.com/nishanths/exhaustive v0.8.3/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= +github.com/nishanths/exhaustive v0.9.5 h1:TzssWan6orBiLYVqewCG8faud9qlFntJE30ACpzmGME= +github.com/nishanths/exhaustive v0.9.5/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= +github.com/nunnatsa/ginkgolinter v0.8.1 h1:/y4o/0hV+ruUHj4xXh89xlFjoaitnI4LnkpuYs02q1c= +github.com/nunnatsa/ginkgolinter v0.8.1/go.mod h1:FYYLtszIdmzCH8XMaMPyxPVXZ7VCaIm55bA+gugx+14= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= -github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8= +github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -399,8 +399,6 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -408,8 +406,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v1.0.5 h1:AHB5JRCjlmelh9RrLxT9sgzpalIwwq4hqE8EkwIwKdY= -github.com/polyfloyd/go-errorlint v1.0.5/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= +github.com/polyfloyd/go-errorlint v1.0.6 h1:ZevdyEGxDoHAMQUVvdTT06hnYuKULe8TQkOmIYx6s1c= +github.com/polyfloyd/go-errorlint v1.0.6/go.mod h1:NcnNncnm8fVV7vfQWiI4HZrzWFzGp24C262IQutNcMs= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -448,18 +446,18 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4= -github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M= -github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= -github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= -github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= -github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJHMLuTw= +github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= +github.com/ryanrolds/sqlclosecheck v0.4.0 h1:i8SX60Rppc1wRuyQjMciLqIzV3xnoHB7/tXbr6RGYNI= +github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= +github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= +github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= -github.com/sashamelentyev/usestdlibvars v1.20.0 h1:K6CXjqqtSYSsuyRDDC7Sjn6vTMLiSJa4ZmDkiokoqtw= -github.com/sashamelentyev/usestdlibvars v1.20.0/go.mod h1:0GaP+ecfZMXShS0A94CJn6aEuPRILv8h/VuWI9n1ygg= -github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM= -github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo= +github.com/sashamelentyev/usestdlibvars v1.21.1 h1:GQGlReyL9Ek8DdJmwtwhHbhwHnuPfsKaprpjnrPcjxc= +github.com/sashamelentyev/usestdlibvars v1.21.1/go.mod h1:MPI52Qq99iO9sFZZcKJ2y/bx6BNjs+/2bw3PCggIbew= +github.com/securego/gosec/v2 v2.14.0 h1:U1hfs0oBackChXA72plCYVA4cOlQ4gO+209dHiSNZbI= +github.com/securego/gosec/v2 v2.14.0/go.mod h1:Ff03zEi5NwSOfXj9nFpBfhbWTtROCkg9N+9goggrYn4= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -473,18 +471,18 @@ github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYI github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8= github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= -github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= -github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= +github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= -github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= -github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= +github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= -github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -497,8 +495,9 @@ github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -506,10 +505,13 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= @@ -518,12 +520,12 @@ github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpR github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= -github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= -github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e h1:MV6KaVu/hzByHP0UvJ4HcMGE/8a6A4Rggc/0wx2AvJo= +github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= github.com/timonwong/loggercheck v0.9.3 h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI= github.com/timonwong/loggercheck v0.9.3/go.mod h1:wUqnk9yAOIKtGA39l1KLE9Iz0QiTocu/YZoOf+OzFdw= -github.com/tomarrell/wrapcheck/v2 v2.7.0 h1:J/F8DbSKJC83bAvC6FoZaRjZiZ/iKoueSdrEkmGeacA= -github.com/tomarrell/wrapcheck/v2 v2.7.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= +github.com/tomarrell/wrapcheck/v2 v2.8.0 h1:qDzbir0xmoE+aNxGCPrn+rUSxAX+nG6vREgbbXAR81I= +github.com/tomarrell/wrapcheck/v2 v2.8.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= @@ -566,6 +568,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -579,8 +582,9 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 h1:Ic/qN6TEifvObMGQy72k0n1LlJr7DjWWEi+MOsDOiSk= golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a h1:Jw5wfR+h9mnIYH+OtGT2im5wV1YGGDora5vTv/aa5bE= +golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -608,8 +612,9 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -647,7 +652,11 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -670,8 +679,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -689,7 +698,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -718,7 +726,6 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -728,10 +735,17 @@ golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -740,8 +754,10 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -755,7 +771,6 @@ golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -794,9 +809,7 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -806,7 +819,6 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -824,8 +836,11 @@ golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= +golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -950,16 +965,16 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= -honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= +honnef.co/go/tools v0.4.0 h1:lyXVV1c8wUBJRKqI8JgIpT8TW1VDagfYYaxbKa/HoL8= +honnef.co/go/tools v0.4.0/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= mvdan.cc/gofumpt v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM= mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk= -mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk= +mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d h1:3rvTIIM22r9pvXk+q3swxUQAQOxksVMGK7sml4nG57w= +mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/tools/replace-buildid/main.go b/tools/replace-buildid/main.go index 0eab44149..369d348c4 100644 --- a/tools/replace-buildid/main.go +++ b/tools/replace-buildid/main.go @@ -16,6 +16,8 @@ import ( "io" "os" "path/filepath" + + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" ) func main() { @@ -105,7 +107,7 @@ func writeBinary(binaryPath string, contents []byte) error { f.Close() }() - if err := f.Chmod(0o755); err != nil { + if err := f.Chmod(perm.SharedExecutable); err != nil { return fmt.Errorf("could not change permissions: %w", err) } |