Skip to content

Commit

Permalink
Implement a simple Git server for hosting repos
Browse files Browse the repository at this point in the history
Supports auto linking a build config to a git repo
mirror, as well as integrating automatic push.
  • Loading branch information
smarterclayton committed May 1, 2015
1 parent c81b66b commit eb3ea80
Show file tree
Hide file tree
Showing 16 changed files with 1,069 additions and 1 deletion.
13 changes: 13 additions & 0 deletions examples/gitserver/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#
# This is an example Git server for OpenShift Origin.
#
# The standard name for this image is openshift/origin-gitserver
#
FROM openshift/origin

ADD hooks/ /var/lib/git-hooks/
RUN ln -s /usr/bin/openshift /usr/bin/openshift-gitserver && \
mkdir -p /var/lib/git
VOLUME /var/lib/git

ENTRYPOINT ["/usr/bin/openshift-gitserver"]
16 changes: 16 additions & 0 deletions examples/gitserver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Configurable Git Server
=======================

This example provides automatic mirroring of Git repositories, intended
for use within a container or Kubernetes pod. It can clone repositories
from remote systems on startup as well as remotely register hooks. It
can automatically initialize and receive Git directories on push.

In the more advanced modes, it can integrate with an OpenShift server to
automatically perform actions when new repositories are created, like
reading the build configs in the current namespace and performing
automatic mirroring of their input, and creating new build-configs when
content is pushed.

The Dockerfile built by this example is published as
openshift/origin-gitserver
48 changes: 48 additions & 0 deletions examples/gitserver/hooks/detect-language
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash
#
# detect-language returns a string indicating the image repository to use as a base
# image for this source repository. Return "docker.io/*/*" for Docker images, a two
# segment entry for a local image repository, or a single segment name to search
# in the current namespace. Set a tag to qualify the version - e.g. "ruby:1.9.3",
# "nodejs:0.10".
#

set -o errexit
set -o nounset
set -o pipefail

function has {
[[ -n $(git ls-tree --full-name --name-only HEAD ${@:1}) ]]
}
function key {
git config --local --get "${1}"
}

prefix=${PREFIX:-openshift/}

if has Gemfile; then
echo "${prefix}ruby"
exit 0
fi

if has requirements.txt; then
echo "${prefix}python"
exit 0
fi

if has package.json app.json; then
echo "${prefix}nodejs"
exit 0
fi

if has '*.go'; then
echo "${prefix}golang"
exit 0
fi

if has index.php; then
echo "${prefix}php"
exit 0
fi

exit 1
54 changes: 54 additions & 0 deletions examples/gitserver/hooks/post-receive
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash

set -o errexit
set -o nounset
set -o pipefail

function key {
git config --local --get "${1}"
}
function addkey {
git config --local --add "${1}" "${2}"
}

function detect {
if detected=$(key openshift.io.detect); then
exit 0
fi
if ! url=$(key gitserver.self.url); then
echo "detect: no self url set"
exit 0
fi

# TODO: make it easier to find the build config name created
# by osc new-app
name=$(basename "${url}")
name="${name%.*}"

if ! lang=$($(dirname $0)/detect-language); then
exit 0
fi
echo "detect: found language ${lang} for ${name}"

if ! osc=$(which osc); then
echo "detect: osc is not installed"
addkey openshift.io.detect 1
exit 0
fi
osc new-app "${lang}~${url}"
if webhook=$(osc start-build --show-webhooks="generic" "${name}"); then
addkey openshift.io.webhook "${webhook}"
fi
addkey openshift.io.detect 1
}

cat > /tmp/postreceived

detect

if webhook=$(key openshift.io.webhook); then
# TODO: print output from the server about the hook status
osc start-build --from-webhook="${webhook}"
# TODO: follow logs
echo "build: started"
fi
23 changes: 23 additions & 0 deletions examples/gitserver/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"fmt"
"log"
"os"

"github.com/openshift/origin/pkg/gitserver"
)

func main() {
if len(os.Args) != 1 {
fmt.Printf(`git-server - Expose Git repositories to the network
%[1]s`, gitserver.EnvironmentHelp)
os.Exit(0)
}
config, err := gitserver.NewEnviromentConfig()
if err != nil {
log.Fatal(err)
}
log.Fatal(gitserver.Start(config))
}
47 changes: 47 additions & 0 deletions examples/gitserver/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
apiVersion: v1beta3
kind: List
items:
- apiVersion: v1beta3
kind: DeploymentConfig
metadata:
name: gitserver
spec:
triggers:
- type: ConfigChange
replicas: 1
selector:
run-container: gitserver
template:
metadata:
labels:
run-container: gitserver
spec:
containers:
- name: gitserver
image: openshift/origin-gitserver
ports:
- containerPort: 8080
env:
- name: PUBLIC_URL
value: http://gitserver:8080 # TODO: calculate me?
- name: GIT_HOME
value: /var/lib/git
- name: HOOK_PATH
value: /var/lib/git-hooks
- name: ALLOW_GIT_PUSH
value: "yes"
- name: ALLOW_GIT_HOOKS
value: "yes"
- name: ALLOW_LAZY_CREATE
value: "yes"
- name: AUTOLINK_CONFIG
#value: # TODO: use the service account secret
- name: AUTOLINK_NAMESPACE
#value: # TODO: use env generation
- name: AUTOLINK_HOOK
value:
- name: REQUIRE_GIT_AUTH
#value: user:password # if set, authentication is required to push to this server
#- name: GIT_INITIAL_CLONE_1
# value:

1 change: 1 addition & 0 deletions hack/build-images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ image openshift/origin-docker-registry images/dockerregistry
# images that depend on openshift/origin
image openshift/origin-deployer images/deployer
image openshift/origin-docker-builder images/builder/docker/docker-builder
image openshift/origin-gitserver examples/gitserver
image openshift/origin-sti-builder images/builder/docker/sti-builder
# extra images (not part of infrastructure)
image openshift/hello-openshift examples/hello-openshift
Expand Down
1 change: 1 addition & 0 deletions hack/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ readonly OPENSHIFT_BINARY_SYMLINKS=(
openshift-deploy
openshift-sti-build
openshift-docker-build
openshift-gitserver
osc
osadm
)
Expand Down
6 changes: 6 additions & 0 deletions images/dockerregistry/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#
# This is the integrated OpenShift Origin Docker registry. It is configured to
# publish metadata to OpenShift to provide automatic management of images on push.
#
# The standard name for this image is openshift/origin-docker-registry
#
FROM openshift/origin-base

ADD config.yml /config.yml
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func NewCommandAdmin(name, fullName string, out io.Writer) *cobra.Command {
// Main command
cmds := &cobra.Command{
Use: name,
Short: "tools for managing an OpenShift cluster",
Short: "Tools for managing an OpenShift cluster",
Long: fmt.Sprintf(longDesc),
Run: func(c *cobra.Command, args []string) {
c.SetOutput(out)
Expand Down
61 changes: 61 additions & 0 deletions pkg/cmd/infra/gitserver/gitserver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package gitserver

import (
"fmt"
"log"
"net/url"

cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"

"github.com/openshift/origin/pkg/gitserver"
"github.com/openshift/origin/pkg/gitserver/autobuild"
)

const longCommandDesc = `
Start a Git server
This command launches a Git HTTP/HTTPS server that supports push and pull, mirroring,
and automatic creation of OpenShift applications on push.
%[1]s
`

// NewCommandGitServer launches a Git server
func NewCommandGitServer(name string) *cobra.Command {
cmd := &cobra.Command{
Use: name,
Short: "Start a Git server",
Long: fmt.Sprintf(longCommandDesc, gitserver.EnvironmentHelp),
Run: func(c *cobra.Command, args []string) {
err := RunGitServer()
cmdutil.CheckErr(err)
},
}

return cmd
}

func RunGitServer() error {
config, err := gitserver.NewEnviromentConfig()
if err != nil {
return err
}
link, err := autobuild.NewAutoLinkBuildsFromEnvironment()
switch {
case err == autobuild.ErrNotEnabled:
case err != nil:
log.Fatal(err)
default:
link.LinkFn = func(name string) *url.URL { return gitserver.RepositoryURL(config, name, nil) }
clones, err := link.Link()
if err != nil {
log.Printf("error: %v", err)
break
}
for name, v := range clones {
config.InitialClones[name] = v
}
}
return gitserver.Start(config)
}
4 changes: 4 additions & 0 deletions pkg/cmd/openshift/openshift.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/openshift/origin/pkg/cmd/flagtypes"
"github.com/openshift/origin/pkg/cmd/infra/builder"
"github.com/openshift/origin/pkg/cmd/infra/deployer"
"github.com/openshift/origin/pkg/cmd/infra/gitserver"
"github.com/openshift/origin/pkg/cmd/infra/router"
"github.com/openshift/origin/pkg/cmd/server/start"
"github.com/openshift/origin/pkg/cmd/templates"
Expand Down Expand Up @@ -63,6 +64,8 @@ func CommandFor(basename string) *cobra.Command {
cmd = builder.NewCommandSTIBuilder(basename)
case "openshift-docker-build":
cmd = builder.NewCommandDockerBuilder(basename)
case "openshift-gitserver":
cmd = gitserver.NewCommandGitServer(basename)
case "osc":
cmd = cli.NewCommandCLI(basename, basename)
case "osadm":
Expand Down Expand Up @@ -108,6 +111,7 @@ func NewCommandOpenShift() *cobra.Command {
deployer.NewCommandDeployer("deploy"),
builder.NewCommandSTIBuilder("sti-build"),
builder.NewCommandDockerBuilder("docker-build"),
gitserver.NewCommandGitServer("git-server"),
)
root.AddCommand(infra)

Expand Down
Loading

0 comments on commit eb3ea80

Please sign in to comment.