Skip to content

Commit

Permalink
Use gitaly-upload-pack and gitaly-receive-pack
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobvosmaer committed May 23, 2017
1 parent 285c061 commit 25a32cf
Show file tree
Hide file tree
Showing 33 changed files with 9,808 additions and 54 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ tags
custom_hooks
hooks/*.d
/go_build
/bin/hello-world
/bin/gitaly-upload-pack
/bin/gitaly-receive-pack
4 changes: 2 additions & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ rspec:ruby2.1:
except:
- tags

compile:
go:
# Image taken from gitlab-ce@59f81b4ff8
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.7-phantomjs-2.1-node-7.1"
script:
- go version
- which go
- bin/compile

- support/go-test
29 changes: 5 additions & 24 deletions bin/compile
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,16 @@

require 'fileutils'

# This will set the ROOT_PATH variable
require_relative '../lib/gitlab_init'

GO_DIR = 'go'
BUILD_DIR = File.join(ROOT_PATH, 'go_build')
GO_PACKAGE = File.join('gitlab.com/gitlab-org/gitlab-shell', GO_DIR)
require_relative '../support/go_build'
include GoBuild

def main
FileUtils.rm_rf(BUILD_DIR)
build_source_dir = File.join(BUILD_DIR, 'src', GO_PACKAGE)
FileUtils.mkdir_p(build_source_dir)
FileUtils.cp_r(File.join(ROOT_PATH, GO_DIR, '.'), build_source_dir)
env = {
'GOPATH' => BUILD_DIR,
'GO15VENDOREXPERIMENT' => '1',
}
run!(env, %W[go install #{GO_PACKAGE}/cmd/...])
create_fresh_build_dir

run!(GO_ENV, %W[go install #{GO_PACKAGE}/cmd/...])
executables = Dir[File.join(BUILD_DIR, 'bin', '*')]
FileUtils.chmod(0755, executables)
FileUtils.cp(executables, File.join(ROOT_PATH, 'bin'))
end

def run!(env, cmd)
raise "env must be a hash" unless env.is_a?(Hash)
raise "cmd must be an array" unless cmd.is_a?(Array)

if !system(env, *cmd)
abort "command failed: #{env.inspect} #{cmd.join(' ')}"
end
end

main
30 changes: 30 additions & 0 deletions go/cmd/gitaly-receive-pack/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"encoding/json"
"os"

"gitlab.com/gitlab-org/gitlab-shell/go/internal/handler"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/logger"

pb "gitlab.com/gitlab-org/gitaly-proto/go"
)

func init() {
logger.ProgName = "gitaly-receive-pack"
}

func main() {
if err := handler.Prepare(); err != nil {
logger.Fatal(err)
}

var request pb.SSHReceivePackRequest
if err := json.Unmarshal([]byte(os.Args[2]), &request); err != nil {
logger.Fatal(err)
}

if err := handler.ReceivePack(os.Args[1], &request); err != nil {
logger.Fatal(err)
}
}
30 changes: 30 additions & 0 deletions go/cmd/gitaly-upload-pack/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"encoding/json"
"os"

"gitlab.com/gitlab-org/gitlab-shell/go/internal/handler"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/logger"

pb "gitlab.com/gitlab-org/gitaly-proto/go"
)

func init() {
logger.ProgName = "gitaly-upload-pack"
}

func main() {
if err := handler.Prepare(); err != nil {
logger.Fatal(err)
}

var request pb.SSHUploadPackRequest
if err := json.Unmarshal([]byte(os.Args[2]), &request); err != nil {
logger.Fatal(err)
}

if err := handler.UploadPack(os.Args[1], &request); err != nil {
logger.Fatal(err)
}
}
12 changes: 0 additions & 12 deletions go/cmd/hello-world/main.go

This file was deleted.

57 changes: 57 additions & 0 deletions go/internal/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package config

import (
"io/ioutil"
"os"
"path"

"gopkg.in/yaml.v2"
)

const (
configFile = "config.yml"
logFile = "gitlab-shell.log"
)

type Config struct {
RootDir string
LogFile string `yaml:"log_file"`
}

func New() (*Config, error) {
cfg := Config{}

dir, err := os.Getwd()
if err != nil {
return nil, err
}
cfg.RootDir = dir

configBytes, err := ioutil.ReadFile(path.Join(cfg.RootDir, configFile))
if err != nil {
return nil, err
}

if err := parseConfig(configBytes, &cfg); err != nil {
return nil, err
}

return &cfg, nil
}

// parseConfig expects YAML data in configBytes and a Config instance with RootDir set.
func parseConfig(configBytes []byte, cfg *Config) error {
if err := yaml.Unmarshal(configBytes, cfg); err != nil {
return err
}

if cfg.LogFile == "" {
cfg.LogFile = logFile
}

if len(cfg.LogFile) > 0 && cfg.LogFile[0] != '/' {
cfg.LogFile = path.Join(cfg.RootDir, cfg.LogFile)
}

return nil
}
28 changes: 28 additions & 0 deletions go/internal/config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package config

import (
"testing"
)

func TestConfigLogFile(t *testing.T) {
testRoot := "/foo/bar"
testCases := []struct {
yaml string
path string
}{
{path: "/foo/bar/gitlab-shell.log"},
{yaml: "log_file: my-log.log", path: "/foo/bar/my-log.log"},
{yaml: "log_file: /qux/my-log.log", path: "/qux/my-log.log"},
}

for _, tc := range testCases {
cfg := Config{RootDir: testRoot}
if err := parseConfig([]byte(tc.yaml), &cfg); err != nil {
t.Fatalf("%q: %v", tc.yaml, err)
}

if cfg.LogFile != tc.path {
t.Fatalf("%q: expected %q, got %q", tc.yaml, tc.path, cfg.LogFile)
}
}
}
38 changes: 38 additions & 0 deletions go/internal/handler/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package handler

import (
"os"
"os/exec"
"syscall"

"gitlab.com/gitlab-org/gitlab-shell/go/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/logger"
)

func Prepare() error {
cfg, err := config.New()
if err != nil {
return err
}

if err := logger.Configure(cfg); err != nil {
return err
}

// Use a working directory that won't get removed or unmounted.
if err := os.Chdir("/"); err != nil {
return err
}

return nil
}

func execCommand(command string, args ...string) error {
binPath, err := exec.LookPath(command)
if err != nil {
return err
}

args = append([]string{binPath}, args...)
return syscall.Exec(binPath, args, os.Environ())
}
16 changes: 16 additions & 0 deletions go/internal/handler/receive_pack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package handler

import (
"fmt"

pb "gitlab.com/gitlab-org/gitaly-proto/go"
)

func ReceivePack(gitalyAddress string, request *pb.SSHReceivePackRequest) error {
repoPath := request.Repository.Path
if repoPath == "" {
return fmt.Errorf("empty path in repository message")
}

return execCommand("git-receive-pack", repoPath)
}
16 changes: 16 additions & 0 deletions go/internal/handler/upload_pack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package handler

import (
"fmt"

pb "gitlab.com/gitlab-org/gitaly-proto/go"
)

func UploadPack(gitalyAddress string, request *pb.SSHUploadPackRequest) error {
repoPath := request.Repository.Path
if repoPath == "" {
return fmt.Errorf("empty path in repository message")
}

return execCommand("git-upload-pack", repoPath)
}
72 changes: 72 additions & 0 deletions go/internal/logger/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package logger

import (
"fmt"
"io"
"log"
"log/syslog"
"os"
"sync"
"time"

"gitlab.com/gitlab-org/gitlab-shell/go/internal/config"
)

var (
logWriter io.Writer
bootstrapLogger *log.Logger
pid int
mutex sync.Mutex
ProgName string
)

func Configure(cfg *config.Config) error {
mutex.Lock()
defer mutex.Unlock()

pid = os.Getpid()

var err error
logWriter, err = os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND, 0)
return err
}

func logPrint(msg ...interface{}) {
mutex.Lock()
defer mutex.Unlock()

if logWriter == nil {
bootstrapLogPrint(msg...)
return
}

// Emulate the existing log format of gitlab-shell
t := time.Now().Format("2006-01-02T15:04:05.999999")
prefix := fmt.Sprintf("E, [%s #%d] ERROR -- : %s: ", t, pid, ProgName)
fmt.Fprintln(logWriter, append([]interface{}{prefix}, msg...)...)
}

func Fatal(msg ...interface{}) {
logPrint(msg...)
fmt.Fprintf(os.Stderr, "%s: fatal error\n", ProgName)
os.Exit(1)
}

// If our log file is not available we want to log somewhere else, but
// not to standard error because that leaks information to the user. This
// function attemps to log to syslog.
//
// We assume the logging mutex is already locked.
func bootstrapLogPrint(msg ...interface{}) {
if bootstrapLogger == nil {
var err error
bootstrapLogger, err = syslog.NewLogger(syslog.LOG_ERR|syslog.LOG_USER, 0)
if err != nil {
// The message will not be logged.
return
}
}

args := append([]interface{}{ProgName + ":"}, msg...)
bootstrapLogger.Print(args)
}
13 changes: 13 additions & 0 deletions go/vendor/gopkg.in/yaml.v2/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 25a32cf

Please sign in to comment.