Merge branch 'master' into remove-lib

This commit is contained in:
Will Sun 2019-11-27 17:44:30 +08:00 committed by GitHub
commit a52b99e180
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 293 additions and 97 deletions

View File

@ -1,23 +1,23 @@
sudo: true sudo: true
language: go language: go
go: go:
- 1.12.12 - 1.13.4
go_import_path: github.com/goharbor/harbor go_import_path: github.com/goharbor/harbor
services: services:
- docker - docker
dist: trusty dist: trusty
matrix: matrix:
include: include:
- go: 1.12.12 - go: 1.13.4
env: env:
- UTTEST=true - UTTEST=true
- go: 1.12.12 - go: 1.13.4
env: env:
- APITEST_DB=true - APITEST_DB=true
- go: 1.12.12 - go: 1.13.4
env: env:
- APITEST_LDAP=true - APITEST_LDAP=true
- go: 1.12.12 - go: 1.13.4
env: env:
- OFFLINE=true - OFFLINE=true
- language: node_js - language: node_js

View File

@ -128,6 +128,8 @@ Harbor backend is written in [Go](http://golang.org/). If you don't have a Harbo
| 1.7 | 1.9.2 | | 1.7 | 1.9.2 |
| 1.8 | 1.11.2 | | 1.8 | 1.11.2 |
| 1.9 | 1.12.12 | | 1.9 | 1.12.12 |
| 1.10 | 1.12.12 |
| 1.11 | 1.13.4 |
Ensure your GOPATH and PATH have been configured in accordance with the Go environment instructions. Ensure your GOPATH and PATH have been configured in accordance with the Go environment instructions.

View File

@ -9,7 +9,7 @@
# compile_golangimage: # compile_golangimage:
# compile from golang image # compile from golang image
# for example: make compile_golangimage -e GOBUILDIMAGE= \ # for example: make compile_golangimage -e GOBUILDIMAGE= \
# golang:1.12.12 # golang:1.13.4
# compile_core, compile_jobservice: compile specific binary # compile_core, compile_jobservice: compile specific binary
# #
# build: build Harbor docker images from photon baseimage # build: build Harbor docker images from photon baseimage
@ -138,7 +138,7 @@ GOINSTALL=$(GOCMD) install
GOTEST=$(GOCMD) test GOTEST=$(GOCMD) test
GODEP=$(GOTEST) -i GODEP=$(GOTEST) -i
GOFMT=gofmt -w GOFMT=gofmt -w
GOBUILDIMAGE=golang:1.12.12 GOBUILDIMAGE=golang:1.13.4
GOBUILDPATH=/harbor GOBUILDPATH=/harbor
# go build # go build
@ -323,7 +323,7 @@ build:
-e CLAIRVERSION=$(CLAIRVERSION) -e CLAIRADAPTERVERSION=$(CLAIRADAPTERVERSION) -e VERSIONTAG=$(VERSIONTAG) \ -e CLAIRVERSION=$(CLAIRVERSION) -e CLAIRADAPTERVERSION=$(CLAIRADAPTERVERSION) -e VERSIONTAG=$(VERSIONTAG) \
-e BUILDBIN=$(BUILDBIN) -e REDISVERSION=$(REDISVERSION) -e MIGRATORVERSION=$(MIGRATORVERSION) \ -e BUILDBIN=$(BUILDBIN) -e REDISVERSION=$(REDISVERSION) -e MIGRATORVERSION=$(MIGRATORVERSION) \
-e CHARTMUSEUMVERSION=$(CHARTMUSEUMVERSION) -e DOCKERIMAGENAME_CHART_SERVER=$(DOCKERIMAGENAME_CHART_SERVER) \ -e CHARTMUSEUMVERSION=$(CHARTMUSEUMVERSION) -e DOCKERIMAGENAME_CHART_SERVER=$(DOCKERIMAGENAME_CHART_SERVER) \
-e NPM_REGISTRY=$(NPM_REGISTRY) -e BASEIMAGETAG=${BASEIMAGETAG} -e NPM_REGISTRY=$(NPM_REGISTRY) -e BASEIMAGETAG=$(BASEIMAGETAG)
build_base_docker: build_base_docker:
@for name in chartserver clair clair-adapter core db jobservice log nginx notary-server notary-signer portal prepare redis registry registryctl; do \ @for name in chartserver clair clair-adapter core db jobservice log nginx notary-server notary-signer portal prepare redis registry registryctl; do \

View File

@ -13,10 +13,6 @@
|------------------| |------------------|
|The Harbor Project holds bi-weekly community calls in two different timezones. To join the community calls or to watch previous meeting notes and recordings, please visit the [meeting schedule](https://github.com/goharbor/community/blob/master/MEETING_SCHEDULE.md).| |The Harbor Project holds bi-weekly community calls in two different timezones. To join the community calls or to watch previous meeting notes and recordings, please visit the [meeting schedule](https://github.com/goharbor/community/blob/master/MEETING_SCHEDULE.md).|
We welcome you to join the below Harbor community events and meet with project maintainers and users:
**November 18-21, 2019**, [KubeCon US, San Diego](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019): Harbor Lunch & Learn led by Joe Beda, Intro and Deep-dive sessions.
</br> </br> </br> </br>
**Note**: The `master` branch may be in an *unstable or even broken state* during development. **Note**: The `master` branch may be in an *unstable or even broken state* during development.

View File

@ -43,25 +43,25 @@ You can compile the code by one of the three approaches:
- Get official Golang image from docker hub: - Get official Golang image from docker hub:
```sh ```sh
$ docker pull golang:1.12.12 $ docker pull golang:1.13.4
``` ```
- Build, install and bring up Harbor without Notary: - Build, install and bring up Harbor without Notary:
```sh ```sh
$ make install GOBUILDIMAGE=golang:1.12.12 COMPILETAG=compile_golangimage $ make install GOBUILDIMAGE=golang:1.13.4 COMPILETAG=compile_golangimage
``` ```
- Build, install and bring up Harbor with Notary: - Build, install and bring up Harbor with Notary:
```sh ```sh
$ make install GOBUILDIMAGE=golang:1.12.12 COMPILETAG=compile_golangimage NOTARYFLAG=true $ make install GOBUILDIMAGE=golang:1.13.4 COMPILETAG=compile_golangimage NOTARYFLAG=true
``` ```
- Build, install and bring up Harbor with Clair: - Build, install and bring up Harbor with Clair:
```sh ```sh
$ make install GOBUILDIMAGE=golang:1.12.12 COMPILETAG=compile_golangimage CLAIRFLAG=true $ make install GOBUILDIMAGE=golang:1.13.4 COMPILETAG=compile_golangimage CLAIRFLAG=true
``` ```
#### II. Compile code with your own Golang environment, then build Harbor #### II. Compile code with your own Golang environment, then build Harbor

View File

@ -36,10 +36,10 @@ version | set harbor version
#### EXAMPLE: #### EXAMPLE:
#### Build and run harbor from source code. #### Build and run harbor from source code.
make install GOBUILDIMAGE=golang:1.12.12 COMPILETAG=compile_golangimage NOTARYFLAG=true make install GOBUILDIMAGE=golang:1.13.4 COMPILETAG=compile_golangimage NOTARYFLAG=true
### Package offline installer ### Package offline installer
make package_offline GOBUILDIMAGE=golang:1.12.12 COMPILETAG=compile_golangimage NOTARYFLAG=true make package_offline GOBUILDIMAGE=golang:1.13.4 COMPILETAG=compile_golangimage NOTARYFLAG=true
### Start harbor with notary ### Start harbor with notary
make -e NOTARYFLAG=true start make -e NOTARYFLAG=true start

View File

@ -4,7 +4,7 @@ set +e
usage(){ usage(){
echo "Usage: builder <golang image:version> <code path> <code release tag> <main.go path> <binary name>" echo "Usage: builder <golang image:version> <code path> <code release tag> <main.go path> <binary name>"
echo "e.g: builder golang:1.11.2 github.com/helm/chartmuseum v0.9.0 cmd/chartmuseum chartm" echo "e.g: builder golang:1.13.4 https://github.com/helm/chartmuseum v0.9.0 cmd/chartmuseum chartm"
exit 1 exit 1
} }

View File

@ -1,4 +1,4 @@
FROM golang:1.12.12 FROM golang:1.13.4
ADD . /go/src/github.com/goharbor/harbor-scanner-clair/ ADD . /go/src/github.com/goharbor/harbor-scanner-clair/
WORKDIR /go/src/github.com/goharbor/harbor-scanner-clair/ WORKDIR /go/src/github.com/goharbor/harbor-scanner-clair/

View File

@ -23,7 +23,7 @@ TEMP=`mktemp -d ${TMPDIR-/tmp}/clair-adapter.XXXXXX`
git clone https://github.com/goharbor/harbor-scanner-clair.git $TEMP git clone https://github.com/goharbor/harbor-scanner-clair.git $TEMP
cd $TEMP; git checkout $VERSION; cd - cd $TEMP; git checkout $VERSION; cd -
echo 'build the clair adapter binary bases on the golang:1.12.12' echo 'build the clair adapter binary bases on the golang:1.13.4'
cp Dockerfile.binary $TEMP cp Dockerfile.binary $TEMP
docker build -f $TEMP/Dockerfile.binary -t clair-adapter-golang $TEMP docker build -f $TEMP/Dockerfile.binary -t clair-adapter-golang $TEMP

View File

@ -1,4 +1,4 @@
FROM golang:1.12.12 FROM golang:1.13.4
ADD . /go/src/github.com/coreos/clair/ ADD . /go/src/github.com/coreos/clair/
WORKDIR /go/src/github.com/coreos/clair/ WORKDIR /go/src/github.com/coreos/clair/

View File

@ -23,7 +23,7 @@ TEMP=`mktemp -d /$TMPDIR/clair.XXXXXX`
git clone https://github.com/coreos/clair.git $TEMP git clone https://github.com/coreos/clair.git $TEMP
cd $TEMP; git checkout $VERSION; cd - cd $TEMP; git checkout $VERSION; cd -
echo 'build the clair binary bases on the golang:1.12.12' echo 'build the clair binary bases on the golang:1.13.4'
cp Dockerfile.binary $TEMP cp Dockerfile.binary $TEMP
docker build -f $TEMP/Dockerfile.binary -t clair-golang $TEMP docker build -f $TEMP/Dockerfile.binary -t clair-golang $TEMP

View File

@ -1,4 +1,4 @@
FROM golang:1.12.12 FROM golang:1.13.4
ARG NOTARY_VERSION ARG NOTARY_VERSION
ARG MIGRATE_VERSION ARG MIGRATE_VERSION

View File

@ -1,4 +1,4 @@
FROM golang:1.12.12 FROM golang:1.13.4
ENV DISTRIBUTION_DIR /go/src/github.com/docker/distribution ENV DISTRIBUTION_DIR /go/src/github.com/docker/distribution
ENV BUILDTAGS include_oss include_gcs ENV BUILDTAGS include_oss include_gcs

View File

@ -50,7 +50,7 @@ type ProjectAPI struct {
} }
const projectNameMaxLen int = 255 const projectNameMaxLen int = 255
const projectNameMinLen int = 2 const projectNameMinLen int = 1
const restrictedNameChars = `[a-z0-9]+(?:[._-][a-z0-9]+)*` const restrictedNameChars = `[a-z0-9]+(?:[._-][a-z0-9]+)*`
// Prepare validates the URL and the user // Prepare validates the URL and the user

View File

@ -119,7 +119,7 @@ func TestAddProject(t *testing.T) {
// case 4: response code = 400 : Project name is illegal in length // case 4: response code = 400 : Project name is illegal in length
fmt.Println("case 4 : response code = 400 : Project name is illegal in length ") fmt.Println("case 4 : response code = 400 : Project name is illegal in length ")
result, err = apiTest.ProjectsPost(*admin, apilib.ProjectReq{ProjectName: "t", Metadata: map[string]string{models.ProMetaPublic: "true"}}) result, err = apiTest.ProjectsPost(*admin, apilib.ProjectReq{ProjectName: "", Metadata: map[string]string{models.ProMetaPublic: "true"}})
if err != nil { if err != nil {
t.Error("Error while creat project", err.Error()) t.Error("Error while creat project", err.Error())
t.Log(err) t.Log(err)

View File

@ -34,7 +34,6 @@ import (
"github.com/goharbor/harbor/src/core/auth" "github.com/goharbor/harbor/src/core/auth"
"github.com/goharbor/harbor/src/core/config" "github.com/goharbor/harbor/src/core/config"
"github.com/goharbor/harbor/src/pkg/authproxy" "github.com/goharbor/harbor/src/pkg/authproxy"
k8s_api_v1beta1 "k8s.io/api/authentication/v1beta1"
) )
const refreshDuration = 2 * time.Second const refreshDuration = 2 * time.Second
@ -101,31 +100,12 @@ func (a *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
s := session{} s := session{}
err = json.Unmarshal(data, &s) err = json.Unmarshal(data, &s)
if err != nil { if err != nil {
log.Errorf("failed to read session %v", err) return nil, auth.NewErrAuth(fmt.Sprintf("failed to read session %v", err))
} }
if err := a.tokenReview(s.SessionID, user); err != nil {
reviewResponse, err := a.tokenReview(s.SessionID) return nil, auth.NewErrAuth(err.Error())
if err != nil {
return nil, err
}
if reviewResponse == nil {
return nil, auth.ErrAuth{}
}
// Attach user group ID information
ugList := reviewResponse.Status.User.Groups
log.Debugf("user groups %+v", ugList)
if len(ugList) > 0 {
userGroups := models.UserGroupsFromName(ugList, common.HTTPGroupType)
groupIDList, err := group.PopulateGroup(userGroups)
if err != nil {
return nil, err
}
log.Debugf("current user's group ID list is %+v", groupIDList)
user.GroupIDs = groupIDList
} }
return user, nil return user, nil
} else if resp.StatusCode == http.StatusUnauthorized { } else if resp.StatusCode == http.StatusUnauthorized {
return nil, auth.ErrAuth{} return nil, auth.ErrAuth{}
} else { } else {
@ -134,17 +114,24 @@ func (a *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
log.Warningf("Failed to read response body, error: %v", err) log.Warningf("Failed to read response body, error: %v", err)
} }
return nil, fmt.Errorf("failed to authenticate, status code: %d, text: %s", resp.StatusCode, string(data)) return nil, fmt.Errorf("failed to authenticate, status code: %d, text: %s", resp.StatusCode, string(data))
}
} }
} func (a *Auth) tokenReview(sessionID string, user *models.User) error {
func (a *Auth) tokenReview(sessionID string) (*k8s_api_v1beta1.TokenReview, error) {
httpAuthProxySetting, err := config.HTTPAuthProxySetting() httpAuthProxySetting, err := config.HTTPAuthProxySetting()
if err != nil { if err != nil {
return nil, err return err
} }
return authproxy.TokenReview(sessionID, httpAuthProxySetting) reviewStatus, err := authproxy.TokenReview(sessionID, httpAuthProxySetting)
if err != nil {
return err
}
u2, err := authproxy.UserFromReviewStatus(reviewStatus)
if err != nil {
return err
}
user.GroupIDs = u2.GroupIDs
return nil
} }
// OnBoardUser delegates to dao pkg to insert/update data in DB. // OnBoardUser delegates to dao pkg to insert/update data in DB.

View File

@ -325,16 +325,16 @@ func (ap *authProxyReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
log.Errorf("fail to get auth proxy settings, %v", err) log.Errorf("fail to get auth proxy settings, %v", err)
return false return false
} }
tokenReviewResponse, err := authproxy.TokenReview(proxyPwd, httpAuthProxyConf) tokenReviewStatus, err := authproxy.TokenReview(proxyPwd, httpAuthProxyConf)
if err != nil { if err != nil {
log.Errorf("fail to review token, %v", err) log.Errorf("fail to review token, %v", err)
return false return false
} }
if rawUserName != tokenReviewStatus.User.Username {
if !tokenReviewResponse.Status.Authenticated { log.Errorf("user name doesn't match with token: %s", rawUserName)
log.Errorf("fail to auth user: %s", rawUserName)
return false return false
} }
user, err := dao.GetUser(models.User{ user, err := dao.GetUser(models.User{
Username: rawUserName, Username: rawUserName,
}) })
@ -346,11 +346,12 @@ func (ap *authProxyReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
log.Errorf("User: %s has not been on boarded yet.", rawUserName) log.Errorf("User: %s has not been on boarded yet.", rawUserName)
return false return false
} }
if rawUserName != tokenReviewResponse.Status.User.Username { u2, err := authproxy.UserFromReviewStatus(tokenReviewStatus)
log.Errorf("user name doesn't match with token: %s", rawUserName) if err != nil {
log.Errorf("Failed to get user information from token review status, error: %v", err)
return false return false
} }
user.GroupIDs = u2.GroupIDs
pm := config.GlobalProjectMgr pm := config.GlobalProjectMgr
log.Debug("creating local database security context for auth proxy...") log.Debug("creating local database security context for auth proxy...")
securCtx := local.NewSecurityContext(user, pm) securCtx := local.NewSecurityContext(user, pm)

View File

@ -2,6 +2,9 @@ package authproxy
import ( import (
"encoding/json" "encoding/json"
"fmt"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/dao/group"
"github.com/goharbor/harbor/src/common/models" "github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/utils/log" "github.com/goharbor/harbor/src/common/utils/log"
k8s_api_v1beta1 "k8s.io/api/authentication/v1beta1" k8s_api_v1beta1 "k8s.io/api/authentication/v1beta1"
@ -13,8 +16,9 @@ import (
) )
// TokenReview ... // TokenReview ...
func TokenReview(sessionID string, authProxyConfig *models.HTTPAuthProxy) (*k8s_api_v1beta1.TokenReview, error) { func TokenReview(rawToken string, authProxyConfig *models.HTTPAuthProxy) (k8s_api_v1beta1.TokenReviewStatus, error) {
emptyStatus := k8s_api_v1beta1.TokenReviewStatus{}
// Init auth client with the auth proxy endpoint. // Init auth client with the auth proxy endpoint.
authClientCfg := &rest.Config{ authClientCfg := &rest.Config{
Host: authProxyConfig.TokenReviewEndpoint, Host: authProxyConfig.TokenReviewEndpoint,
@ -22,14 +26,14 @@ func TokenReview(sessionID string, authProxyConfig *models.HTTPAuthProxy) (*k8s_
GroupVersion: &schema.GroupVersion{}, GroupVersion: &schema.GroupVersion{},
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}, NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
}, },
BearerToken: sessionID, BearerToken: rawToken,
TLSClientConfig: rest.TLSClientConfig{ TLSClientConfig: rest.TLSClientConfig{
Insecure: !authProxyConfig.VerifyCert, Insecure: !authProxyConfig.VerifyCert,
}, },
} }
authClient, err := rest.RESTClientFor(authClientCfg) authClient, err := rest.RESTClientFor(authClientCfg)
if err != nil { if err != nil {
return nil, err return emptyStatus, err
} }
// Do auth with the token. // Do auth with the token.
@ -39,27 +43,49 @@ func TokenReview(sessionID string, authProxyConfig *models.HTTPAuthProxy) (*k8s_
APIVersion: "authentication.k8s.io/v1beta1", APIVersion: "authentication.k8s.io/v1beta1",
}, },
Spec: k8s_api_v1beta1.TokenReviewSpec{ Spec: k8s_api_v1beta1.TokenReviewSpec{
Token: sessionID, Token: rawToken,
}, },
} }
res := authClient.Post().Body(tokenReviewRequest).Do() res := authClient.Post().Body(tokenReviewRequest).Do()
err = res.Error() err = res.Error()
if err != nil { if err != nil {
log.Errorf("fail to POST auth request, %v", err) log.Errorf("fail to POST auth request, %v", err)
return nil, err return emptyStatus, err
} }
resRaw, err := res.Raw() resRaw, err := res.Raw()
if err != nil { if err != nil {
log.Errorf("fail to get raw data of token review, %v", err) log.Errorf("fail to get raw data of token review, %v", err)
return nil, err return emptyStatus, err
} }
// Parse the auth response, check the user name and authenticated status. // Parse the auth response, check the user name and authenticated status.
tokenReviewResponse := &k8s_api_v1beta1.TokenReview{} tokenReviewResponse := &k8s_api_v1beta1.TokenReview{}
err = json.Unmarshal(resRaw, &tokenReviewResponse) err = json.Unmarshal(resRaw, tokenReviewResponse)
if err != nil { if err != nil {
log.Errorf("fail to decode token review, %v", err) log.Errorf("fail to decode token review, %v", err)
return nil, err return emptyStatus, err
} }
return tokenReviewResponse, nil return tokenReviewResponse.Status, nil
}
// UserFromReviewStatus transform a review status to a user model.
// Group entries will be populated if needed.
func UserFromReviewStatus(status k8s_api_v1beta1.TokenReviewStatus) (*models.User, error) {
if !status.Authenticated {
return nil, fmt.Errorf("failed to authenticate the token, error in status: %s", status.Error)
}
user := &models.User{
Username: status.User.Username,
}
if len(status.User.Groups) > 0 {
userGroups := models.UserGroupsFromName(status.User.Groups, common.HTTPGroupType)
groupIDList, err := group.PopulateGroup(userGroups)
if err != nil {
return nil, err
}
log.Debugf("current user's group ID list is %+v", groupIDList)
user.GroupIDs = groupIDList
}
return user, nil
} }

View File

@ -0,0 +1,87 @@
package authproxy
import (
"github.com/goharbor/harbor/src/common/dao"
"github.com/goharbor/harbor/src/common/dao/group"
"github.com/stretchr/testify/assert"
"k8s.io/api/authentication/v1beta1"
"os"
"testing"
)
func TestMain(m *testing.M) {
dao.PrepareTestForPostgresSQL()
result := m.Run()
if result != 0 {
os.Exit(result)
}
}
func TestUserFromReviewStatus(t *testing.T) {
type result struct {
hasErr bool
username string
groupLen int
}
cases := []struct {
input v1beta1.TokenReviewStatus
expect result
}{
{
input: v1beta1.TokenReviewStatus{
Authenticated: false,
Error: "connection error",
},
expect: result{
hasErr: true,
},
},
{
input: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
Username: "jack",
UID: "u-1",
},
},
expect: result{
hasErr: false,
username: "jack",
groupLen: 0,
},
},
{
input: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
Username: "daniel",
Groups: []string{"group1", "group2"},
},
Error: "",
},
expect: result{
hasErr: false,
username: "daniel",
groupLen: 2,
},
},
}
for _, c := range cases {
u, err := UserFromReviewStatus(c.input)
if c.expect.hasErr == true {
assert.NotNil(t, err)
} else {
assert.Nil(t, err)
assert.Equal(t, c.expect.username, u.Username)
assert.Equal(t, c.expect.groupLen, len(u.GroupIDs))
}
if u != nil {
for _, gid := range u.GroupIDs {
t.Logf("Deleting group %d", gid)
if err := group.DeleteUserGroup(gid); err != nil {
panic(err)
}
}
}
}
}

View File

@ -14,6 +14,7 @@
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER, LOCALE_ID, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { NgModule, APP_INITIALIZER, LOCALE_ID, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { InterceptHttpService } from './intercept-http.service';
import { BaseModule } from './base/base.module'; import { BaseModule } from './base/base.module';
import { HarborRoutingModule } from './harbor-routing.module'; import { HarborRoutingModule } from './harbor-routing.module';
@ -43,6 +44,8 @@ import { InterrogationServicesComponent } from "./interrogation-services/interro
import { LabelsComponent } from './labels/labels.component'; import { LabelsComponent } from './labels/labels.component';
import { ProjectQuotasComponent } from './project-quotas/project-quotas.component'; import { ProjectQuotasComponent } from './project-quotas/project-quotas.component';
import { HarborLibraryModule } from "../lib/harbor-library.module"; import { HarborLibraryModule } from "../lib/harbor-library.module";
import { HTTP_INTERCEPTORS } from '@angular/common/http';
registerLocaleData(zh, 'zh-cn'); registerLocaleData(zh, 'zh-cn');
registerLocaleData(es, 'es-es'); registerLocaleData(es, 'es-es');
@ -95,7 +98,9 @@ export function getCurrentLanguage(translateService: TranslateService) {
deps: [ AppConfigService, SkinableConfig], deps: [ AppConfigService, SkinableConfig],
multi: true multi: true
}, },
{provide: LOCALE_ID, useValue: "en-US"} {provide: LOCALE_ID, useValue: "en-US"},
{ provide: HTTP_INTERCEPTORS, useClass: InterceptHttpService, multi: true }
], ],
schemas: [ schemas: [
CUSTOM_ELEMENTS_SCHEMA CUSTOM_ELEMENTS_SCHEMA

View File

@ -0,0 +1,58 @@
import { TestBed, inject } from '@angular/core/testing';
import { InterceptHttpService } from './intercept-http.service';
import { CookieService } from 'ngx-cookie';
import { HttpRequest, HttpResponse } from '@angular/common/http';
import { of, throwError } from 'rxjs';
describe('InterceptHttpService', () => {
let cookie = "fdsa|ds";
const mockCookieService = {
get: function () {
return cookie;
},
set: function (cookieStr: string) {
cookie = cookieStr;
}
};
const mockRequest = new HttpRequest('PUT', "", {
headers: new Map()
});
const mockHandle = {
handle: (request) => {
if (request.headers.has('X-Xsrftoken')) {
return of(new HttpResponse({status: 200}));
} else {
return throwError(new HttpResponse( {
status: 403
}));
}
}
};
beforeEach(() => TestBed.configureTestingModule({}));
beforeEach(() => {
TestBed.configureTestingModule({
imports: [],
providers: [
InterceptHttpService,
{ provide: CookieService, useValue: mockCookieService }
]
});
});
it('should be initialized', inject([InterceptHttpService], (service: InterceptHttpService) => {
expect(service).toBeTruthy();
}));
it('should be get right token and send right request when the cookie not exists', inject([InterceptHttpService],
(service: InterceptHttpService) => {
mockCookieService.set("fdsa|ds");
service.intercept(mockRequest, mockHandle).subscribe(res => {
if (res.status === 403) {
expect(btoa(mockRequest.headers.get("X-Xsrftoken"))).toEqual(cookie.split("|")[0]);
} else {
expect(res.status).toEqual(200);
}
});
}));
});

View File

@ -0,0 +1,28 @@
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';
import { CookieService } from 'ngx-cookie';
@Injectable({
providedIn: 'root'
})
export class InterceptHttpService implements HttpInterceptor {
constructor(private cookie: CookieService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<any> {
return next.handle(request).pipe(catchError(error => {
if (error.status === 403) {
let Xsrftoken = this.cookie.get("_xsrf") ? atob(this.cookie.get("_xsrf").split("|")[0]) : null;
if (Xsrftoken && !request.headers.has('X-Xsrftoken')) {
request = request.clone({ headers: request.headers.set('X-Xsrftoken', Xsrftoken) });
return next.handle(request);
}
}
return throwError(error);
}));
}
}

View File

@ -8,7 +8,7 @@
<div class="clr-control-container" [class.clr-error]="!isNameValid"> <div class="clr-control-container" [class.clr-error]="!isNameValid">
<div class="clr-input-wrapper"> <div class="clr-input-wrapper">
<input type="text" id="create_project_name" [(ngModel)]="project.name" name="create_project_name" class="clr-input input-width" <input type="text" id="create_project_name" [(ngModel)]="project.name" name="create_project_name" class="clr-input input-width"
required pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$" minlength="2" #projectName="ngModel" autocomplete="off" required pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$" #projectName="ngModel" autocomplete="off"
(keyup)='handleValidation()'> (keyup)='handleValidation()'>
<clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon> <clr-icon class="clr-validate-icon" shape="exclamation-circle"></clr-icon>
<span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span> <span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span>

View File

@ -214,9 +214,8 @@
"PUBLIC_PROJECTS": "Public Projects", "PUBLIC_PROJECTS": "Public Projects",
"PROJECT": "Project", "PROJECT": "Project",
"NEW_PROJECT": "New Project", "NEW_PROJECT": "New Project",
"NAME_TOOLTIP": "Project name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.", "NAME_TOOLTIP": "Project name should be 1~255 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
"NAME_IS_REQUIRED": "Project name is required.", "NAME_IS_REQUIRED": "Project name is required.",
"NAME_MINIMUM_LENGTH": "Project name is too short, it should be greater than 2 characters.",
"NAME_ALREADY_EXISTS": "Project name already exists.", "NAME_ALREADY_EXISTS": "Project name already exists.",
"NAME_IS_ILLEGAL": "Project name is invalid.", "NAME_IS_ILLEGAL": "Project name is invalid.",
"UNKNOWN_ERROR": "An unknown error occurred while creating the project.", "UNKNOWN_ERROR": "An unknown error occurred while creating the project.",

View File

@ -214,10 +214,9 @@
"PUBLIC_PROJECTS": "Public Projects", "PUBLIC_PROJECTS": "Public Projects",
"PROJECT": "Proyecto", "PROJECT": "Proyecto",
"NEW_PROJECT": "Nuevo proyecto", "NEW_PROJECT": "Nuevo proyecto",
"NAME_TOOLTIP": "Project name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.", "NAME_TOOLTIP": "Project name should be 1~255 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
"DESTINATION_NAME_TOOLTIP": "Destination name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.", "DESTINATION_NAME_TOOLTIP": "Destination name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
"NAME_IS_REQUIRED": "El nombre del proyecto es obligatorio.", "NAME_IS_REQUIRED": "El nombre del proyecto es obligatorio.",
"NAME_MINIMUM_LENGTH": "El nombre del proyecto es demasiado corto, debe ser mayor de 2 caracteres.",
"NAME_ALREADY_EXISTS": "Ya existe un proyecto con ese nombre.", "NAME_ALREADY_EXISTS": "Ya existe un proyecto con ese nombre.",
"NAME_IS_ILLEGAL": "El nombre del proyecto no es valido.", "NAME_IS_ILLEGAL": "El nombre del proyecto no es valido.",
"UNKNOWN_ERROR": "Ha ocurrido un error al crear el proyecto.", "UNKNOWN_ERROR": "Ha ocurrido un error al crear el proyecto.",

View File

@ -208,9 +208,8 @@
"PUBLIC_PROJECTS": "Projets Publics", "PUBLIC_PROJECTS": "Projets Publics",
"PROJECT": "Projet", "PROJECT": "Projet",
"NEW_PROJECT": "Nouveau Projet", "NEW_PROJECT": "Nouveau Projet",
"NAME_TOOLTIP": "Le nom du projet doit comporter au moins 2 caractères avec des minuscules, des chiffres et. _- et doit commencer par des caractères ou des chiffres.", "NAME_TOOLTIP": "Le nom du projet doit comporter 1~255 caractères avec des minuscules, des chiffres et. _- et doit commencer par des caractères ou des chiffres.",
"NAME_IS_REQUIRED": "Le nom du projet est obligatoire.", "NAME_IS_REQUIRED": "Le nom du projet est obligatoire.",
"NAME_MINIMUM_LENGTH": "Le nom du projet est trop court, il doit être supérieur à 2 caractères.",
"NAME_ALREADY_EXISTS": "Le nom du projet existe déjà.", "NAME_ALREADY_EXISTS": "Le nom du projet existe déjà.",
"NAME_IS_ILLEGAL": "Le nom du projet est invalide.", "NAME_IS_ILLEGAL": "Le nom du projet est invalide.",
"UNKNOWN_ERROR": "Une erreur inconnue s'est produite lors de la création du projet.", "UNKNOWN_ERROR": "Une erreur inconnue s'est produite lors de la création du projet.",

View File

@ -212,9 +212,8 @@
"PUBLIC_PROJECTS": "Projetos Públicos", "PUBLIC_PROJECTS": "Projetos Públicos",
"PROJECT": "Projeto", "PROJECT": "Projeto",
"NEW_PROJECT": "Novo Projeto", "NEW_PROJECT": "Novo Projeto",
"NAME_TOOLTIP": "Nome do projeto deve conter ao menos 2 caracteres sendo minusculos, números e ._- e deve iniciar com letras ou números.", "NAME_TOOLTIP": "Nome do projeto deve conter 1~255 caracteres sendo minusculos, números e ._- e deve iniciar com letras ou números.",
"NAME_IS_REQUIRED": "Nome do projeto é obrigatório.", "NAME_IS_REQUIRED": "Nome do projeto é obrigatório.",
"NAME_MINIMUM_LENGTH": "Nome do projeto é muito curto, deve conter ao menos 2 caracteres.",
"NAME_ALREADY_EXISTS": "Nome do projeto já existe.", "NAME_ALREADY_EXISTS": "Nome do projeto já existe.",
"NAME_IS_ILLEGAL": "Nome do projeto é inválido.", "NAME_IS_ILLEGAL": "Nome do projeto é inválido.",
"UNKNOWN_ERROR": "Um erro desconhecido ocorreu ao criar o projeto.", "UNKNOWN_ERROR": "Um erro desconhecido ocorreu ao criar o projeto.",

View File

@ -214,9 +214,8 @@
"PUBLIC_PROJECTS": "Genel Projeler", "PUBLIC_PROJECTS": "Genel Projeler",
"PROJECT": "Proje", "PROJECT": "Proje",
"NEW_PROJECT": "Yeni Proje", "NEW_PROJECT": "Yeni Proje",
"NAME_TOOLTIP": "Proje adı, en az 2 karakter uzunluğunda, küçük harf, rakam ve ._- ile yazılmalı ve karakter veya rakamlarla başlamalıdır.", "NAME_TOOLTIP": "Proje adı, en az 1~255 karakter uzunluğunda, küçük harf, rakam ve ._- ile yazılmalı ve karakter veya rakamlarla başlamalıdır.",
"NAME_IS_REQUIRED": "Proje adı gerekli.", "NAME_IS_REQUIRED": "Proje adı gerekli.",
"NAME_MINIMUM_LENGTH": "Proje adı çok kısa, 2 karakterden büyük olmalıdır.",
"NAME_ALREADY_EXISTS": "Proje adı zaten var.", "NAME_ALREADY_EXISTS": "Proje adı zaten var.",
"NAME_IS_ILLEGAL": "Proje adı geçersiz.", "NAME_IS_ILLEGAL": "Proje adı geçersiz.",
"UNKNOWN_ERROR": "Proje oluşturulurken bilinmeyen bir hata oluştu.", "UNKNOWN_ERROR": "Proje oluşturulurken bilinmeyen bir hata oluştu.",

View File

@ -213,9 +213,8 @@
"PUBLIC_PROJECTS": "公开项目", "PUBLIC_PROJECTS": "公开项目",
"PROJECT": "项目", "PROJECT": "项目",
"NEW_PROJECT": "新建项目", "NEW_PROJECT": "新建项目",
"NAME_TOOLTIP": "项目名称由小写字符、数字和._-组成且至少2个字符并以字符或者数字开头。", "NAME_TOOLTIP": "项目名称由小写字符、数字和._-组成且至少1个字符并以字符或者数字开头。",
"NAME_IS_REQUIRED": "项目名称为必填项。", "NAME_IS_REQUIRED": "项目名称为必填项。",
"NAME_MINIMUM_LENGTH": "项目名称长度过短至少多于2个字符。",
"NAME_ALREADY_EXISTS": "项目名称已存在。", "NAME_ALREADY_EXISTS": "项目名称已存在。",
"NAME_IS_ILLEGAL": "项目名称非法。", "NAME_IS_ILLEGAL": "项目名称非法。",
"UNKNOWN_ERROR": "创建项目时发生未知错误。", "UNKNOWN_ERROR": "创建项目时发生未知错误。",

View File

@ -93,6 +93,14 @@ export Harbor_Assets_Version=$Harbor_Assets_Version
export Harbor_Package_Version=$Harbor_Package_Version export Harbor_Package_Version=$Harbor_Package_Version
export NPM_REGISTRY=$NPM_REGISTRY export NPM_REGISTRY=$NPM_REGISTRY
# release branch must have their own base image with branch name, master and others will use the dev as base.
if [[ $DRONE_BRANCH == "release-"* ]]; then
Harbor_Build_Base_Tag=$DRONE_BRANCH
else
Harbor_Build_Base_Tag=dev
fi
export Harbor_Build_Base_Tag=$Harbor_Build_Base_Tag
echo "--------------------------------------------------" echo "--------------------------------------------------"
echo "Harbor Package version: $Harbor_Package_Version" echo "Harbor Package version: $Harbor_Package_Version"
echo "Harbor Assets version: $Harbor_Assets_Version" echo "Harbor Assets version: $Harbor_Assets_Version"

View File

@ -26,9 +26,8 @@ Go Into Project
\ Retry Wait Element ${search_input} \ Retry Wait Element ${search_input}
\ Retry Clear Element Text ${search_input} \ Retry Clear Element Text ${search_input}
\ Input Text ${search_input} ${project} \ Input Text ${search_input} ${project}
\ Retry Wait Until Page Contains ${project} \ ${out} Run Keyword If ${has_image}==${false} Retry Double Keywords When Error Retry Element Click xpath=//*[@id='project-results']//clr-dg-cell[contains(.,'${project}')]/a Wait Until Element Is Visible And Enabled xpath=//clr-dg-placeholder[contains(.,\"We couldn\'t find any repositories!\")] DoAssert=${false}
\ ${out} Run Keyword If ${has_image}==${false} Retry Double Keywords When Error Retry Element Click xpath=//*[@id='project-results']//clr-dg-cell[contains(.,'${project}')]/a Wait Until Element Is Visible And Enabled xpath=//clr-dg-placeholder[contains(.,\"We couldn\'t find any repositories!\")] \ ... ELSE Retry Double Keywords When Error Retry Element Click xpath=//*[@id='project-results']//clr-dg-cell[contains(.,'${project}')]/a Wait Until Element Is Visible And Enabled xpath=//project-detail//hbr-repository-gridview//clr-dg-cell[contains(.,'${project}/')] DoAssert=${false}
\ ... ELSE Retry Double Keywords When Error Retry Element Click xpath=//*[@id='project-results']//clr-dg-cell[contains(.,'${project}')]/a Wait Until Element Is Visible And Enabled xpath=//project-detail//hbr-repository-gridview//clr-dg-cell[contains(.,'${project}/')]
\ Log To Console ${out} \ Log To Console ${out}
\ Run Keyword If ${out} == 'PASS' Exit For Loop \ Run Keyword If ${out} == 'PASS' Exit For Loop
\ Sleep 1 \ Sleep 1

View File

@ -55,7 +55,7 @@ Package Harbor Offline
[Arguments] ${with_notary}=true ${with_clair}=true ${with_migrator}=true ${with_chartmuseum}=true [Arguments] ${with_notary}=true ${with_clair}=true ${with_migrator}=true ${with_chartmuseum}=true
Log To Console \nStart Docker Daemon Log To Console \nStart Docker Daemon
Start Docker Daemon Locally Start Docker Daemon Locally
Log To Console \n\nmake package_offline NPM_REGISTRY=%{NPM_REGISTRY} VERSIONTAG=%{Harbor_Assets_Version} PKGVERSIONTAG=%{Harbor_Package_Version} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} MIGRATORFLAG=${with_migrator} CHARTFLAG=${with_chartmuseum} HTTPPROXY= Log To Console \n\nmake package_offline BASEIMAGETAG=%{Harbor_Build_Base_Tag} NPM_REGISTRY=%{NPM_REGISTRY} VERSIONTAG=%{Harbor_Assets_Version} PKGVERSIONTAG=%{Harbor_Package_Version} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} MIGRATORFLAG=${with_migrator} CHARTFLAG=${with_chartmuseum} HTTPPROXY=
${rc} ${output}= Run And Return Rc And Output make package_offline NPM_REGISTRY=%{NPM_REGISTRY} VERSIONTAG=%{Harbor_Assets_Version} PKGVERSIONTAG=%{Harbor_Package_Version} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} MIGRATORFLAG=${with_migrator} CHARTFLAG=${with_chartmuseum} HTTPPROXY= ${rc} ${output}= Run And Return Rc And Output make package_offline NPM_REGISTRY=%{NPM_REGISTRY} VERSIONTAG=%{Harbor_Assets_Version} PKGVERSIONTAG=%{Harbor_Package_Version} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} MIGRATORFLAG=${with_migrator} CHARTFLAG=${with_chartmuseum} HTTPPROXY=
Log To Console ${rc} Log To Console ${rc}
Log To Console ${output} Log To Console ${output}

View File

@ -246,7 +246,7 @@ Retry Keyword When Return Value Mismatch
Should Be Equal As Strings ${status} 'PASS' Should Be Equal As Strings ${status} 'PASS'
Retry Double Keywords When Error Retry Double Keywords When Error
[Arguments] ${keyword1} ${element1} ${keyword2} ${element2} [Arguments] ${keyword1} ${element1} ${keyword2} ${element2} ${DoAssert}=${true}
:For ${n} IN RANGE 1 5 :For ${n} IN RANGE 1 5
\ Log To Console Trying ${keyword1} and ${keyword2} ${n} times ... \ Log To Console Trying ${keyword1} and ${keyword2} ${n} times ...
\ ${out1} Run Keyword And Ignore Error ${keyword1} ${element1} \ ${out1} Run Keyword And Ignore Error ${keyword1} ${element1}
@ -257,8 +257,8 @@ Retry Double Keywords When Error
\ Log To Console Return value is ${out1[0]} ${out2[0]} \ Log To Console Return value is ${out1[0]} ${out2[0]}
\ Exit For Loop If '${out2[0]}'=='PASS' \ Exit For Loop If '${out2[0]}'=='PASS'
\ Sleep 1 \ Sleep 1
Return From Keyword If ${DoAssert} == ${false} '${out2[0]}'
Should Be Equal As Strings '${out2[0]}' 'PASS' Should Be Equal As Strings '${out2[0]}' 'PASS'
[Return] 'PASS'
Run Curl And Return Json Run Curl And Return Json
[Arguments] ${curl_cmd} [Arguments] ${curl_cmd}

View File

@ -499,7 +499,7 @@ Test Case - Project Storage Quotas Dispaly And Control
${storage_quota_unit}= Set Variable MB ${storage_quota_unit}= Set Variable MB
${image_a}= Set Variable redis ${image_a}= Set Variable redis
${image_b}= Set Variable logstash ${image_b}= Set Variable logstash
${image_a_size}= Set Variable 34.16MB ${image_a_size}= Set Variable 34.15MB
${image_b_size}= Set Variable 321.03MB ${image_b_size}= Set Variable 321.03MB
${image_a_ver}= Set Variable 5.0 ${image_a_ver}= Set Variable 5.0
${image_b_ver}= Set Variable 6.8.3 ${image_b_ver}= Set Variable 6.8.3
@ -508,11 +508,16 @@ Test Case - Project Storage Quotas Dispaly And Control
Push Image With Tag ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} ${image_b} tag=${image_b_ver} tag1=${image_b_ver} Push Image With Tag ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} ${image_b} tag=${image_b_ver} tag1=${image_b_ver}
${storage_quota_ret}= Get Project Storage Quota Text From Project Quotas List project${d} ${storage_quota_ret}= Get Project Storage Quota Text From Project Quotas List project${d}
Should Be Equal As Strings ${storage_quota_ret} ${image_b_size} of ${storage_quota}${storage_quota_unit} Should Be Equal As Strings ${storage_quota_ret} ${image_b_size} of ${storage_quota}${storage_quota_unit}
Cannot Push image ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} ${image_a}:${image_a_ver} err_msg=Quota exceeded when processing the request of adding 25.9 MiB of storage resource, which when updated to current usage of 329.3 MiB will exceed the configured upper limit of 330.0 MiB Cannot Push image ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} ${image_a}:${image_a_ver} err_msg=Quota exceeded when processing the request of adding 25.8 MiB of storage resource, which when updated to current usage of 329.3 MiB will exceed the configured upper limit of 330.0 MiB
Go Into Project project${d} Go Into Project project${d}
Delete Repo project${d}/${image_b} Delete Repo project${d}/${image_b}
Push Image With Tag ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} ${image_a} tag=${image_a_ver} tag1=${image_a_ver} Push Image With Tag ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} ${image_a} tag=${image_a_ver} tag1=${image_a_ver}
${storage_quota_ret}= Get Project Storage Quota Text From Project Quotas List project${d} ${storage_quota_ret}= Get Project Storage Quota Text From Project Quotas List project${d}
${storage_quota_ret_str_left} Fetch From Left ${storage_quota_ret} 25.
Log ${storage_quota_ret_str_left}
${storage_quota_ret_str_right} Fetch From Left ${storage_quota_ret} 25.
Log ${storage_quota_ret_str_right}
Log ${storage_quota_ret_str_left}${storage_quota_ret_str_right}
Should Be Equal As Strings ${storage_quota_ret} ${image_a_size} of ${storage_quota}${storage_quota_unit} Should Be Equal As Strings ${storage_quota_ret} ${image_a_size} of ${storage_quota}${storage_quota_unit}
Close Browser Close Browser

View File

@ -24,5 +24,5 @@ sudo curl -o /home/travis/gopath/src/github.com/goharbor/harbor/tests/apitests/p
sudo apt-get update && sudo apt-get install -y --no-install-recommends python-dev openjdk-7-jdk libssl-dev && sudo apt-get autoremove -y && sudo rm -rf /var/lib/apt/lists/* sudo apt-get update && sudo apt-get install -y --no-install-recommends python-dev openjdk-7-jdk libssl-dev && sudo apt-get autoremove -y && sudo rm -rf /var/lib/apt/lists/*
sudo wget https://bootstrap.pypa.io/get-pip.py && sudo python ./get-pip.py && sudo pip install --ignore-installed urllib3 chardet requests && sudo pip install robotframework==3.0.4 robotframework-httplibrary requests dbbot robotframework-pabot --upgrade sudo wget https://bootstrap.pypa.io/get-pip.py && sudo python ./get-pip.py && sudo pip install --ignore-installed urllib3 chardet requests && sudo pip install robotframework==3.0.4 robotframework-httplibrary requests dbbot robotframework-pabot --upgrade
sudo make swagger_client sudo make swagger_client
sudo make install GOBUILDIMAGE=golang:1.12.12 COMPILETAG=compile_golangimage CLARITYIMAGE=goharbor/harbor-clarity-ui-builder:1.6.0 NOTARYFLAG=true CLAIRFLAG=true CHARTFLAG=true sudo make install GOBUILDIMAGE=golang:1.13.4 COMPILETAG=compile_golangimage CLARITYIMAGE=goharbor/harbor-clarity-ui-builder:1.6.0 NOTARYFLAG=true CLAIRFLAG=true CHARTFLAG=true
sleep 10 sleep 10

View File

@ -2,5 +2,5 @@
set -e set -e
sudo make package_online VERSIONTAG=dev-travis PKGVERSIONTAG=dev-travis UIVERSIONTAG=dev-travis GOBUILDIMAGE=golang:1.12.12 COMPILETAG=compile_golangimage NOTARYFLAG=true CLAIRFLAG=true MIGRATORFLAG=false CHARTFLAG=true HTTPPROXY= sudo make package_online VERSIONTAG=dev-travis PKGVERSIONTAG=dev-travis UIVERSIONTAG=dev-travis GOBUILDIMAGE=golang:1.13.4 COMPILETAG=compile_golangimage NOTARYFLAG=true CLAIRFLAG=true MIGRATORFLAG=false CHARTFLAG=true HTTPPROXY=
sudo make package_offline VERSIONTAG=dev-travis PKGVERSIONTAG=dev-travis UIVERSIONTAG=dev-travis GOBUILDIMAGE=golang:1.12.12 COMPILETAG=compile_golangimage NOTARYFLAG=true CLAIRFLAG=true MIGRATORFLAG=false CHARTFLAG=true HTTPPROXY= sudo make package_offline VERSIONTAG=dev-travis PKGVERSIONTAG=dev-travis UIVERSIONTAG=dev-travis GOBUILDIMAGE=golang:1.13.4 COMPILETAG=compile_golangimage NOTARYFLAG=true CLAIRFLAG=true MIGRATORFLAG=false CHARTFLAG=true HTTPPROXY=