https://zhuanlan.zhihu.com/p/585435721gitlab支持upload/artifacts/lfs等数据使用object 目标存储,它使用的模块是fog。包
括aws,aliyun,google等多家云厂商的OSS存储。唯独不支持COS。考虑到大多OSS都是使
用amazon S3作为模板,我在配置文件里设置aws作为后端存储,/etc/gitlab/gitlib.rb
配置如下:
```
gitlab_rails['uploads_directory'] = "/var/opt/gitlab/gitlab-rails/uploads"
gitlab_rails['uploads_base_dir'] = "uploads/-/system"
gitlab_rails['uploads_object_store_enabled'] = true
gitlab_rails['uploads_object_store_proxy_download'] = false
gitlab_rails['uploads_object_store_remote_directory'] = "uploads"
gitlab_rails['uploads_object_store_connection'] = {
'provider' => 'AWS',
# 'region' => 'eu-west-1',
'aws_access_key_id' => 'AKXXXXXXXXXQ1K',
'aws_secret_access_key' => '3xxxxxxxxxxxxAft', # 配置cos的AK,最好使用最小权
限系统
# # The below options configure an S3 compatible host instead of
AWSgitlab.rb
#'host' => 'cos.ap-shanghai.myqcloud.com',
# 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if
provider does not support v4.
'endpoint' => '
https://gitlab-upload-xxxxxxxx.cos.ap-shanghai.myqcloud.com',
# default: nil - Useful for S3 compliant services suc
'path_style' => true# Use 'host/bucket_name/object' instead of
'bucket_name.host/object'
}
```
lfs/artifacts的配置类似。
这时候,重新使用gitlab-ctl reconfigure或者redploy一下gitlab的deployment即可。
上传文件测试, 发现上传失败,查看日志,错误如下:
...
<?xml version='1.0' encoding='utf-8' ?>
<Error>
<Code>InvalidArgument</Code>
<Message>Copy Source must mention the source bucket and key :
sourcebucket-appid.cos.region.myqcloud/sourcekey</Message>
<Resource>/uploads/@hashed/4f/c8/4fc82b26aecb47d2868c4efbe3581732a3e7c
bcc6c2efb32062c08170a05eeb8/25385d0914d1b7365db5017f356b8fcf/oasis0928.pdf</Re
source>
<RequestId>xxxxxxxxx==</RequestId>
<TraceId>xxxxxxxxxxxxxxx=</TraceId>
</Error>
...
config/initializers/carrierwave_patch.rb:29:in `copy_to'
app/uploaders/object_storage.rb:393:in `store!'
app/services/upload_service.rb:18:in `execute'
app/controllers/concerns/uploads_actions.rb:17:in `create'
app/controllers/application_controller.rb:527:in `set_current_admin'
lib/gitlab/session.rb:11:in `with_session'
app/controllers/application_controller.rb:518:in `set_session_storage'
查COS的文档,对比AWS的API,发现问题了。
COS的COPY OBJECT方法API如下:
```
PUT /<ObjectKey> HTTP/1.1
Host: <BucketName-APPID>.cos.<Region>.myqcloud.com
Date: GMT Date
x-cos-copy-source: <SourceBucketName-SourceAPPID>.cos.<SourceRegion>.myqcloud.
com/<SourceObjectKey>
Content-Length: 0
Authorization: Auth String
```
AWS OSS的API
```
PUT /my-second-image.jpg HTTP/1.1
Host: bucket.s3.<Region>.amazonaws.com
Date: Wed, 28 Oct 2009 22:32:00 GMT
x-amz-copy-source: /bucket/my-image.jpg
Authorization: authorization string
```
发现,copy_source的格式发生了改动。没办法,手工修改fog的代码吧,找到fog-aws发
送request的代码,增加下列代码:
```
diff --git a/lib/fog/aws/storage.rb b/lib/fog/aws/storage.rb
index 73e72aef1..6603ea2f7 100644
--- a/lib/fog/aws/storage.rb
+++ b/lib/fog/aws/storage.rb
@@ -629,7 +627,9 @@ module Fog
host = params.delete(:host)
port = params.delete(:port) || DEFAULT_SCHEME_PORT[scheme]
params[:headers]['Host'] = host
-
+ if host.downcase =~ (/.*myqcloud.com.*/) && params[:headers]["x-amz
-copy-source"] != nil
+ params[:headers]["x-amz-copy-source"] = "#{host}#{params[:headers
]["x-amz-copy-source"]}"
+ end
if @signature_version == 4
params[:headers]['x-amz-date'] = date.to_iso8601_basic
```
就是说,如果请求的是COS的url,且是copy object,就把header里的x-amz-copy-source
前面加上host。
修改后,如何让它生效也是个问题,一方面,gitlab我始终要升级,不然有些漏洞可能致
命,但是每次升级,都需要重新打包也很头大。为了解决这个问题,我设置一个了
configmap,把storage.rb的代码放在里面,然后在gitlab的配置里增加一个configmap映
射的存储,后续修改的代码也都可以放在这个configmap里。
configmap的配置文件:
```
apiVersion: v1
data:
storage.rb: |-
module Fog
....
kind: ConfigMap
metadata:
name: production.rb
namespace: devops
```
gitlab增加的配置
```
...
- configMap:
defaultMode: 420
name: production.rb
name: vol-t9tgv
...
volumeMounts:
- mountPath: /opt/gitlab/embedded/lib/ruby/gems/2.7.0/gems/fog-aws-3.1
4.0/lib/fog/aws/storage.rb
name: vol-t9tgv
subPath: storage.rb
```
这样每次启动时,容器会自动加载这个ConfigMap里的storage.rb,覆盖掉容器里原有的
文件,从而达到修改的目的。
而每次当gitlab升级后,重新用diff生成新的文件即可。
当然,还有一个坑暂时没有解决,就是要定时clean 无效的upload和lfs,仍然是cos的
api的锅,哪天有空再看看吧。
--
FROM 119.139.198.*