Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
107768e4
Commit
107768e4
authored
Dec 08, 2020
by
Stan Hu
Browse files
Options
Browse Files
Download
Plain Diff
Update vendored workhorse to v8.58.0
parents
99fba74a
2a3bc8ab
Changes
33
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
574 additions
and
239 deletions
+574
-239
workhorse/.gitignore
workhorse/.gitignore
+1
-0
workhorse/CHANGELOG
workhorse/CHANGELOG
+16
-0
workhorse/README.md
workhorse/README.md
+14
-0
workhorse/VERSION
workhorse/VERSION
+1
-1
workhorse/config.toml.example
workhorse/config.toml.example
+2
-0
workhorse/go.mod
workhorse/go.mod
+5
-5
workhorse/go.sum
workhorse/go.sum
+220
-75
workhorse/internal/api/api.go
workhorse/internal/api/api.go
+3
-7
workhorse/internal/artifacts/artifacts_upload.go
workhorse/internal/artifacts/artifacts_upload.go
+2
-5
workhorse/internal/builds/register.go
workhorse/internal/builds/register.go
+3
-9
workhorse/internal/config/config.go
workhorse/internal/config/config.go
+1
-0
workhorse/internal/config/config_test.go
workhorse/internal/config/config_test.go
+12
-0
workhorse/internal/filestore/file_handler.go
workhorse/internal/filestore/file_handler.go
+7
-1
workhorse/internal/filestore/file_handler_test.go
workhorse/internal/filestore/file_handler_test.go
+102
-0
workhorse/internal/git/archive.go
workhorse/internal/git/archive.go
+2
-5
workhorse/internal/git/responsewriter.go
workhorse/internal/git/responsewriter.go
+4
-9
workhorse/internal/gitaly/gitaly.go
workhorse/internal/gitaly/gitaly.go
+2
-5
workhorse/internal/imageresizer/image_resizer.go
workhorse/internal/imageresizer/image_resizer.go
+19
-18
workhorse/internal/imageresizer/image_resizer_test.go
workhorse/internal/imageresizer/image_resizer_test.go
+23
-0
workhorse/internal/objectstore/prometheus.go
workhorse/internal/objectstore/prometheus.go
+8
-12
workhorse/internal/objectstore/uploader.go
workhorse/internal/objectstore/uploader.go
+2
-0
workhorse/internal/queueing/queue.go
workhorse/internal/queueing/queue.go
+8
-15
workhorse/internal/redis/keywatcher.go
workhorse/internal/redis/keywatcher.go
+3
-9
workhorse/internal/redis/redis.go
workhorse/internal/redis/redis.go
+3
-9
workhorse/internal/senddata/senddata.go
workhorse/internal/senddata/senddata.go
+3
-7
workhorse/internal/sendfile/sendfile.go
workhorse/internal/sendfile/sendfile.go
+3
-7
workhorse/internal/sendurl/sendurl.go
workhorse/internal/sendurl/sendurl.go
+4
-10
workhorse/internal/staticpages/error_pages.go
workhorse/internal/staticpages/error_pages.go
+2
-5
workhorse/internal/upload/rewrite.go
workhorse/internal/upload/rewrite.go
+4
-9
workhorse/internal/upstream/metrics.go
workhorse/internal/upstream/metrics.go
+7
-14
workhorse/internal/upstream/routes.go
workhorse/internal/upstream/routes.go
+11
-1
workhorse/main.go
workhorse/main.go
+1
-0
workhorse/main_test.go
workhorse/main_test.go
+76
-1
No files found.
workhorse/.gitignore
View file @
107768e4
testdata/data
testdata/scratch
testdata/public
testdata/alt-public
/gitlab-workhorse
/gitlab-resize-image
/gitlab-zip-cat
...
...
workhorse/CHANGELOG
View file @
107768e4
# Changelog for gitlab-workhorse
## v8.58.0
### Added
- Support alternate document root directory
https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/626
### Fixed
- Fix uploader not returning 413 when artifact too large
https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/663
- Auto-register Prometheus metrics
https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/660
### Other
- Do not resize when image is less than 8 bytes
https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/666
## v8.57.0
### Added
...
...
workhorse/README.md
View file @
107768e4
...
...
@@ -7,6 +7,20 @@ push/pull and Git archive downloads.
Workhorse itself is not a feature, but there are
[
several features in
GitLab
](
doc/architecture/gitlab_features.md
)
that would not work efficiently without Workhorse.
## Canonical source
The canonical source for Workhorse is currently
[
gitlab-org/gitlab-workhorse
](
https://gitlab.com/gitlab-org/gitlab-workhorse
)
.
As explained in https://gitlab.com/groups/gitlab-org/-/epics/4826, we
are in the process of moving the canonical source to
[
gitlab-org/gitlab/workhorse
](
https://gitlab.com/gitlab-org/gitlab/tree/master/workhorse
)
.
Until that transition is complete, changes (Merge Requests) for
Workhorse should be submitted at
[
gitlab-org/gitlab-workhorse
](
https://gitlab.com/gitlab-org/gitlab-workhorse
)
.
Once merged, they will propagate to gitlab-org/gitlab/workhorse via
the usual Workhorse release process.
## Documentation
Workhorse documentation is available in the
[
`doc` folder of this repository
](
doc/
)
.
...
...
workhorse/VERSION
View file @
107768e4
8.5
7
.0
8.5
8
.0
workhorse/config.toml.example
View file @
107768e4
# alt_document_root = '/home/git/public/assets'
[redis]
URL = "unix:/home/git/gitlab/redis/redis.socket"
...
...
workhorse/go.mod
View file @
107768e4
...
...
@@ -13,15 +13,15 @@ require (
github.com/disintegration/imaging v1.6.2
github.com/getsentry/raven-go v0.2.0
github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721
github.com/golang/protobuf v1.4.
2
github.com/golang/protobuf v1.4.
3
github.com/gomodule/redigo v2.0.0+incompatible
github.com/gorilla/websocket v1.4.0
github.com/grpc-ecosystem/go-grpc-middleware v1.
0.0
github.com/grpc-ecosystem/go-grpc-middleware v1.
2.2
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/johannesboyne/gofakes3 v0.0.0-20200510090907-02d71f533bec
github.com/jpillora/backoff v
0.0.0-20170918002102-8eab2debe79d
github.com/jpillora/backoff v
1.0.0
github.com/mitchellh/copystructure v1.0.0
github.com/prometheus/client_golang v1.
0
.0
github.com/prometheus/client_golang v1.
8
.0
github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1
github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35
github.com/shabbyrobe/gocovmerge v0.0.0-20190829150210-3e036491d500 // indirect
...
...
@@ -32,7 +32,7 @@ require (
gitlab.com/gitlab-org/labkit v1.0.0
gocloud.dev v0.20.0
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
golang.org/x/net v0.0.0-202006
02114024-627f9648deb9
golang.org/x/net v0.0.0-202006
25001655-4c5254603344
golang.org/x/tools v0.0.0-20200608174601-1b747fd94509
google.golang.org/grpc v1.29.1
honnef.co/go/tools v0.0.1-2020.1.5
...
...
workhorse/go.sum
View file @
107768e4
This diff is collapsed.
Click to expand it.
workhorse/internal/api/api.go
View file @
107768e4
...
...
@@ -11,6 +11,7 @@ import (
"strings"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"
...
...
@@ -34,14 +35,14 @@ type API struct {
}
var
(
requestsCounter
=
prom
etheus
.
NewCounterVec
(
requestsCounter
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_internal_api_requests"
,
Help
:
"How many internal API requests have been completed by gitlab-workhorse, partitioned by status code and HTTP method."
,
},
[]
string
{
"code"
,
"method"
},
)
bytesTotal
=
prom
etheus
.
NewCounter
(
bytesTotal
=
prom
auto
.
NewCounter
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_internal_api_failure_response_bytes"
,
Help
:
"How many bytes have been returned by upstream GitLab in API failure/rejection response bodies."
,
...
...
@@ -49,11 +50,6 @@ var (
)
)
func
init
()
{
prometheus
.
MustRegister
(
requestsCounter
)
prometheus
.
MustRegister
(
bytesTotal
)
}
func
NewAPI
(
myURL
*
url
.
URL
,
version
string
,
roundTripper
http
.
RoundTripper
)
*
API
{
return
&
API
{
Client
:
&
http
.
Client
{
Transport
:
roundTripper
},
...
...
workhorse/internal/artifacts/artifacts_upload.go
View file @
107768e4
...
...
@@ -12,6 +12,7 @@ import (
"syscall"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/labkit/log"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/api"
...
...
@@ -28,16 +29,12 @@ const (
ArtifactFormatDefault
=
""
)
var
zipSubcommandsErrorsCounter
=
prom
etheus
.
NewCounterVec
(
var
zipSubcommandsErrorsCounter
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_zip_subcommand_errors_total"
,
Help
:
"Errors comming from subcommands used for processing ZIP archives"
,
},
[]
string
{
"error"
})
func
init
()
{
prometheus
.
MustRegister
(
zipSubcommandsErrorsCounter
)
}
type
artifactsUploadProcessor
struct
{
opts
*
filestore
.
SaveFileOpts
format
string
...
...
workhorse/internal/builds/register.go
View file @
107768e4
...
...
@@ -7,6 +7,7 @@ import (
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/redis"
...
...
@@ -20,14 +21,14 @@ const (
)
var
(
registerHandlerRequests
=
prom
etheus
.
NewCounterVec
(
registerHandlerRequests
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_builds_register_handler_requests"
,
Help
:
"Describes how many requests in different states hit a register handler"
,
},
[]
string
{
"status"
},
)
registerHandlerOpen
=
prom
etheus
.
NewGaugeVec
(
registerHandlerOpen
=
prom
auto
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
Name
:
"gitlab_workhorse_builds_register_handler_open"
,
Help
:
"Describes how many requests is currently open in given state"
,
...
...
@@ -53,13 +54,6 @@ type largeBodyError struct{ error }
type
WatchKeyHandler
func
(
key
,
value
string
,
timeout
time
.
Duration
)
(
redis
.
WatchKeyStatus
,
error
)
func
init
()
{
prometheus
.
MustRegister
(
registerHandlerRequests
,
registerHandlerOpen
,
)
}
type
runnerRequest
struct
{
Token
string
`json:"token,omitempty"`
LastUpdate
string
`json:"last_update,omitempty"`
...
...
workhorse/internal/config/config.go
View file @
107768e4
...
...
@@ -105,6 +105,7 @@ type Config struct {
ObjectStorageCredentials
ObjectStorageCredentials
`toml:"object_storage"`
PropagateCorrelationID
bool
`toml:"-"`
ImageResizerConfig
ImageResizerConfig
`toml:"image_resizer"`
AltDocumentRoot
string
`toml:"alt_document_root"`
}
var
DefaultImageResizerConfig
=
ImageResizerConfig
{
...
...
workhorse/internal/config/config_test.go
View file @
107768e4
...
...
@@ -21,6 +21,7 @@ func TestLoadEmptyConfig(t *testing.T) {
cfg
,
err
:=
LoadConfig
(
config
)
require
.
NoError
(
t
,
err
)
require
.
Empty
(
t
,
cfg
.
AltDocumentRoot
)
require
.
Equal
(
t
,
cfg
.
ImageResizerConfig
.
MaxFilesize
,
uint64
(
250000
))
require
.
GreaterOrEqual
(
t
,
cfg
.
ImageResizerConfig
.
MaxScalerProcs
,
uint32
(
2
))
...
...
@@ -97,3 +98,14 @@ max_filesize = 350000
require
.
Equal
(
t
,
expected
,
cfg
.
ImageResizerConfig
)
}
func
TestAltDocumentConfig
(
t
*
testing
.
T
)
{
config
:=
`
alt_document_root = "/path/to/documents"
`
cfg
,
err
:=
LoadConfig
(
config
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
"/path/to/documents"
,
cfg
.
AltDocumentRoot
)
}
workhorse/internal/filestore/file_handler.go
View file @
107768e4
...
...
@@ -166,7 +166,13 @@ func SaveFileFromReader(ctx context.Context, reader io.Reader, size int64, opts
return
nil
,
SizeError
(
fmt
.
Errorf
(
"the upload size %d is over maximum of %d bytes"
,
size
,
opts
.
MaximumSize
))
}
reader
=
&
hardLimitReader
{
r
:
reader
,
n
:
opts
.
MaximumSize
}
hlr
:=
&
hardLimitReader
{
r
:
reader
,
n
:
opts
.
MaximumSize
}
reader
=
hlr
defer
func
()
{
if
hlr
.
n
<
0
{
err
=
ErrEntityTooLarge
}
}()
}
fh
.
Size
,
err
=
uploadDestination
.
Consume
(
ctx
,
reader
,
opts
.
Deadline
)
...
...
workhorse/internal/filestore/file_handler_test.go
View file @
107768e4
...
...
@@ -2,6 +2,7 @@ package filestore_test
import
(
"context"
"errors"
"fmt"
"io/ioutil"
"os"
...
...
@@ -428,6 +429,107 @@ func TestSaveMultipartInBodyFailure(t *testing.T) {
require
.
EqualError
(
t
,
err
,
test
.
MultipartUploadInternalError
()
.
Error
())
}
func
TestSaveRemoteFileWithLimit
(
t
*
testing
.
T
)
{
testhelper
.
ConfigureSecret
()
type
remote
int
const
(
notRemote
remote
=
iota
remoteSingle
remoteMultipart
)
remoteTypes
:=
[]
remote
{
remoteSingle
,
remoteMultipart
}
tests
:=
[]
struct
{
name
string
objectSize
int64
maxSize
int64
expectedErr
error
testData
string
}{
{
name
:
"known size with no limit"
,
testData
:
test
.
ObjectContent
,
objectSize
:
test
.
ObjectSize
,
},
{
name
:
"unknown size with no limit"
,
testData
:
test
.
ObjectContent
,
objectSize
:
-
1
,
},
{
name
:
"unknown object size with limit"
,
testData
:
test
.
ObjectContent
,
objectSize
:
-
1
,
maxSize
:
test
.
ObjectSize
-
1
,
expectedErr
:
filestore
.
ErrEntityTooLarge
,
},
{
name
:
"large object with unknown size with limit"
,
testData
:
string
(
make
([]
byte
,
20000
)),
objectSize
:
-
1
,
maxSize
:
19000
,
expectedErr
:
filestore
.
ErrEntityTooLarge
,
},
}
for
_
,
tc
:=
range
tests
{
t
.
Run
(
tc
.
name
,
func
(
t
*
testing
.
T
)
{
var
opts
filestore
.
SaveFileOpts
for
_
,
remoteType
:=
range
remoteTypes
{
tmpFolder
,
err
:=
ioutil
.
TempDir
(
""
,
"workhorse-test-tmp"
)
require
.
NoError
(
t
,
err
)
defer
os
.
RemoveAll
(
tmpFolder
)
osStub
,
ts
:=
test
.
StartObjectStore
()
defer
ts
.
Close
()
switch
remoteType
{
case
remoteSingle
:
objectURL
:=
ts
.
URL
+
test
.
ObjectPath
opts
.
RemoteID
=
"test-file"
opts
.
RemoteURL
=
objectURL
opts
.
PresignedPut
=
objectURL
+
"?Signature=ASignature"
opts
.
PresignedDelete
=
objectURL
+
"?Signature=AnotherSignature"
opts
.
Deadline
=
testDeadline
()
opts
.
MaximumSize
=
tc
.
maxSize
case
remoteMultipart
:
objectURL
:=
ts
.
URL
+
test
.
ObjectPath
opts
.
RemoteID
=
"test-file"
opts
.
RemoteURL
=
objectURL
opts
.
PresignedDelete
=
objectURL
+
"?Signature=AnotherSignature"
opts
.
PartSize
=
int64
(
len
(
tc
.
testData
)
/
2
)
+
1
opts
.
PresignedParts
=
[]
string
{
objectURL
+
"?partNumber=1"
,
objectURL
+
"?partNumber=2"
}
opts
.
PresignedCompleteMultipart
=
objectURL
+
"?Signature=CompleteSignature"
opts
.
Deadline
=
testDeadline
()
opts
.
MaximumSize
=
tc
.
maxSize
require
.
Less
(
t
,
int64
(
len
(
tc
.
testData
)),
int64
(
len
(
opts
.
PresignedParts
))
*
opts
.
PartSize
,
"check part size calculation"
)
osStub
.
InitiateMultipartUpload
(
test
.
ObjectPath
)
}
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
fh
,
err
:=
filestore
.
SaveFileFromReader
(
ctx
,
strings
.
NewReader
(
tc
.
testData
),
tc
.
objectSize
,
&
opts
)
if
tc
.
expectedErr
==
nil
{
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
fh
)
}
else
{
require
.
True
(
t
,
errors
.
Is
(
err
,
tc
.
expectedErr
))
require
.
Nil
(
t
,
fh
)
}
}
})
}
}
func
checkFileHandlerWithFields
(
t
*
testing
.
T
,
fh
*
filestore
.
FileHandler
,
fields
map
[
string
]
string
,
prefix
string
)
{
key
:=
func
(
field
string
)
string
{
if
prefix
==
""
{
...
...
workhorse/internal/git/archive.go
View file @
107768e4
...
...
@@ -18,6 +18,7 @@ import (
"github.com/golang/protobuf/proto"
//lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab-workhorse/-/issues/274
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"
...
...
@@ -39,7 +40,7 @@ type archiveParams struct {
var
(
SendArchive
=
&
archive
{
"git-archive:"
}
gitArchiveCache
=
prom
etheus
.
NewCounterVec
(
gitArchiveCache
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_git_archive_cache"
,
Help
:
"Cache hits and misses for 'git archive' streaming"
,
...
...
@@ -48,10 +49,6 @@ var (
)
)
func
init
()
{
prometheus
.
MustRegister
(
gitArchiveCache
)
}
func
(
a
*
archive
)
Inject
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
sendData
string
)
{
var
params
archiveParams
if
err
:=
a
.
Unpack
(
&
params
,
sendData
);
err
!=
nil
{
...
...
workhorse/internal/git/responsewriter.go
View file @
107768e4
...
...
@@ -5,6 +5,7 @@ import (
"strconv"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
)
...
...
@@ -15,12 +16,12 @@ const (
)
var
(
gitHTTPSessionsActive
=
prom
etheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
gitHTTPSessionsActive
=
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"gitlab_workhorse_git_http_sessions_active"
,
Help
:
"Number of Git HTTP request-response cycles currently being handled by gitlab-workhorse."
,
})
gitHTTPRequests
=
prom
etheus
.
NewCounterVec
(
gitHTTPRequests
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_git_http_requests"
,
Help
:
"How many Git HTTP requests have been processed by gitlab-workhorse, partitioned by request type and agent."
,
...
...
@@ -28,7 +29,7 @@ var (
[]
string
{
"method"
,
"code"
,
"service"
,
"agent"
},
)
gitHTTPBytes
=
prom
etheus
.
NewCounterVec
(
gitHTTPBytes
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_git_http_bytes"
,
Help
:
"How many Git HTTP bytes have been sent by gitlab-workhorse, partitioned by request type, agent and direction."
,
...
...
@@ -37,12 +38,6 @@ var (
)
)
func
init
()
{
prometheus
.
MustRegister
(
gitHTTPSessionsActive
)
prometheus
.
MustRegister
(
gitHTTPRequests
)
prometheus
.
MustRegister
(
gitHTTPBytes
)
}
type
HttpResponseWriter
struct
{
helper
.
CountingResponseWriter
}
...
...
workhorse/internal/gitaly/gitaly.go
View file @
107768e4
...
...
@@ -10,6 +10,7 @@ import (
grpc_middleware
"github.com/grpc-ecosystem/go-grpc-middleware"
grpc_prometheus
"github.com/grpc-ecosystem/go-grpc-prometheus"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
gitalyauth
"gitlab.com/gitlab-org/gitaly/auth"
gitalyclient
"gitlab.com/gitlab-org/gitaly/client"
"gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"
...
...
@@ -43,7 +44,7 @@ var (
connections
:
make
(
map
[
cacheKey
]
*
grpc
.
ClientConn
),
}
connectionsTotal
=
prom
etheus
.
NewCounterVec
(
connectionsTotal
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_gitaly_connections_total"
,
Help
:
"Number of Gitaly connections that have been established"
,
...
...
@@ -52,10 +53,6 @@ var (
)
)
func
init
()
{
prometheus
.
MustRegister
(
connectionsTotal
)
}
func
withOutgoingMetadata
(
ctx
context
.
Context
,
features
map
[
string
]
string
)
context
.
Context
{
md
:=
metadata
.
New
(
nil
)
for
k
,
v
:=
range
features
{
...
...
workhorse/internal/imageresizer/image_resizer.go
View file @
107768e4
...
...
@@ -5,7 +5,6 @@ import (
"context"
"fmt"
"io"
"math"
"net"
"net/http"
"os"
...
...
@@ -17,6 +16,7 @@ import (
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/labkit/correlation"
"gitlab.com/gitlab-org/labkit/log"
...
...
@@ -96,7 +96,7 @@ const (
)
var
(
imageResizeConcurrencyLimitExceeds
=
prom
etheus
.
NewCounter
(
imageResizeConcurrencyLimitExceeds
=
prom
auto
.
NewCounter
(
prometheus
.
CounterOpts
{
Namespace
:
namespace
,
Subsystem
:
subsystem
,
...
...
@@ -104,7 +104,7 @@ var (
Help
:
"Amount of image resizing requests that exceeded the maximum allowed scaler processes"
,
},
)
imageResizeProcesses
=
prom
etheus
.
NewGauge
(
imageResizeProcesses
=
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Namespace
:
namespace
,
Subsystem
:
subsystem
,
...
...
@@ -112,7 +112,7 @@ var (
Help
:
"Amount of image scaler processes working now"
,
},
)
imageResizeMaxProcesses
=
prom
etheus
.
NewGauge
(
imageResizeMaxProcesses
=
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Namespace
:
namespace
,
Subsystem
:
subsystem
,
...
...
@@ -120,7 +120,7 @@ var (
Help
:
"The maximum amount of image scaler processes allowed to run concurrently"
,
},
)
imageResizeRequests
=
prom
etheus
.
NewCounterVec
(
imageResizeRequests
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Namespace
:
namespace
,
Subsystem
:
subsystem
,
...
...
@@ -129,7 +129,7 @@ var (
},
[]
string
{
"status"
},
)
imageResizeDurations
=
prom
etheus
.
NewHistogramVec
(
imageResizeDurations
=
prom
auto
.
NewHistogramVec
(
prometheus
.
HistogramOpts
{
Namespace
:
namespace
,
Subsystem
:
subsystem
,
...
...
@@ -154,14 +154,6 @@ const (
maxMagicLen
=
8
// 8 first bytes is enough to detect PNG or JPEG
)
func
init
()
{
prometheus
.
MustRegister
(
imageResizeConcurrencyLimitExceeds
)
prometheus
.
MustRegister
(
imageResizeProcesses
)
prometheus
.
MustRegister
(
imageResizeMaxProcesses
)
prometheus
.
MustRegister
(
imageResizeRequests
)
prometheus
.
MustRegister
(
imageResizeDurations
)
}
func
NewResizer
(
cfg
config
.
Config
)
*
Resizer
{
imageResizeMaxProcesses
.
Set
(
float64
(
cfg
.
ImageResizerConfig
.
MaxScalerProcs
))
...
...
@@ -279,6 +271,10 @@ func (r *Resizer) tryResizeImage(req *http.Request, f *imageFile, params *resize
return
f
.
reader
,
nil
,
fmt
.
Errorf
(
"%d bytes exceeds maximum file size of %d bytes"
,
f
.
contentLength
,
cfg
.
MaxFilesize
)
}
if
f
.
contentLength
<
maxMagicLen
{
return
f
.
reader
,
nil
,
fmt
.
Errorf
(
"file is too small to resize: %d bytes"
,
f
.
contentLength
)
}
if
!
r
.
numScalerProcs
.
tryIncrement
(
int32
(
cfg
.
MaxScalerProcs
))
{
return
f
.
reader
,
nil
,
fmt
.
Errorf
(
"too many running scaler processes (%d / %d)"
,
r
.
numScalerProcs
.
n
,
cfg
.
MaxScalerProcs
)
}
...
...
@@ -289,11 +285,16 @@ func (r *Resizer) tryResizeImage(req *http.Request, f *imageFile, params *resize
r
.
numScalerProcs
.
decrement
()
}()
// Prevents EOF if the file is smaller than 8 bytes
bufferSize
:=
int
(
math
.
Min
(
maxMagicLen
,
float64
(
f
.
contentLength
)))
buffered
:=
bufio
.
NewReaderSize
(
f
.
reader
,
bufferSize
)
// Creating buffered Reader is required for us to Peek into first bytes of the image file to detect the format
// without advancing the reader (we need to read from the file start in the Scaler binary).
// We set `8` as the minimal buffer size by the length of PNG magic bytes sequence (JPEG needs only 2).
// In fact, `NewReaderSize` will immediately override it with `16` using its `minReadBufferSize` -
// here we are just being explicit about the buffer size required for our code to operate correctly.
// Having a reader with such tiny buffer will not hurt the performance during further operations,
// because Golang `bufio.Read` avoids double copy: https://golang.org/src/bufio/bufio.go?s=1768:1804#L212
buffered
:=
bufio
.
NewReaderSize
(
f
.
reader
,
maxMagicLen
)
headerBytes
,
err
:=
buffered
.
Peek
(
bufferSize
)
headerBytes
,
err
:=
buffered
.
Peek
(
maxMagicLen
)
if
err
!=
nil
{
return
buffered
,
nil
,
fmt
.
Errorf
(
"peek stream: %v"
,
err
)
}
...
...
workhorse/internal/imageresizer/image_resizer_test.go
View file @
107768e4
...
...
@@ -198,6 +198,29 @@ func TestServeOriginalImageWhenSourceImageFormatIsNotAllowed(t *testing.T) {
require
.
Equal
(
t
,
svgImage
,
responseData
,
"expected original image"
)
}
func
TestServeOriginalImageWhenSourceImageIsTooSmall
(
t
*
testing
.
T
)
{
content
:=
[]
byte
(
"PNG"
)
// 3 bytes only, invalid as PNG/JPEG image
img
,
err
:=
ioutil
.
TempFile
(
""
,
"*.png"
)
require
.
NoError
(
t
,
err
)
defer
img
.
Close
()
defer
os
.
Remove
(
img
.
Name
())
_
,
err
=
img
.
Write
(
content
)
require
.
NoError
(
t
,
err
)
cfg
:=
config
.
DefaultImageResizerConfig
params
:=
resizeParams
{
Location
:
img
.
Name
(),
ContentType
:
"image/png"
,
Width
:
64
}
resp
:=
requestScaledImage
(
t
,
nil
,
params
,
cfg
)
require
.
Equal
(
t
,
http
.
StatusOK
,
resp
.
StatusCode
)
responseData
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
content
,
responseData
,
"expected original image"
)
}
// The Rails applications sends a Base64 encoded JSON string carrying
// these parameters in an HTTP response header
func
encodeParams
(
t
*
testing
.
T
,
p
*
resizeParams
)
string
{
...
...
workhorse/internal/objectstore/prometheus.go
View file @
107768e4
package
objectstore
import
"github.com/prometheus/client_golang/prometheus"
import
(
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var
(
objectStorageUploadRequests
=
prom
etheus
.
NewCounterVec
(
objectStorageUploadRequests
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_object_storage_upload_requests"
,
Help
:
"How many object storage requests have been processed"
,
},
[]
string
{
"status"
},
)
objectStorageUploadsOpen
=
prom
etheus
.
NewGauge
(
objectStorageUploadsOpen
=
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"gitlab_workhorse_object_storage_upload_open"
,
Help
:
"Describes many object storage requests are open now"
,
},
)
objectStorageUploadBytes
=
prom
etheus
.
NewCounter
(
objectStorageUploadBytes
=
prom
auto
.
NewCounter
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_object_storage_upload_bytes"
,
Help
:
"How many bytes were sent to object storage"
,
},
)
objectStorageUploadTime
=
prom
etheus
.
NewHistogram
(
objectStorageUploadTime
=
prom
auto
.
NewHistogram
(
prometheus
.
HistogramOpts
{
Name
:
"gitlab_workhorse_object_storage_upload_time"
,
Help
:
"How long it took to upload objects"
,
...
...
@@ -34,10 +37,3 @@ var (
objectStorageUploadTimeBuckets
=
[]
float64
{
.1
,
.25
,
.5
,
1
,
2.5
,
5
,
10
,
25
,
50
,
100
}
)
func
init
()
{
prometheus
.
MustRegister
(
objectStorageUploadRequests
,
objectStorageUploadsOpen
,
objectStorageUploadBytes
)
}
workhorse/internal/objectstore/uploader.go
View file @
107768e4
...
...
@@ -90,6 +90,8 @@ func (u *uploader) Consume(outerCtx context.Context, reader io.Reader, deadline
}
}
objectStorageUploadBytes
.
Add
(
float64
(
cr
.
n
))
return
cr
.
n
,
nil
}
...
...
workhorse/internal/queueing/queue.go
View file @
107768e4
...
...
@@ -5,6 +5,7 @@ import (
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
type
errTooManyRequests
struct
{
error
}
...
...
@@ -44,7 +45,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics {
}
metrics
:=
&
queueMetrics
{
queueingLimit
:
prom
etheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
queueingLimit
:
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"gitlab_workhorse_queueing_limit"
,
Help
:
"Current limit set for the queueing mechanism"
,
ConstLabels
:
prometheus
.
Labels
{
...
...
@@ -52,7 +53,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics {
},
}),
queueingQueueLimit
:
prom
etheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
queueingQueueLimit
:
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"gitlab_workhorse_queueing_queue_limit"
,
Help
:
"Current queueLimit set for the queueing mechanism"
,
ConstLabels
:
prometheus
.
Labels
{
...
...
@@ -60,7 +61,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics {
},
}),
queueingQueueTimeout
:
prom
etheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
queueingQueueTimeout
:
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"gitlab_workhorse_queueing_queue_timeout"
,
Help
:
"Current queueTimeout set for the queueing mechanism"
,
ConstLabels
:
prometheus
.
Labels
{
...
...
@@ -68,7 +69,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics {
},
}),
queueingBusy
:
prom
etheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
queueingBusy
:
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"gitlab_workhorse_queueing_busy"
,
Help
:
"How many queued requests are now processed"
,
ConstLabels
:
prometheus
.
Labels
{
...
...
@@ -76,7 +77,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics {
},
}),
queueingWaiting
:
prom
etheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
queueingWaiting
:
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"gitlab_workhorse_queueing_waiting"
,
Help
:
"How many requests are now queued"
,
ConstLabels
:
prometheus
.
Labels
{
...
...
@@ -84,7 +85,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics {
},
}),
queueingWaitingTime
:
prom
etheus
.
NewHistogram
(
prometheus
.
HistogramOpts
{
queueingWaitingTime
:
prom
auto
.
NewHistogram
(
prometheus
.
HistogramOpts
{
Name
:
"gitlab_workhorse_queueing_waiting_time"
,
Help
:
"How many time a request spent in queue"
,
ConstLabels
:
prometheus
.
Labels
{
...
...
@@ -93,7 +94,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics {
Buckets
:
waitingTimeBuckets
,
}),
queueingErrors
:
prom
etheus
.
NewCounterVec
(
queueingErrors
:
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_queueing_errors"
,
Help
:
"How many times the TooManyRequests or QueueintTimedout errors were returned while queueing, partitioned by error type"
,
...
...
@@ -105,14 +106,6 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics {
),
}
prometheus
.
MustRegister
(
metrics
.
queueingLimit
)
prometheus
.
MustRegister
(
metrics
.
queueingQueueLimit
)
prometheus
.
MustRegister
(
metrics
.
queueingQueueTimeout
)
prometheus
.
MustRegister
(
metrics
.
queueingBusy
)
prometheus
.
MustRegister
(
metrics
.
queueingWaiting
)
prometheus
.
MustRegister
(
metrics
.
queueingWaitingTime
)
prometheus
.
MustRegister
(
metrics
.
queueingErrors
)
return
metrics
}
...
...
workhorse/internal/redis/keywatcher.go
View file @
107768e4
...
...
@@ -9,6 +9,7 @@ import (
"github.com/gomodule/redigo/redis"
"github.com/jpillora/backoff"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/labkit/log"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
...
...
@@ -24,13 +25,13 @@ var (
Factor
:
2
,
Jitter
:
true
,
}
keyWatchers
=
prom
etheus
.
NewGauge
(
keyWatchers
=
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"gitlab_workhorse_keywatcher_keywatchers"
,
Help
:
"The number of keys that is being watched by gitlab-workhorse"
,
},
)
totalMessages
=
prom
etheus
.
NewCounter
(
totalMessages
=
prom
auto
.
NewCounter
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_keywatcher_total_messages"
,
Help
:
"How many messages gitlab-workhorse has received in total on pubsub."
,
...
...
@@ -38,13 +39,6 @@ var (
)
)
func
init
()
{
prometheus
.
MustRegister
(
keyWatchers
,
totalMessages
,
)
}
const
(
keySubChannel
=
"workhorse:notifications"
)
...
...
workhorse/internal/redis/redis.go
View file @
107768e4
...
...
@@ -10,6 +10,7 @@ import (
"github.com/FZambia/sentinel"
"github.com/gomodule/redigo/redis"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/labkit/log"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/config"
...
...
@@ -45,14 +46,14 @@ const (
)
var
(
totalConnections
=
prom
etheus
.
NewCounter
(
totalConnections
=
prom
auto
.
NewCounter
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_redis_total_connections"
,
Help
:
"How many connections gitlab-workhorse has opened in total. Can be used to track Redis connection rate for this process"
,
},
)
errorCounter
=
prom
etheus
.
NewCounterVec
(
errorCounter
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_redis_errors"
,
Help
:
"Counts different types of Redis errors encountered by workhorse, by type and destination (redis, sentinel)"
,
...
...
@@ -61,13 +62,6 @@ var (
)
)
func
init
()
{
prometheus
.
MustRegister
(
totalConnections
,
errorCounter
,
)
}
func
sentinelConn
(
master
string
,
urls
[]
config
.
TomlURL
)
*
sentinel
.
Sentinel
{
if
len
(
urls
)
==
0
{
return
nil
...
...
workhorse/internal/senddata/senddata.go
View file @
107768e4
...
...
@@ -8,17 +8,18 @@ import (
"gitlab.com/gitlab-org/gitlab-workhorse/internal/senddata/contentprocessor"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var
(
sendDataResponses
=
prom
etheus
.
NewCounterVec
(
sendDataResponses
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_senddata_responses"
,
Help
:
"How many HTTP responses have been hijacked by a workhorse senddata injecter"
,
},
[]
string
{
"injecter"
},
)
sendDataResponseBytes
=
prom
etheus
.
NewCounterVec
(
sendDataResponseBytes
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_senddata_response_bytes"
,
Help
:
"How many bytes have been written by workhorse senddata response injecters"
,
...
...
@@ -27,11 +28,6 @@ var (
)
)
func
init
()
{
prometheus
.
MustRegister
(
sendDataResponses
)
prometheus
.
MustRegister
(
sendDataResponseBytes
)
}
type
sendDataResponseWriter
struct
{
rw
http
.
ResponseWriter
status
int
...
...
workhorse/internal/sendfile/sendfile.go
View file @
107768e4
...
...
@@ -14,6 +14,7 @@ import (
"regexp"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/labkit/log"
"gitlab.com/gitlab-org/labkit/mask"
...
...
@@ -23,7 +24,7 @@ import (
)
var
(
sendFileRequests
=
prom
etheus
.
NewCounterVec
(
sendFileRequests
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_sendfile_requests"
,
Help
:
"How many X-Sendfile requests have been processed by gitlab-workhorse, partitioned by sendfile type."
,
...
...
@@ -31,7 +32,7 @@ var (
[]
string
{
"type"
},
)
sendFileBytes
=
prom
etheus
.
NewCounterVec
(
sendFileBytes
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_sendfile_bytes"
,
Help
:
"How many X-Sendfile bytes have been sent by gitlab-workhorse, partitioned by sendfile type."
,
...
...
@@ -49,11 +50,6 @@ type sendFileResponseWriter struct {
req
*
http
.
Request
}
func
init
()
{
prometheus
.
MustRegister
(
sendFileRequests
)
prometheus
.
MustRegister
(
sendFileBytes
)
}
func
SendFile
(
h
http
.
Handler
)
http
.
Handler
{
return
http
.
HandlerFunc
(
func
(
rw
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
s
:=
&
sendFileResponseWriter
{
...
...
workhorse/internal/sendurl/sendurl.go
View file @
107768e4
...
...
@@ -8,6 +8,7 @@ import (
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/labkit/correlation"
"gitlab.com/gitlab-org/labkit/log"
...
...
@@ -68,20 +69,20 @@ var httpClient = &http.Client{
}
var
(
sendURLRequests
=
prom
etheus
.
NewCounterVec
(
sendURLRequests
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_send_url_requests"
,
Help
:
"How many send URL requests have been processed"
,
},
[]
string
{
"status"
},
)
sendURLOpenRequests
=
prom
etheus
.
NewGauge
(
sendURLOpenRequests
=
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Name
:
"gitlab_workhorse_send_url_open_requests"
,
Help
:
"Describes how many send URL requests are open now"
,
},
)
sendURLBytes
=
prom
etheus
.
NewCounter
(
sendURLBytes
=
prom
auto
.
NewCounter
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_send_url_bytes"
,
Help
:
"How many bytes were passed with send URL"
,
...
...
@@ -93,13 +94,6 @@ var (
sendURLRequestsSucceeded
=
sendURLRequests
.
WithLabelValues
(
"succeeded"
)
)
func
init
()
{
prometheus
.
MustRegister
(
sendURLRequests
,
sendURLOpenRequests
,
sendURLBytes
)
}
func
(
e
*
entry
)
Inject
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
sendData
string
)
{
var
params
entryParams
...
...
workhorse/internal/staticpages/error_pages.go
View file @
107768e4
...
...
@@ -8,12 +8,13 @@ import (
"path/filepath"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
)
var
(
staticErrorResponses
=
prom
etheus
.
NewCounterVec
(
staticErrorResponses
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_static_error_responses"
,
Help
:
"How many HTTP responses have been changed to a static error page, by HTTP status code."
,
...
...
@@ -30,10 +31,6 @@ const (
ErrorFormatText
)
func
init
()
{
prometheus
.
MustRegister
(
staticErrorResponses
)
}
type
errorPageResponseWriter
struct
{
rw
http
.
ResponseWriter
status
int
...
...
workhorse/internal/upload/rewrite.go
View file @
107768e4
...
...
@@ -11,6 +11,7 @@ import (
"strings"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"gitlab.com/gitlab-org/labkit/log"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/api"
...
...
@@ -23,7 +24,7 @@ import (
var
ErrInjectedClientParam
=
errors
.
New
(
"injected client parameter"
)
var
(
multipartUploadRequests
=
prom
etheus
.
NewCounterVec
(
multipartUploadRequests
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_multipart_upload_requests"
,
...
...
@@ -32,7 +33,7 @@ var (
[]
string
{
"type"
},
)
multipartFileUploadBytes
=
prom
etheus
.
NewCounterVec
(
multipartFileUploadBytes
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_multipart_upload_bytes"
,
Help
:
"How many disk bytes of multipart file parts have been successfully written by gitlab-workhorse. Partitioned by type."
,
...
...
@@ -40,7 +41,7 @@ var (
[]
string
{
"type"
},
)
multipartFiles
=
prom
etheus
.
NewCounterVec
(
multipartFiles
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Name
:
"gitlab_workhorse_multipart_upload_files"
,
Help
:
"How many multipart file parts have been processed by gitlab-workhorse. Partitioned by type."
,
...
...
@@ -56,12 +57,6 @@ type rewriter struct {
finalizedFields
map
[
string
]
bool
}
func
init
()
{
prometheus
.
MustRegister
(
multipartUploadRequests
)
prometheus
.
MustRegister
(
multipartFileUploadBytes
)
prometheus
.
MustRegister
(
multipartFiles
)
}
func
rewriteFormFilesFromMultipart
(
r
*
http
.
Request
,
writer
*
multipart
.
Writer
,
preauth
*
api
.
Response
,
filter
MultipartFormProcessor
,
opts
*
filestore
.
SaveFileOpts
)
error
{
// Create multipart reader
reader
,
err
:=
r
.
MultipartReader
()
...
...
workhorse/internal/upstream/metrics.go
View file @
107768e4
...
...
@@ -4,6 +4,7 @@ import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
...
...
@@ -40,14 +41,14 @@ func byteSizeBuckets() []float64 {
}
var
(
httpInFlightRequests
=
prom
etheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
httpInFlightRequests
=
prom
auto
.
NewGauge
(
prometheus
.
GaugeOpts
{
Namespace
:
namespace
,
Subsystem
:
httpSubsystem
,
Name
:
"in_flight_requests"
,
Help
:
"A gauge of requests currently being served by workhorse."
,
})
httpRequestsTotal
=
prom
etheus
.
NewCounterVec
(
httpRequestsTotal
=
prom
auto
.
NewCounterVec
(
prometheus
.
CounterOpts
{
Namespace
:
namespace
,
Subsystem
:
httpSubsystem
,
...
...
@@ -57,7 +58,7 @@ var (
[]
string
{
"code"
,
"method"
,
"route"
},
)
httpRequestDurationSeconds
=
prom
etheus
.
NewHistogramVec
(
httpRequestDurationSeconds
=
prom
auto
.
NewHistogramVec
(
prometheus
.
HistogramOpts
{
Namespace
:
namespace
,
Subsystem
:
httpSubsystem
,
...
...
@@ -68,7 +69,7 @@ var (
[]
string
{
"code"
,
"method"
,
"route"
},
)
httpRequestSizeBytes
=
prom
etheus
.
NewHistogramVec
(
httpRequestSizeBytes
=
prom
auto
.
NewHistogramVec
(
prometheus
.
HistogramOpts
{
Namespace
:
namespace
,
Subsystem
:
httpSubsystem
,
...
...
@@ -79,7 +80,7 @@ var (
[]
string
{
"code"
,
"method"
,
"route"
},
)
httpResponseSizeBytes
=
prom
etheus
.
NewHistogramVec
(
httpResponseSizeBytes
=
prom
auto
.
NewHistogramVec
(
prometheus
.
HistogramOpts
{
Namespace
:
namespace
,
Subsystem
:
httpSubsystem
,
...
...
@@ -90,7 +91,7 @@ var (
[]
string
{
"code"
,
"method"
,
"route"
},
)
httpTimeToWriteHeaderSeconds
=
prom
etheus
.
NewHistogramVec
(
httpTimeToWriteHeaderSeconds
=
prom
auto
.
NewHistogramVec
(
prometheus
.
HistogramOpts
{
Namespace
:
namespace
,
Subsystem
:
httpSubsystem
,
...
...
@@ -102,14 +103,6 @@ var (
)
)
func
init
()
{
prometheus
.
MustRegister
(
httpInFlightRequests
)
prometheus
.
MustRegister
(
httpRequestsTotal
)
prometheus
.
MustRegister
(
httpRequestDurationSeconds
)
prometheus
.
MustRegister
(
httpRequestSizeBytes
)
prometheus
.
MustRegister
(
httpTimeToWriteHeaderSeconds
)
}
func
instrumentRoute
(
next
http
.
Handler
,
method
string
,
regexpStr
string
)
http
.
Handler
{
handler
:=
next
...
...
workhorse/internal/upstream/routes.go
View file @
107768e4
...
...
@@ -192,6 +192,16 @@ func (u *upstream) configureRoutes() {
proxy
:=
buildProxy
(
u
.
Backend
,
u
.
Version
,
u
.
RoundTripper
,
u
.
Config
)
cableProxy
:=
proxypkg
.
NewProxy
(
u
.
CableBackend
,
u
.
Version
,
u
.
CableRoundTripper
)
assetsNotFoundHandler
:=
NotFoundUnless
(
u
.
DevelopmentMode
,
proxy
)
if
u
.
AltDocumentRoot
!=
""
{
altStatic
:=
&
staticpages
.
Static
{
DocumentRoot
:
u
.
AltDocumentRoot
}
assetsNotFoundHandler
=
altStatic
.
ServeExisting
(
u
.
URLPrefix
,
staticpages
.
CacheExpireMax
,
NotFoundUnless
(
u
.
DevelopmentMode
,
proxy
),
)
}
signingTripper
:=
secret
.
NewRoundTripper
(
u
.
RoundTripper
,
u
.
Version
)
signingProxy
:=
buildProxy
(
u
.
Backend
,
u
.
Version
,
signingTripper
,
u
.
Config
)
...
...
@@ -283,7 +293,7 @@ func (u *upstream) configureRoutes() {
static
.
ServeExisting
(
u
.
URLPrefix
,
staticpages
.
CacheExpireMax
,
NotFoundUnless
(
u
.
DevelopmentMode
,
proxy
)
,
assetsNotFoundHandler
,
),
withoutTracing
(),
// Tracing on assets is very noisy
),
...
...
workhorse/main.go
View file @
107768e4
...
...
@@ -143,6 +143,7 @@ func buildConfig(arg0 string, args []string) (*bootConfig, *config.Config, error
cfg
.
Redis
=
cfgFromFile
.
Redis
cfg
.
ObjectStorageCredentials
=
cfgFromFile
.
ObjectStorageCredentials
cfg
.
ImageResizerConfig
=
cfgFromFile
.
ImageResizerConfig
cfg
.
AltDocumentRoot
=
cfgFromFile
.
AltDocumentRoot
return
boot
,
cfg
,
nil
}
...
...
workhorse/main_test.go
View file @
107768e4
...
...
@@ -38,6 +38,7 @@ import (
const
scratchDir
=
"testdata/scratch"
const
testRepoRoot
=
"testdata/data"
const
testDocumentRoot
=
"testdata/public"
const
testAltDocumentRoot
=
"testdata/alt-public"
var
absDocumentRoot
string
...
...
@@ -312,6 +313,72 @@ func TestGzipAssets(t *testing.T) {
}
}
func
TestAltDocumentAssets
(
t
*
testing
.
T
)
{
path
:=
"/assets/static.txt"
content
:=
"asset"
require
.
NoError
(
t
,
setupAltStaticFile
(
path
,
content
))
buf
:=
&
bytes
.
Buffer
{}
gzipWriter
:=
gzip
.
NewWriter
(
buf
)
_
,
err
:=
gzipWriter
.
Write
([]
byte
(
content
))
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
gzipWriter
.
Close
())
contentGzip
:=
buf
.
String
()
require
.
NoError
(
t
,
setupAltStaticFile
(
path
+
".gz"
,
contentGzip
))
proxied
:=
false
ts
:=
testhelper
.
TestServerWithHandler
(
regexp
.
MustCompile
(
`.`
),
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
proxied
=
true
w
.
WriteHeader
(
404
)
})
defer
ts
.
Close
()
upstreamConfig
:=
newUpstreamConfig
(
ts
.
URL
)
upstreamConfig
.
AltDocumentRoot
=
testAltDocumentRoot
ws
:=
startWorkhorseServerWithConfig
(
upstreamConfig
)
defer
ws
.
Close
()
testCases
:=
[]
struct
{
desc
string
path
string
content
string
acceptEncoding
string
contentEncoding
string
}{
{
desc
:
"plaintext asset"
,
path
:
path
,
content
:
content
},
{
desc
:
"gzip asset available"
,
path
:
path
,
content
:
contentGzip
,
acceptEncoding
:
"gzip"
,
contentEncoding
:
"gzip"
},
{
desc
:
"non-existent file"
,
path
:
"/assets/non-existent"
},
}
for
_
,
tc
:=
range
testCases
{
req
,
err
:=
http
.
NewRequest
(
"GET"
,
ws
.
URL
+
tc
.
path
,
nil
)
require
.
NoError
(
t
,
err
)
if
tc
.
acceptEncoding
!=
""
{
req
.
Header
.
Set
(
"Accept-Encoding"
,
tc
.
acceptEncoding
)
}
resp
,
err
:=
http
.
DefaultTransport
.
RoundTrip
(
req
)
require
.
NoError
(
t
,
err
)
defer
resp
.
Body
.
Close
()
b
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
require
.
NoError
(
t
,
err
)
if
tc
.
content
!=
""
{
require
.
Equal
(
t
,
200
,
resp
.
StatusCode
,
"%s: status code"
,
tc
.
desc
)
require
.
Equal
(
t
,
tc
.
content
,
string
(
b
),
"%s: response body"
,
tc
.
desc
)
require
.
False
(
t
,
proxied
,
"%s: should not have made it to backend"
,
tc
.
desc
)
if
tc
.
contentEncoding
!=
""
{
require
.
Equal
(
t
,
tc
.
contentEncoding
,
resp
.
Header
.
Get
(
"Content-Encoding"
))
}
}
else
{
require
.
Equal
(
t
,
404
,
resp
.
StatusCode
,
"%s: status code"
,
tc
.
desc
)
}
}
}
var
sendDataHeader
=
"Gitlab-Workhorse-Send-Data"
func
sendDataResponder
(
command
string
,
literalJSON
string
)
*
httptest
.
Server
{
...
...
@@ -576,11 +643,19 @@ func TestPropagateCorrelationIdHeader(t *testing.T) {
}
func
setupStaticFile
(
fpath
,
content
string
)
error
{
return
setupStaticFileHelper
(
fpath
,
content
,
testDocumentRoot
)
}
func
setupAltStaticFile
(
fpath
,
content
string
)
error
{
return
setupStaticFileHelper
(
fpath
,
content
,
testAltDocumentRoot
)
}
func
setupStaticFileHelper
(
fpath
,
content
,
directory
string
)
error
{
cwd
,
err
:=
os
.
Getwd
()
if
err
!=
nil
{
return
err
}
absDocumentRoot
=
path
.
Join
(
cwd
,
testDocumentRoot
)
absDocumentRoot
=
path
.
Join
(
cwd
,
directory
)
if
err
:=
os
.
MkdirAll
(
path
.
Join
(
absDocumentRoot
,
path
.
Dir
(
fpath
)),
0755
);
err
!=
nil
{
return
err
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment