internal/command/command.go (70 lines of code) (raw):

package command import ( "context" "fmt" "os" "path" "strings" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/tracing" ) type Command interface { Execute(ctx context.Context) (context.Context, error) } type LogMetadata struct { Project string `json:"project,omitempty"` RootNamespace string `json:"root_namespace,omitempty"` ProjectID int `json:"project_id,omitempty"` RootNamespaceID int `json:"root_namespace_id,omitempty"` } type LogData struct { Username string `json:"username"` WrittenBytes int64 `json:"written_bytes"` Meta LogMetadata `json:"meta"` } func CheckForVersionFlag(osArgs []string, version, buildTime string) { // We can't use the flag library because gitlab-shell receives other arguments // that confuse the parser. // // See: https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/800#note_1459474735 if len(osArgs) == 2 && osArgs[1] == "-version" { fmt.Printf("%s %s-%s\n", path.Base(osArgs[0]), version, buildTime) os.Exit(0) } } // Setup() initializes tracing from the configuration file and generates a // background context from which all other contexts in the process should derive // from, as it has a service name and initial correlation ID set. func Setup(serviceName string, config *config.Config) (context.Context, func()) { closer := tracing.Initialize( tracing.WithServiceName(serviceName), // For GitLab-Shell, we explicitly initialize tracing from a config file // instead of the default environment variable (using GITLAB_TRACING) // This decision was made owing to the difficulty in passing environment // variables into GitLab-Shell processes. // // Processes are spawned as children of the SSH daemon, which tightly // controls environment variables; doing this means we don't have to // enable PermitUserEnvironment // // gitlab-sshd could use the standard GITLAB_TRACING envvar, but that // would lead to inconsistencies between the two forms of operation tracing.WithConnectionString(config.GitlabTracing), ) ctx, finished := tracing.ExtractFromEnv(context.Background()) ctx = correlation.ContextWithClientName(ctx, serviceName) correlationID := correlation.ExtractFromContext(ctx) if correlationID == "" { correlationID := correlation.SafeRandomID() ctx = correlation.ContextWithCorrelation(ctx, correlationID) } return ctx, func() { finished() closer.Close() } } func NewLogData(project, username string, projectID, rootNamespaceID int) LogData { rootNameSpace := "" if len(project) > 0 { splitFn := func(c rune) bool { return c == '/' } m := strings.FieldsFunc(project, splitFn) if len(m) > 0 { rootNameSpace = m[0] } } return LogData{ Username: username, WrittenBytes: 0, Meta: LogMetadata{ Project: project, RootNamespace: rootNameSpace, ProjectID: projectID, RootNamespaceID: rootNamespaceID, }, } }