diff --git a/src/portal/src/app/vulnerability-page/vulnerability-page.component.ts b/src/portal/src/app/vulnerability-page/vulnerability-page.component.ts
index 618ed513f..a822469eb 100644
--- a/src/portal/src/app/vulnerability-page/vulnerability-page.component.ts
+++ b/src/portal/src/app/vulnerability-page/vulnerability-page.component.ts
@@ -7,11 +7,12 @@ import { AppConfigService } from "../app-config.service";
styleUrls: ["./vulnerability-page.component.scss"]
})
export class VulnerabilityPageComponent implements OnInit {
+ inProgress: boolean = true;
constructor(private appConfigService: AppConfigService) {}
ngOnInit() {}
- public get withClair(): boolean {
- return this.appConfigService.getConfig().with_clair;
+ getStatus(status: boolean) {
+ this.inProgress = false;
}
}
diff --git a/src/portal/src/i18n/lang/en-us-lang.json b/src/portal/src/i18n/lang/en-us-lang.json
index b1816987d..a23815db7 100644
--- a/src/portal/src/i18n/lang/en-us-lang.json
+++ b/src/portal/src/i18n/lang/en-us-lang.json
@@ -55,13 +55,13 @@
"STOP_FAILURE": "Stop execution failed"
},
"TOOLTIP": {
- "NAME_FILTER": "Filter the name part of the resources. Leaving empty or '**' matches all; 'library/**' only matches the resources under 'library'. For more patterns please refer to the user guide.",
- "TAG_FILTER": "Filter the tag/version part of the resources. Leaving empty or '**' matches all; '1.0*' only matches the tags that starts with '1.0'. For more patterns please refer to the user guide.",
- "RESOURCE_FILTER": "Filter the type of the resources.",
- "PUSH_BASED": "Push the resources from the current Harbor to the remote registry.",
- "PULL_BASED": "Pull the resources from the remote registry to the current Harbor.",
- "DESTINATION_NAMESPACE": "Specify the destination namespaces. The resources will be put under the same namespace with the source if it is empty.",
- "OVERRIDE": "Specify whether override the resources if the same name resources found on the destination registry.",
+ "NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
+ "TAG_FILTER": "Filter the tag/version part of the resources. Leave empty or use '**' to match all. '1.0*' only matches the tags that starts with '1.0'. For more patterns, please refer to the user guide.",
+ "RESOURCE_FILTER": "Filter the type of resources.",
+ "PUSH_BASED": "Push the resources from the local Harbor to the remote registry.",
+ "PULL_BASED": "Pull the resources from the remote registry to the local Harbor.",
+ "DESTINATION_NAMESPACE": "Specify the destination namespace. If empty, the resources will be put under the same namespace as the source.",
+ "OVERRIDE": "Specify whether to replace the resources at the destination if a resource with the same name exists.",
"EMAIL": "Email should be a valid email address like name@example.com.",
"USER_NAME": "Cannot contain special characters and maximum length should be 255 characters.",
"FULL_NAME": "Maximum length should be 20 characters.",
@@ -360,7 +360,8 @@
"REPLICATION": {
"TOTAL": "Total",
"OVERRIDE": "Override",
- "OVERRIDE_INFO": "Override the destination resources if name conflicts",
+ "ENABLED_RULE": "Enable rule",
+ "OVERRIDE_INFO": "Replace the destination resources if name exists",
"OPERATION": "Operation",
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
diff --git a/src/portal/src/i18n/lang/es-es-lang.json b/src/portal/src/i18n/lang/es-es-lang.json
index d05dce0c5..b5cd35c91 100644
--- a/src/portal/src/i18n/lang/es-es-lang.json
+++ b/src/portal/src/i18n/lang/es-es-lang.json
@@ -55,13 +55,13 @@
"STOP_FAILURE": "Stop execution failed"
},
"TOOLTIP": {
- "NAME_FILTER": "Filter the name part of the resources. Leaving empty or '**' matches all; 'library/**' only matches the resources under 'library'. For more patterns please refer to the user guide.",
- "TAG_FILTER": "Filter the tag/version part of the resources. Leaving empty or '**' matches all; '1.0*' only matches the tags that starts with '1.0'. For more patterns please refer to the user guide.",
- "RESOURCE_FILTER": "Filter the type of the resources.",
- "PUSH_BASED": "Push the resources from the current Harbor to the remote registry.",
- "PULL_BASED": "Pull the resources from the remote registry to the current Harbor.",
- "DESTINATION_NAMESPACE": "Specify the destination namespaces. The resources will be put under the same namespace with the source if it is empty.",
- "OVERRIDE": "Specify whether override the resources if the same name resources found on the destination registry.",
+ "NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
+ "TAG_FILTER": "Filter the tag/version part of the resources. Leave empty or use '**' to match all. '1.0*' only matches the tags that starts with '1.0'. For more patterns, please refer to the user guide.",
+ "RESOURCE_FILTER": "Filter the type of resources.",
+ "PUSH_BASED": "Push the resources from the local Harbor to the remote registry.",
+ "PULL_BASED": "Pull the resources from the remote registry to the local Harbor.",
+ "DESTINATION_NAMESPACE": "Specify the destination namespace. If empty, the resources will be put under the same namespace as the source.",
+ "OVERRIDE": "Specify whether to replace the resources at the destination if a resource with the same name exists.",
"EMAIL": "El email debe ser una dirección válida como nombre@ejemplo.com.",
"USER_NAME": "Debe tener una longitud máxima de 255 caracteres y no puede contener caracteres especiales.",
"FULL_NAME": "La longitud máxima debería ser de 20 caracteres.",
@@ -359,7 +359,8 @@
"REPLICATION": {
"TOTAL": "Total",
"OVERRIDE": "Override",
- "OVERRIDE_INFO": "Override the destination resources if name conflicts",
+ "ENABLED_RULE": "Enable rule",
+ "OVERRIDE_INFO": "Replace the destination resources if name exists",
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirme Stop Executions",
diff --git a/src/portal/src/i18n/lang/fr-fr-lang.json b/src/portal/src/i18n/lang/fr-fr-lang.json
index 6aee1f37d..d07c87094 100644
--- a/src/portal/src/i18n/lang/fr-fr-lang.json
+++ b/src/portal/src/i18n/lang/fr-fr-lang.json
@@ -52,13 +52,13 @@
"STOP_FAILURE": "Stop execution failed"
},
"TOOLTIP": {
- "NAME_FILTER": "Filter the name part of the resources. Leaving empty or '**' matches all; 'library/**' only matches the resources under 'library'. For more patterns please refer to the user guide.",
- "TAG_FILTER": "Filter the tag/version part of the resources. Leaving empty or '**' matches all; '1.0*' only matches the tags that starts with '1.0'. For more patterns please refer to the user guide.",
- "RESOURCE_FILTER": "Filter the type of the resources.",
- "PUSH_BASED": "Push the resources from the current Harbor to the remote registry.",
- "PULL_BASED": "Pull the resources from the remote registry to the current Harbor.",
- "DESTINATION_NAMESPACE": "Specify the destination namespaces. The resources will be put under the same namespace with the source if it is empty.",
- "OVERRIDE": "Specify whether override the resources if the same name resources found on the destination registry.",
+ "NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
+ "TAG_FILTER": "Filter the tag/version part of the resources. Leave empty or use '**' to match all. '1.0*' only matches the tags that starts with '1.0'. For more patterns, please refer to the user guide.",
+ "RESOURCE_FILTER": "Filter the type of resources.",
+ "PUSH_BASED": "Push the resources from the local Harbor to the remote registry.",
+ "PULL_BASED": "Pull the resources from the remote registry to the local Harbor.",
+ "DESTINATION_NAMESPACE": "Specify the destination namespace. If empty, the resources will be put under the same namespace as the source.",
+ "OVERRIDE": "Specify whether to replace the resources at the destination if a resource with the same name exists.",
"EMAIL": "L'email doit être une adresse email valide comme name@example.com.",
"USER_NAME": "Ne peut pas contenir de caractères spéciaux et la longueur maximale doit être de 255 caractères.",
"FULL_NAME": "La longueur maximale doit être de 20 caractères.",
@@ -352,7 +352,8 @@
"REPLICATION": {
"TOTAL": "Total",
"OVERRIDE": "Override",
- "OVERRIDE_INFO": "Override the destination resources if name conflicts",
+ "ENABLED_RULE": "Enable rule",
+ "OVERRIDE_INFO": "Replace the destination resources if name exists",
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirmer arrêter les exécutions",
diff --git a/src/portal/src/i18n/lang/pt-br-lang.json b/src/portal/src/i18n/lang/pt-br-lang.json
index 32e9fa4f7..2d68cc5b3 100644
--- a/src/portal/src/i18n/lang/pt-br-lang.json
+++ b/src/portal/src/i18n/lang/pt-br-lang.json
@@ -55,13 +55,13 @@
"STOP_FAILURE": "Stop execution failed"
},
"TOOLTIP": {
- "NAME_FILTER": "Filter the name part of the resources. Leaving empty or '**' matches all; 'library/**' only matches the resources under 'library'. For more patterns please refer to the user guide.",
- "TAG_FILTER": "Filter the tag/version part of the resources. Leaving empty or '**' matches all; '1.0*' only matches the tags that starts with '1.0'. For more patterns please refer to the user guide.",
- "RESOURCE_FILTER": "Filter the type of the resources.",
- "PUSH_BASED": "Push the resources from the current Harbor to the remote registry.",
- "PULL_BASED": "Pull the resources from the remote registry to the current Harbor.",
- "DESTINATION_NAMESPACE": "Specify the destination namespaces. The resources will be put under the same namespace with the source if it is empty.",
- "OVERRIDE": "Specify whether override the resources if the same name resources found on the destination registry.",
+ "NAME_FILTER": "Filter the name of the resource. Leave empty or use '**' to match all. 'library/**' only matches resources under 'library'. For more patterns, please refer to the user guide.",
+ "TAG_FILTER": "Filter the tag/version part of the resources. Leave empty or use '**' to match all. '1.0*' only matches the tags that starts with '1.0'. For more patterns, please refer to the user guide.",
+ "RESOURCE_FILTER": "Filter the type of resources.",
+ "PUSH_BASED": "Push the resources from the local Harbor to the remote registry.",
+ "PULL_BASED": "Pull the resources from the remote registry to the local Harbor.",
+ "DESTINATION_NAMESPACE": "Specify the destination namespace. If empty, the resources will be put under the same namespace as the source.",
+ "OVERRIDE": "Specify whether to replace the resources at the destination if a resource with the same name exists.",
"EMAIL": "Email deve ser um endereço de email válido como nome@exemplo.com.",
"USER_NAME": "Não pode conter caracteres especiais e o tamanho máximo deve ser de 255 caracteres.",
"FULL_NAME": "Tamanho máximo deve ser de 20 caracteres.",
@@ -358,7 +358,8 @@
"REPLICATION": {
"TOTAL": "Total",
"OVERRIDE": "Override",
- "OVERRIDE_INFO": "Override the destination resources if name conflicts",
+ "ENABLED_RULE": "Enable rule",
+ "OVERRIDE_INFO": "Replace the destination resources if name exists",
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirme as execuções de parada",
diff --git a/src/portal/src/i18n/lang/zh-cn-lang.json b/src/portal/src/i18n/lang/zh-cn-lang.json
index 1fa548f58..bcfa8e805 100644
--- a/src/portal/src/i18n/lang/zh-cn-lang.json
+++ b/src/portal/src/i18n/lang/zh-cn-lang.json
@@ -58,10 +58,10 @@
"NAME_FILTER": "过滤资源的名字。不填或者“”匹配所有资源;“library/”只匹配“library”下的资源。更多的匹配模式请参考用户手册。",
"TAG_FILTER": "过滤资源的tag/version。不填或者“”匹配所有;“1.0*”只匹配以“1.0”开头的tag/version。",
"RESOURCE_FILTER": "过滤资源的类型。",
- "PUSH_BASED": "把资源由当前Harbor推送到远端仓库。",
- "PULL_BASED": "把资源由远端仓库拉取到当前Harbor。",
+ "PUSH_BASED": "把资源由本地Harbor推送到远端仓库。",
+ "PULL_BASED": "把资源由远端仓库拉取到本地Harbor。",
"DESTINATION_NAMESPACE": "指定目的端名称空间。如果不填,资源会被放到和源相同的名称空间下。",
- "OVERRIDE": "指定如果目的端仓库中已有同名的资源是否覆盖。",
+ "OVERRIDE": "如果存在具有相同名称的资源,请指定是否替换目标上的资源。",
"EMAIL": "请使用正确的邮箱地址,比如name@example.com。",
"USER_NAME": "不能包含特殊字符且长度不能超过255。",
"FULL_NAME": "长度不能超过20。",
@@ -359,7 +359,8 @@
"REPLICATION": {
"TOTAL": "总数",
"OVERRIDE": "覆盖",
- "OVERRIDE_INFO": "如果名称冲突则覆盖目标资源",
+ "ENABLED_RULE": "启用规则",
+ "OVERRIDE_INFO": "如果名称存在,则替换目标资源",
"CURRENT": "当前仓库",
"FILTER_PLACEHOLDER": "过滤任务",
"STOP_TITLE": "确认停止任务",
diff --git a/src/replication/adapter/harbor/chart_registry.go b/src/replication/adapter/harbor/chart_registry.go
index 1f15cd196..cfc66153f 100644
--- a/src/replication/adapter/harbor/chart_registry.go
+++ b/src/replication/adapter/harbor/chart_registry.go
@@ -130,13 +130,6 @@ func (a *adapter) ChartExist(name, version string) (bool, error) {
if httpErr, ok := err.(*common_http.Error); ok && httpErr.Code == http.StatusNotFound {
return false, nil
}
- // TODO this is a workaround for https://github.com/goharbor/harbor/issues/7171
- if httpErr, ok := err.(*common_http.Error); ok && httpErr.Code == http.StatusInternalServerError {
- if strings.Contains(httpErr.Message, "no chart name found") ||
- strings.Contains(httpErr.Message, "No chart version found") {
- return false, nil
- }
- }
return false, err
}
diff --git a/src/replication/adapter/huawei/image_registry.go b/src/replication/adapter/huawei/image_registry.go
index fd7e637b5..b3636163e 100644
--- a/src/replication/adapter/huawei/image_registry.go
+++ b/src/replication/adapter/huawei/image_registry.go
@@ -98,6 +98,9 @@ func (a *adapter) ManifestExist(repository, reference string) (exist bool, diges
defer resp.Body.Close()
code := resp.StatusCode
if code >= 300 || code < 200 {
+ if code == 404 {
+ return false, digest, nil
+ }
body, _ := ioutil.ReadAll(resp.Body)
return exist, digest, fmt.Errorf("[%d][%s]", code, string(body))
}
diff --git a/src/replication/operation/controller.go b/src/replication/operation/controller.go
index c56bf42f9..5b7756ad9 100644
--- a/src/replication/operation/controller.go
+++ b/src/replication/operation/controller.go
@@ -16,7 +16,6 @@ package operation
import (
"fmt"
- "strings"
"time"
"github.com/goharbor/harbor/src/common/job"
@@ -115,10 +114,6 @@ func (c *controller) StopReplication(executionID int64) error {
continue
}
if err = c.scheduler.Stop(task.JobID); err != nil {
- if isNotRunningJobError(err) {
- log.Warningf("got not running job error when trying stop the task %d(job ID: %s): %v, skip", task.ID, task.JobID, err)
- continue
- }
return err
}
log.Debugf("the stop request for task %d(job ID: %s) sent", task.ID, task.JobID)
@@ -139,16 +134,6 @@ func isTaskRunning(task *models.Task) bool {
return true
}
-// when trying to stop a job which isn't running in jobservice,
-// an error whose message contains "xxx is not a running job"
-// will be returned
-func isNotRunningJobError(err error) bool {
- if err == nil {
- return false
- }
- return strings.Contains(err.Error(), "is not a running job")
-}
-
func (c *controller) ListExecutions(query ...*models.ExecutionQuery) (int64, []*models.Execution, error) {
return c.executionMgr.List(query...)
}
diff --git a/src/replication/operation/controller_test.go b/src/replication/operation/controller_test.go
index 482022e46..b2698ba9a 100644
--- a/src/replication/operation/controller_test.go
+++ b/src/replication/operation/controller_test.go
@@ -15,7 +15,6 @@
package operation
import (
- "errors"
"io"
"testing"
@@ -329,27 +328,3 @@ func TestIsTaskRunning(t *testing.T) {
assert.Equal(t, c.isRunning, isTaskRunning(c.task))
}
}
-
-func TestIsNotRunningJobError(t *testing.T) {
- cases := []struct {
- err error
- isNotRunningJobError bool
- }{
- {
- err: nil,
- isNotRunningJobError: false,
- },
- {
- err: errors.New("not the error"),
- isNotRunningJobError: false,
- },
- {
- err: errors.New(`[ERROR] [handler.go:253]: Serve http request 'POST /api/v1/jobs/734a11140d939ef700889725' error: 500 {"code":10008,"message":"Stop job failed with error","details":"job '734a11140d939ef700889725' is not a running job"}`),
- isNotRunningJobError: true,
- },
- }
-
- for _, c := range cases {
- assert.Equal(t, c.isNotRunningJobError, isNotRunningJobError(c.err))
- }
-}
diff --git a/src/replication/operation/scheduler/scheduler_test.go b/src/replication/operation/scheduler/scheduler_test.go
index 94a25ca97..0ef398d6d 100644
--- a/src/replication/operation/scheduler/scheduler_test.go
+++ b/src/replication/operation/scheduler/scheduler_test.go
@@ -5,6 +5,7 @@ import (
"testing"
"github.com/goharbor/harbor/src/common/job/models"
+ "github.com/goharbor/harbor/src/jobservice/job"
"github.com/goharbor/harbor/src/replication/model"
)
@@ -24,6 +25,9 @@ func (client TestClient) GetJobLog(uuid string) ([]byte, error) {
func (client TestClient) PostAction(uuid, action string) error {
return nil
}
+func (client TestClient) GetExecutions(uuid string) ([]job.Stats, error) {
+ return nil, nil
+}
func TestPreprocess(t *testing.T) {
items, err := generateData()
diff --git a/src/replication/policy/scheduler/scheduler_test.go b/src/replication/policy/scheduler/scheduler_test.go
index 9b6c97a1e..27f6c9456 100644
--- a/src/replication/policy/scheduler/scheduler_test.go
+++ b/src/replication/policy/scheduler/scheduler_test.go
@@ -19,6 +19,7 @@ import (
"testing"
"github.com/goharbor/harbor/src/common/job/models"
+ "github.com/goharbor/harbor/src/jobservice/job"
"github.com/goharbor/harbor/src/replication/config"
"github.com/goharbor/harbor/src/replication/dao"
rep_models "github.com/goharbor/harbor/src/replication/dao/models"
@@ -51,6 +52,10 @@ func (f *fakedJobserviceClient) PostAction(uuid, action string) error {
f.stopped = true
return nil
}
+func (f *fakedJobserviceClient) GetExecutions(uuid string) ([]job.Stats, error) {
+ f.stopped = true
+ return nil, nil
+}
type fakedScheduleJobDAO struct {
idCounter int64
diff --git a/src/vendor/github.com/Sirupsen/logrus/.travis.yml b/src/vendor/github.com/Sirupsen/logrus/.travis.yml
deleted file mode 100644
index a23296a53..000000000
--- a/src/vendor/github.com/Sirupsen/logrus/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-language: go
-go:
- - 1.6.x
- - 1.7.x
- - 1.8.x
- - tip
-env:
- - GOMAXPROCS=4 GORACE=halt_on_error=1
-install:
- - go get github.com/stretchr/testify/assert
- - go get gopkg.in/gemnasium/logrus-airbrake-hook.v2
- - go get golang.org/x/sys/unix
- - go get golang.org/x/sys/windows
-script:
- - go test -race -v ./...
diff --git a/src/vendor/github.com/Sirupsen/logrus/CHANGELOG.md b/src/vendor/github.com/Sirupsen/logrus/CHANGELOG.md
deleted file mode 100644
index 1bd1deb29..000000000
--- a/src/vendor/github.com/Sirupsen/logrus/CHANGELOG.md
+++ /dev/null
@@ -1,123 +0,0 @@
-# 1.0.5
-
-* Fix hooks race (#707)
-* Fix panic deadlock (#695)
-
-# 1.0.4
-
-* Fix race when adding hooks (#612)
-* Fix terminal check in AppEngine (#635)
-
-# 1.0.3
-
-* Replace example files with testable examples
-
-# 1.0.2
-
-* bug: quote non-string values in text formatter (#583)
-* Make (*Logger) SetLevel a public method
-
-# 1.0.1
-
-* bug: fix escaping in text formatter (#575)
-
-# 1.0.0
-
-* Officially changed name to lower-case
-* bug: colors on Windows 10 (#541)
-* bug: fix race in accessing level (#512)
-
-# 0.11.5
-
-* feature: add writer and writerlevel to entry (#372)
-
-# 0.11.4
-
-* bug: fix undefined variable on solaris (#493)
-
-# 0.11.3
-
-* formatter: configure quoting of empty values (#484)
-* formatter: configure quoting character (default is `"`) (#484)
-* bug: fix not importing io correctly in non-linux environments (#481)
-
-# 0.11.2
-
-* bug: fix windows terminal detection (#476)
-
-# 0.11.1
-
-* bug: fix tty detection with custom out (#471)
-
-# 0.11.0
-
-* performance: Use bufferpool to allocate (#370)
-* terminal: terminal detection for app-engine (#343)
-* feature: exit handler (#375)
-
-# 0.10.0
-
-* feature: Add a test hook (#180)
-* feature: `ParseLevel` is now case-insensitive (#326)
-* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
-* performance: avoid re-allocations on `WithFields` (#335)
-
-# 0.9.0
-
-* logrus/text_formatter: don't emit empty msg
-* logrus/hooks/airbrake: move out of main repository
-* logrus/hooks/sentry: move out of main repository
-* logrus/hooks/papertrail: move out of main repository
-* logrus/hooks/bugsnag: move out of main repository
-* logrus/core: run tests with `-race`
-* logrus/core: detect TTY based on `stderr`
-* logrus/core: support `WithError` on logger
-* logrus/core: Solaris support
-
-# 0.8.7
-
-* logrus/core: fix possible race (#216)
-* logrus/doc: small typo fixes and doc improvements
-
-
-# 0.8.6
-
-* hooks/raven: allow passing an initialized client
-
-# 0.8.5
-
-* logrus/core: revert #208
-
-# 0.8.4
-
-* formatter/text: fix data race (#218)
-
-# 0.8.3
-
-* logrus/core: fix entry log level (#208)
-* logrus/core: improve performance of text formatter by 40%
-* logrus/core: expose `LevelHooks` type
-* logrus/core: add support for DragonflyBSD and NetBSD
-* formatter/text: print structs more verbosely
-
-# 0.8.2
-
-* logrus: fix more Fatal family functions
-
-# 0.8.1
-
-* logrus: fix not exiting on `Fatalf` and `Fatalln`
-
-# 0.8.0
-
-* logrus: defaults to stderr instead of stdout
-* hooks/sentry: add special field for `*http.Request`
-* formatter/text: ignore Windows for colors
-
-# 0.7.3
-
-* formatter/\*: allow configuration of timestamp layout
-
-# 0.7.2
-
-* formatter/text: Add configuration option for time format (#158)
diff --git a/src/vendor/github.com/Sirupsen/logrus/entry.go b/src/vendor/github.com/Sirupsen/logrus/entry.go
deleted file mode 100644
index 778f4c9f0..000000000
--- a/src/vendor/github.com/Sirupsen/logrus/entry.go
+++ /dev/null
@@ -1,288 +0,0 @@
-package logrus
-
-import (
- "bytes"
- "fmt"
- "os"
- "sync"
- "time"
-)
-
-var bufferPool *sync.Pool
-
-func init() {
- bufferPool = &sync.Pool{
- New: func() interface{} {
- return new(bytes.Buffer)
- },
- }
-}
-
-// Defines the key when adding errors using WithError.
-var ErrorKey = "error"
-
-// An entry is the final or intermediate Logrus logging entry. It contains all
-// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
-// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
-// passed around as much as you wish to avoid field duplication.
-type Entry struct {
- Logger *Logger
-
- // Contains all the fields set by the user.
- Data Fields
-
- // Time at which the log entry was created
- Time time.Time
-
- // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
- // This field will be set on entry firing and the value will be equal to the one in Logger struct field.
- Level Level
-
- // Message passed to Debug, Info, Warn, Error, Fatal or Panic
- Message string
-
- // When formatter is called in entry.log(), an Buffer may be set to entry
- Buffer *bytes.Buffer
-}
-
-func NewEntry(logger *Logger) *Entry {
- return &Entry{
- Logger: logger,
- // Default is three fields, give a little extra room
- Data: make(Fields, 5),
- }
-}
-
-// Returns the string representation from the reader and ultimately the
-// formatter.
-func (entry *Entry) String() (string, error) {
- serialized, err := entry.Logger.Formatter.Format(entry)
- if err != nil {
- return "", err
- }
- str := string(serialized)
- return str, nil
-}
-
-// Add an error as single field (using the key defined in ErrorKey) to the Entry.
-func (entry *Entry) WithError(err error) *Entry {
- return entry.WithField(ErrorKey, err)
-}
-
-// Add a single field to the Entry.
-func (entry *Entry) WithField(key string, value interface{}) *Entry {
- return entry.WithFields(Fields{key: value})
-}
-
-// Add a map of fields to the Entry.
-func (entry *Entry) WithFields(fields Fields) *Entry {
- data := make(Fields, len(entry.Data)+len(fields))
- for k, v := range entry.Data {
- data[k] = v
- }
- for k, v := range fields {
- data[k] = v
- }
- return &Entry{Logger: entry.Logger, Data: data}
-}
-
-// This function is not declared with a pointer value because otherwise
-// race conditions will occur when using multiple goroutines
-func (entry Entry) log(level Level, msg string) {
- var buffer *bytes.Buffer
- entry.Time = time.Now()
- entry.Level = level
- entry.Message = msg
-
- entry.fireHooks()
-
- buffer = bufferPool.Get().(*bytes.Buffer)
- buffer.Reset()
- defer bufferPool.Put(buffer)
- entry.Buffer = buffer
-
- entry.write()
-
- entry.Buffer = nil
-
- // To avoid Entry#log() returning a value that only would make sense for
- // panic() to use in Entry#Panic(), we avoid the allocation by checking
- // directly here.
- if level <= PanicLevel {
- panic(&entry)
- }
-}
-
-// This function is not declared with a pointer value because otherwise
-// race conditions will occur when using multiple goroutines
-func (entry Entry) fireHooks() {
- entry.Logger.mu.Lock()
- defer entry.Logger.mu.Unlock()
- err := entry.Logger.Hooks.Fire(entry.Level, &entry)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
- }
-}
-
-func (entry *Entry) write() {
- serialized, err := entry.Logger.Formatter.Format(entry)
- entry.Logger.mu.Lock()
- defer entry.Logger.mu.Unlock()
- if err != nil {
- fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
- } else {
- _, err = entry.Logger.Out.Write(serialized)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
- }
- }
-}
-
-func (entry *Entry) Debug(args ...interface{}) {
- if entry.Logger.level() >= DebugLevel {
- entry.log(DebugLevel, fmt.Sprint(args...))
- }
-}
-
-func (entry *Entry) Print(args ...interface{}) {
- entry.Info(args...)
-}
-
-func (entry *Entry) Info(args ...interface{}) {
- if entry.Logger.level() >= InfoLevel {
- entry.log(InfoLevel, fmt.Sprint(args...))
- }
-}
-
-func (entry *Entry) Warn(args ...interface{}) {
- if entry.Logger.level() >= WarnLevel {
- entry.log(WarnLevel, fmt.Sprint(args...))
- }
-}
-
-func (entry *Entry) Warning(args ...interface{}) {
- entry.Warn(args...)
-}
-
-func (entry *Entry) Error(args ...interface{}) {
- if entry.Logger.level() >= ErrorLevel {
- entry.log(ErrorLevel, fmt.Sprint(args...))
- }
-}
-
-func (entry *Entry) Fatal(args ...interface{}) {
- if entry.Logger.level() >= FatalLevel {
- entry.log(FatalLevel, fmt.Sprint(args...))
- }
- Exit(1)
-}
-
-func (entry *Entry) Panic(args ...interface{}) {
- if entry.Logger.level() >= PanicLevel {
- entry.log(PanicLevel, fmt.Sprint(args...))
- }
- panic(fmt.Sprint(args...))
-}
-
-// Entry Printf family functions
-
-func (entry *Entry) Debugf(format string, args ...interface{}) {
- if entry.Logger.level() >= DebugLevel {
- entry.Debug(fmt.Sprintf(format, args...))
- }
-}
-
-func (entry *Entry) Infof(format string, args ...interface{}) {
- if entry.Logger.level() >= InfoLevel {
- entry.Info(fmt.Sprintf(format, args...))
- }
-}
-
-func (entry *Entry) Printf(format string, args ...interface{}) {
- entry.Infof(format, args...)
-}
-
-func (entry *Entry) Warnf(format string, args ...interface{}) {
- if entry.Logger.level() >= WarnLevel {
- entry.Warn(fmt.Sprintf(format, args...))
- }
-}
-
-func (entry *Entry) Warningf(format string, args ...interface{}) {
- entry.Warnf(format, args...)
-}
-
-func (entry *Entry) Errorf(format string, args ...interface{}) {
- if entry.Logger.level() >= ErrorLevel {
- entry.Error(fmt.Sprintf(format, args...))
- }
-}
-
-func (entry *Entry) Fatalf(format string, args ...interface{}) {
- if entry.Logger.level() >= FatalLevel {
- entry.Fatal(fmt.Sprintf(format, args...))
- }
- Exit(1)
-}
-
-func (entry *Entry) Panicf(format string, args ...interface{}) {
- if entry.Logger.level() >= PanicLevel {
- entry.Panic(fmt.Sprintf(format, args...))
- }
-}
-
-// Entry Println family functions
-
-func (entry *Entry) Debugln(args ...interface{}) {
- if entry.Logger.level() >= DebugLevel {
- entry.Debug(entry.sprintlnn(args...))
- }
-}
-
-func (entry *Entry) Infoln(args ...interface{}) {
- if entry.Logger.level() >= InfoLevel {
- entry.Info(entry.sprintlnn(args...))
- }
-}
-
-func (entry *Entry) Println(args ...interface{}) {
- entry.Infoln(args...)
-}
-
-func (entry *Entry) Warnln(args ...interface{}) {
- if entry.Logger.level() >= WarnLevel {
- entry.Warn(entry.sprintlnn(args...))
- }
-}
-
-func (entry *Entry) Warningln(args ...interface{}) {
- entry.Warnln(args...)
-}
-
-func (entry *Entry) Errorln(args ...interface{}) {
- if entry.Logger.level() >= ErrorLevel {
- entry.Error(entry.sprintlnn(args...))
- }
-}
-
-func (entry *Entry) Fatalln(args ...interface{}) {
- if entry.Logger.level() >= FatalLevel {
- entry.Fatal(entry.sprintlnn(args...))
- }
- Exit(1)
-}
-
-func (entry *Entry) Panicln(args ...interface{}) {
- if entry.Logger.level() >= PanicLevel {
- entry.Panic(entry.sprintlnn(args...))
- }
-}
-
-// Sprintlnn => Sprint no newline. This is to get the behavior of how
-// fmt.Sprintln where spaces are always added between operands, regardless of
-// their type. Instead of vendoring the Sprintln implementation to spare a
-// string allocation, we do the simplest thing.
-func (entry *Entry) sprintlnn(args ...interface{}) string {
- msg := fmt.Sprintln(args...)
- return msg[:len(msg)-1]
-}
diff --git a/src/vendor/github.com/Sirupsen/logrus/formatter.go b/src/vendor/github.com/Sirupsen/logrus/formatter.go
deleted file mode 100644
index b183ff5b1..000000000
--- a/src/vendor/github.com/Sirupsen/logrus/formatter.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package logrus
-
-import "time"
-
-const defaultTimestampFormat = time.RFC3339
-
-// The Formatter interface is used to implement a custom Formatter. It takes an
-// `Entry`. It exposes all the fields, including the default ones:
-//
-// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
-// * `entry.Data["time"]`. The timestamp.
-// * `entry.Data["level"]. The level the entry was logged at.
-//
-// Any additional fields added with `WithField` or `WithFields` are also in
-// `entry.Data`. Format is expected to return an array of bytes which are then
-// logged to `logger.Out`.
-type Formatter interface {
- Format(*Entry) ([]byte, error)
-}
-
-// This is to not silently overwrite `time`, `msg` and `level` fields when
-// dumping it. If this code wasn't there doing:
-//
-// logrus.WithField("level", 1).Info("hello")
-//
-// Would just silently drop the user provided level. Instead with this code
-// it'll logged as:
-//
-// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
-//
-// It's not exported because it's still using Data in an opinionated way. It's to
-// avoid code duplication between the two default formatters.
-func prefixFieldClashes(data Fields) {
- if t, ok := data["time"]; ok {
- data["fields.time"] = t
- }
-
- if m, ok := data["msg"]; ok {
- data["fields.msg"] = m
- }
-
- if l, ok := data["level"]; ok {
- data["fields.level"] = l
- }
-}
diff --git a/src/vendor/github.com/Sirupsen/logrus/json_formatter.go b/src/vendor/github.com/Sirupsen/logrus/json_formatter.go
deleted file mode 100644
index fb01c1b10..000000000
--- a/src/vendor/github.com/Sirupsen/logrus/json_formatter.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package logrus
-
-import (
- "encoding/json"
- "fmt"
-)
-
-type fieldKey string
-
-// FieldMap allows customization of the key names for default fields.
-type FieldMap map[fieldKey]string
-
-// Default key names for the default fields
-const (
- FieldKeyMsg = "msg"
- FieldKeyLevel = "level"
- FieldKeyTime = "time"
-)
-
-func (f FieldMap) resolve(key fieldKey) string {
- if k, ok := f[key]; ok {
- return k
- }
-
- return string(key)
-}
-
-// JSONFormatter formats logs into parsable json
-type JSONFormatter struct {
- // TimestampFormat sets the format used for marshaling timestamps.
- TimestampFormat string
-
- // DisableTimestamp allows disabling automatic timestamps in output
- DisableTimestamp bool
-
- // FieldMap allows users to customize the names of keys for default fields.
- // As an example:
- // formatter := &JSONFormatter{
- // FieldMap: FieldMap{
- // FieldKeyTime: "@timestamp",
- // FieldKeyLevel: "@level",
- // FieldKeyMsg: "@message",
- // },
- // }
- FieldMap FieldMap
-}
-
-// Format renders a single log entry
-func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
- data := make(Fields, len(entry.Data)+3)
- for k, v := range entry.Data {
- switch v := v.(type) {
- case error:
- // Otherwise errors are ignored by `encoding/json`
- // https://github.com/sirupsen/logrus/issues/137
- data[k] = v.Error()
- default:
- data[k] = v
- }
- }
- prefixFieldClashes(data)
-
- timestampFormat := f.TimestampFormat
- if timestampFormat == "" {
- timestampFormat = defaultTimestampFormat
- }
-
- if !f.DisableTimestamp {
- data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
- }
- data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
- data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
-
- serialized, err := json.Marshal(data)
- if err != nil {
- return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
- }
- return append(serialized, '\n'), nil
-}
diff --git a/src/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/src/vendor/github.com/Sirupsen/logrus/terminal_bsd.go
deleted file mode 100644
index 4880d13d2..000000000
--- a/src/vendor/github.com/Sirupsen/logrus/terminal_bsd.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// +build darwin freebsd openbsd netbsd dragonfly
-// +build !appengine,!gopherjs
-
-package logrus
-
-import "golang.org/x/sys/unix"
-
-const ioctlReadTermios = unix.TIOCGETA
-
-type Termios unix.Termios
diff --git a/src/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/src/vendor/github.com/Sirupsen/logrus/terminal_linux.go
deleted file mode 100644
index f29a0097c..000000000
--- a/src/vendor/github.com/Sirupsen/logrus/terminal_linux.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Based on ssh/terminal:
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !appengine,!gopherjs
-
-package logrus
-
-import "golang.org/x/sys/unix"
-
-const ioctlReadTermios = unix.TCGETS
-
-type Termios unix.Termios
diff --git a/src/vendor/github.com/Sirupsen/logrus/text_formatter.go b/src/vendor/github.com/Sirupsen/logrus/text_formatter.go
deleted file mode 100644
index 61b21caea..000000000
--- a/src/vendor/github.com/Sirupsen/logrus/text_formatter.go
+++ /dev/null
@@ -1,178 +0,0 @@
-package logrus
-
-import (
- "bytes"
- "fmt"
- "sort"
- "strings"
- "sync"
- "time"
-)
-
-const (
- nocolor = 0
- red = 31
- green = 32
- yellow = 33
- blue = 36
- gray = 37
-)
-
-var (
- baseTimestamp time.Time
-)
-
-func init() {
- baseTimestamp = time.Now()
-}
-
-// TextFormatter formats logs into text
-type TextFormatter struct {
- // Set to true to bypass checking for a TTY before outputting colors.
- ForceColors bool
-
- // Force disabling colors.
- DisableColors bool
-
- // Disable timestamp logging. useful when output is redirected to logging
- // system that already adds timestamps.
- DisableTimestamp bool
-
- // Enable logging the full timestamp when a TTY is attached instead of just
- // the time passed since beginning of execution.
- FullTimestamp bool
-
- // TimestampFormat to use for display when a full timestamp is printed
- TimestampFormat string
-
- // The fields are sorted by default for a consistent output. For applications
- // that log extremely frequently and don't use the JSON formatter this may not
- // be desired.
- DisableSorting bool
-
- // QuoteEmptyFields will wrap empty fields in quotes if true
- QuoteEmptyFields bool
-
- // Whether the logger's out is to a terminal
- isTerminal bool
-
- sync.Once
-}
-
-func (f *TextFormatter) init(entry *Entry) {
- if entry.Logger != nil {
- f.isTerminal = checkIfTerminal(entry.Logger.Out)
- }
-}
-
-// Format renders a single log entry
-func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
- var b *bytes.Buffer
- keys := make([]string, 0, len(entry.Data))
- for k := range entry.Data {
- keys = append(keys, k)
- }
-
- if !f.DisableSorting {
- sort.Strings(keys)
- }
- if entry.Buffer != nil {
- b = entry.Buffer
- } else {
- b = &bytes.Buffer{}
- }
-
- prefixFieldClashes(entry.Data)
-
- f.Do(func() { f.init(entry) })
-
- isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
-
- timestampFormat := f.TimestampFormat
- if timestampFormat == "" {
- timestampFormat = defaultTimestampFormat
- }
- if isColored {
- f.printColored(b, entry, keys, timestampFormat)
- } else {
- if !f.DisableTimestamp {
- f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat))
- }
- f.appendKeyValue(b, "level", entry.Level.String())
- if entry.Message != "" {
- f.appendKeyValue(b, "msg", entry.Message)
- }
- for _, key := range keys {
- f.appendKeyValue(b, key, entry.Data[key])
- }
- }
-
- b.WriteByte('\n')
- return b.Bytes(), nil
-}
-
-func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) {
- var levelColor int
- switch entry.Level {
- case DebugLevel:
- levelColor = gray
- case WarnLevel:
- levelColor = yellow
- case ErrorLevel, FatalLevel, PanicLevel:
- levelColor = red
- default:
- levelColor = blue
- }
-
- levelText := strings.ToUpper(entry.Level.String())[0:4]
-
- if f.DisableTimestamp {
- fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
- } else if !f.FullTimestamp {
- fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
- } else {
- fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
- }
- for _, k := range keys {
- v := entry.Data[k]
- fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
- f.appendValue(b, v)
- }
-}
-
-func (f *TextFormatter) needsQuoting(text string) bool {
- if f.QuoteEmptyFields && len(text) == 0 {
- return true
- }
- for _, ch := range text {
- if !((ch >= 'a' && ch <= 'z') ||
- (ch >= 'A' && ch <= 'Z') ||
- (ch >= '0' && ch <= '9') ||
- ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
- return true
- }
- }
- return false
-}
-
-func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
- if b.Len() > 0 {
- b.WriteByte(' ')
- }
- b.WriteString(key)
- b.WriteByte('=')
- f.appendValue(b, value)
-}
-
-func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
- stringVal, ok := value.(string)
- if !ok {
- stringVal = fmt.Sprint(value)
- }
-
- if !f.needsQuoting(stringVal) {
- b.WriteString(stringVal)
- } else {
- b.WriteString(fmt.Sprintf("%q", stringVal))
- }
-}
diff --git a/src/vendor/github.com/docker/distribution/.gitignore b/src/vendor/github.com/docker/distribution/.gitignore
index 1c3ae0a77..4cf7888e9 100644
--- a/src/vendor/github.com/docker/distribution/.gitignore
+++ b/src/vendor/github.com/docker/distribution/.gitignore
@@ -35,3 +35,4 @@ bin/*
# Editor/IDE specific files.
*.sublime-project
*.sublime-workspace
+.idea/*
diff --git a/src/vendor/github.com/docker/distribution/.gometalinter.json b/src/vendor/github.com/docker/distribution/.gometalinter.json
new file mode 100644
index 000000000..9df5b14bc
--- /dev/null
+++ b/src/vendor/github.com/docker/distribution/.gometalinter.json
@@ -0,0 +1,16 @@
+{
+ "Vendor": true,
+ "Deadline": "2m",
+ "Sort": ["linter", "severity", "path", "line"],
+ "EnableGC": true,
+ "Enable": [
+ "structcheck",
+ "staticcheck",
+ "unconvert",
+
+ "gofmt",
+ "goimports",
+ "golint",
+ "vet"
+ ]
+}
diff --git a/src/vendor/github.com/docker/distribution/.mailmap b/src/vendor/github.com/docker/distribution/.mailmap
index 2d68669f3..0f48321d4 100644
--- a/src/vendor/github.com/docker/distribution/.mailmap
+++ b/src/vendor/github.com/docker/distribution/.mailmap
@@ -1,9 +1,9 @@
-Stephen J Day Stephen Day
-Stephen J Day Stephen Day
-Olivier Gambier Olivier Gambier
-Brian Bland Brian Bland
+Stephen J Day Stephen Day
+Stephen J Day Stephen Day
+Olivier Gambier Olivier Gambier
+Brian Bland Brian Bland
Brian Bland Brian Bland
-Josh Hawn Josh Hawn
+Josh Hawn Josh Hawn
Richard Scothern Richard
Richard Scothern Richard Scothern
Andrew Meredith Andrew Meredith
@@ -16,4 +16,17 @@ davidli davidli
Omer Cohen Omer Cohen
Eric Yang Eric Yang
Nikita Tarasov Nikita
-Misty Stanley-Jones Misty Stanley-Jones
+Yu Wang yuwaMSFT2
+Yu Wang Yu Wang (UC)
+Olivier Gambier dmp
+Olivier Gambier Olivier
+Olivier Gambier Olivier
+Elsan Li 李楠 elsanli(李楠)
+Rui Cao ruicao
+Gwendolynne Barr gbarr01
+Haibing Zhou 周海兵 zhouhaibing089
+Feng Honglin tifayuki
+Helen Xie Helen-xie
+Mike Brown Mike Brown
+Manish Tomar Manish Tomar
+Sakeven Jiang sakeven
diff --git a/src/vendor/github.com/docker/distribution/.travis.yml b/src/vendor/github.com/docker/distribution/.travis.yml
new file mode 100644
index 000000000..44ced6045
--- /dev/null
+++ b/src/vendor/github.com/docker/distribution/.travis.yml
@@ -0,0 +1,51 @@
+dist: trusty
+sudo: required
+# setup travis so that we can run containers for integration tests
+services:
+ - docker
+
+language: go
+
+go:
+ - "1.11.x"
+
+go_import_path: github.com/docker/distribution
+
+addons:
+ apt:
+ packages:
+ - python-minimal
+
+
+env:
+ - TRAVIS_GOOS=linux DOCKER_BUILDTAGS="include_oss include_gcs" TRAVIS_CGO_ENABLED=1
+
+before_install:
+ - uname -r
+ - sudo apt-get -q update
+
+install:
+ - go get -u github.com/vbatts/git-validation
+ # TODO: Add enforcement of license
+ # - go get -u github.com/kunalkushwaha/ltag
+ - cd $TRAVIS_BUILD_DIR
+
+script:
+ - export GOOS=$TRAVIS_GOOS
+ - export CGO_ENABLED=$TRAVIS_CGO_ENABLED
+ - DCO_VERBOSITY=-q script/validate/dco
+ - GOOS=linux script/setup/install-dev-tools
+ - script/validate/vendor
+ - go build -i .
+ - make check
+ - make build
+ - make binaries
+ # Currently takes too long
+ #- if [ "$GOOS" = "linux" ]; then make test-race ; fi
+ - if [ "$GOOS" = "linux" ]; then make coverage ; fi
+
+after_success:
+ - bash <(curl -s https://codecov.io/bash) -F linux
+
+before_deploy:
+ # Run tests with storage driver configurations
diff --git a/src/vendor/github.com/docker/distribution/AUTHORS b/src/vendor/github.com/docker/distribution/AUTHORS
deleted file mode 100644
index aaf029871..000000000
--- a/src/vendor/github.com/docker/distribution/AUTHORS
+++ /dev/null
@@ -1,182 +0,0 @@
-Aaron Lehmann
-Aaron Schlesinger
-Aaron Vinson
-Adam Duke
-Adam Enger
-Adrian Mouat
-Ahmet Alp Balkan
-Alex Chan
-Alex Elman
-Alexey Gladkov
-allencloud
-amitshukla
-Amy Lindburg
-Andrew Hsu
-Andrew Meredith
-Andrew T Nguyen
-Andrey Kostov
-Andy Goldstein
-Anis Elleuch
-Antonio Mercado
-Antonio Murdaca
-Anton Tiurin
-Anusha Ragunathan
-a-palchikov
-Arien Holthuizen
-Arnaud Porterie
-Arthur Baars
-Asuka Suzuki
-Avi Miller
-Ayose Cazorla
-BadZen
-Ben Bodenmiller
-Ben Firshman
-bin liu
-Brian Bland
-burnettk
-Carson A
-Cezar Sa Espinola
-Charles Smith
-Chris Dillon
-cuiwei13
-cyli
-Daisuke Fujita
-Daniel Huhn
-Darren Shepherd
-Dave Trombley
-Dave Tucker
-David Lawrence
-davidli
-David Verhasselt
-David Xia
-Dejan Golja
-Derek McGowan
-Diogo Mónica
-DJ Enriquez
-Donald Huang
-Doug Davis
-Edgar Lee
-Eric Yang
-Fabio Berchtold
-Fabio Huser
-farmerworking
-Felix Yan
-Florentin Raud
-Frank Chen
-Frederick F. Kautz IV
-gabriell nascimento
-Gleb Schukin
-harche
-Henri Gomez
-Hua Wang
-Hu Keping
-HuKeping
-Ian Babrou
-igayoso
-Jack Griffin
-James Findley
-Jason Freidman
-Jason Heiss
-Jeff Nickoloff
-Jess Frazelle
-Jessie Frazelle
-jhaohai
-Jianqing Wang
-Jihoon Chung
-Joao Fernandes
-John Mulhausen
-John Starks
-Jonathan Boulle
-Jon Johnson
-Jon Poler
-Jordan Liggitt
-Josh Chorlton
-Josh Hawn
-Julien Fernandez
-Keerthan Mala
-Kelsey Hightower
-Kenneth Lim
-Kenny Leung
-Ke Xu
-liuchang0812
-Liu Hua
-Li Yi
-Lloyd Ramey
-Louis Kottmann
-Luke Carpenter
-Marcus Martins
-Mary Anthony
-Matt Bentley
-Matt Duch
-Matthew Green
-Matt Moore
-Matt Robenolt
-Michael Prokop
-Michal Minar
-Michal Minář
-Mike Brown
-Miquel Sabaté
-Misty Stanley-Jones
-Morgan Bauer
-moxiegirl
-Nathan Sullivan
-nevermosby
-Nghia Tran
-Nikita Tarasov
-Noah Treuhaft
-Nuutti Kotivuori
-Oilbeater
-Olivier Gambier
-Olivier Jacques
-Omer Cohen
-Patrick Devine
-Phil Estes
-Philip Misiowiec
-Pierre-Yves Ritschard
-Qiao Anran
-Randy Barlow
-Richard Scothern
-Rodolfo Carvalho
-Rusty Conover
-Sean Boran
-Sebastiaan van Stijn
-Sebastien Coavoux
-Serge Dubrouski
-Sharif Nassar
-Shawn Falkner-Horine
-Shreyas Karnik
-Simon Thulbourn
-spacexnice
-Spencer Rinehart
-Stan Hu
-Stefan Majewsky
-Stefan Weil
-Stephen J Day
-Sungho Moon
-Sven Dowideit
-Sylvain Baubeau
-Ted Reed
-tgic
-Thomas Sjögren
-Tianon Gravi
-Tibor Vass
-Tonis Tiigi
-Tony Holdstock-Brown
-Trevor Pounds
-Troels Thomsen
-Victoria Bialas
-Victor Vieux
-Vincent Batts
-Vincent Demeester
-Vincent Giersch
-weiyuan.yl
-W. Trevor King
-xg.song
-xiekeyang
-Yann ROBERT
-yaoyao.xyy
-yixi zhang
-yuexiao-wang