Skip to content

Commit

Permalink
Merge branch 'unit-test/scm-test' into 'master'
Browse files Browse the repository at this point in the history
source code manager unit-test

See merge request !122
  • Loading branch information
CMGS committed Aug 3, 2017
2 parents fd1b6ad + f9698f8 commit ce6cb2e
Show file tree
Hide file tree
Showing 11 changed files with 487 additions and 152 deletions.
4 changes: 2 additions & 2 deletions cluster/calcium/build_image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
func TestGetRandomNode(t *testing.T) {
store := &mockstore.MockStore{}
config := types.Config{}
c := &calcium{store: store, config: config, scheduler: simplescheduler.New(), network: calico.New(), source: gitlab.New(config)}
c := &calcium{store: store, config: config, scheduler: simplescheduler.New(), network: calico.New(), source: gitlab.New(config.Git)}

n1 := &types.Node{Name: "node1", Podname: "podname", Endpoint: "tcp://10.0.0.1:2376", CPU: types.CPUMap{"0": 10, "1": 10}, Available: true}
n2 := &types.Node{Name: "node2", Podname: "podname", Endpoint: "tcp://10.0.0.2:2376", CPU: types.CPUMap{"0": 10, "1": 10}, Available: true}
Expand All @@ -34,7 +34,7 @@ func TestGetRandomNode(t *testing.T) {
func TestGetRandomNodeFail(t *testing.T) {
store := &mockstore.MockStore{}
config := types.Config{}
c := &calcium{store: store, config: config, scheduler: simplescheduler.New(), network: calico.New(), source: gitlab.New(config)}
c := &calcium{store: store, config: config, scheduler: simplescheduler.New(), network: calico.New(), source: gitlab.New(config.Git)}

n1 := &types.Node{Name: "node1", Podname: "podname", Endpoint: "tcp://10.0.0.1:2376", CPU: types.CPUMap{"0": 10, "1": 10}, Available: false}
n2 := &types.Node{Name: "node2", Podname: "podname", Endpoint: "tcp://10.0.0.2:2376", CPU: types.CPUMap{"0": 10, "1": 10}, Available: false}
Expand Down
25 changes: 23 additions & 2 deletions cluster/calcium/cluster.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package calcium

import (
"fmt"
"strings"

"gitlab.ricebook.net/platform/core/network"
"gitlab.ricebook.net/platform/core/network/calico"
"gitlab.ricebook.net/platform/core/scheduler"
"gitlab.ricebook.net/platform/core/scheduler/complex"
"gitlab.ricebook.net/platform/core/source"
"gitlab.ricebook.net/platform/core/source/github"
"gitlab.ricebook.net/platform/core/source/gitlab"
"gitlab.ricebook.net/platform/core/store"
"gitlab.ricebook.net/platform/core/store/etcd"
Expand All @@ -25,6 +29,12 @@ const (
BEFORE_STOP = "before_stop"
)

const (
GITLAB = "gitlab"
GITHUB = "github"
)

// New returns a new cluster config
func New(config types.Config) (*calcium, error) {
var err error
store, err := etcdstore.New(config)
Expand All @@ -37,9 +47,20 @@ func New(config types.Config) (*calcium, error) {
return nil, err
}
titanium := calico.New()
source := gitlab.New(config)

return &calcium{store: store, config: config, scheduler: scheduler, network: titanium, source: source}, nil
var scm source.Source
scmtype := strings.ToLower(config.Git.SCMType)

switch scmtype {
case GITLAB:
scm = gitlab.New(config.Git)
case GITHUB:
scm = github.New(config.Git)
default:
return nil, fmt.Errorf("Unkonwn SCM type: %s", config.Git.SCMType)
}

return &calcium{store: store, config: config, scheduler: scheduler, network: titanium, source: scm}, nil
}

func (c *calcium) ResetSotre(s store.Store) {
Expand Down
6 changes: 3 additions & 3 deletions cluster/calcium/meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
func TestListPods(t *testing.T) {
store := &mockstore.MockStore{}
config := types.Config{}
c := &calcium{store: store, config: config, scheduler: simplescheduler.New(), network: calico.New(), source: gitlab.New(config)}
c := &calcium{store: store, config: config, scheduler: simplescheduler.New(), network: calico.New(), source: gitlab.New(config.Git)}

store.On("GetAllPods").Return([]*types.Pod{
&types.Pod{Name: "pod1", Desc: "desc1"},
Expand All @@ -36,7 +36,7 @@ func TestListPods(t *testing.T) {
func TestAddPod(t *testing.T) {
store := &mockstore.MockStore{}
config := types.Config{}
c := &calcium{store: store, config: config, scheduler: simplescheduler.New(), network: calico.New(), source: gitlab.New(config)}
c := &calcium{store: store, config: config, scheduler: simplescheduler.New(), network: calico.New(), source: gitlab.New(config.Git)}

store.On("AddPod", "pod1", "desc1").Return(&types.Pod{Name: "pod1", Desc: "desc1"}, nil)
store.On("AddPod", "pod2", "desc2").Return(nil, fmt.Errorf("Etcd Error"))
Expand All @@ -54,7 +54,7 @@ func TestAddPod(t *testing.T) {
func TestGetPods(t *testing.T) {
store := &mockstore.MockStore{}
config := types.Config{}
c := &calcium{store: store, config: config, scheduler: simplescheduler.New(), network: calico.New(), source: gitlab.New(config)}
c := &calcium{store: store, config: config, scheduler: simplescheduler.New(), network: calico.New(), source: gitlab.New(config.Git)}

store.On("GetPod", "pod1").Return(&types.Pod{Name: "pod1", Desc: "desc1"}, nil).Once()
store.On("GetPod", "pod2").Return(nil, fmt.Errorf("Not found")).Once()
Expand Down
4 changes: 3 additions & 1 deletion rpc/rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,9 @@ func initConfig(mStore *mockstore.MockStore) (types.Config, *vibranium) {
Zone: "c1", // zone for core, e.g. C1, C2
RunAndWaitTimeout: 1200, // timeout for run and wait

Git: types.GitConfig{},
Git: types.GitConfig{
SCMType: "gitlab",
},
Scheduler: types.SchedConfig{
LockKey: "_scheduler_lock",
LockTTL: 10,
Expand Down
213 changes: 213 additions & 0 deletions source/common/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
package common

import (
"archive/zip"
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"

log "github.com/Sirupsen/logrus"
"gitlab.ricebook.net/platform/core/types"
git "gopkg.in/libgit2/git2go.v25"
)

// GitScm is gitlab or github source code manager
type GitScm struct {
http.Client
Config types.GitConfig
AuthHeaders map[string]string
}

func certificateCheckCallback(cert *git.Certificate, valid bool, hostname string) git.ErrorCode {
return git.ErrorCode(0)
}

func gitcheck(repository, pubkey, prikey string) error {
if !strings.HasPrefix(repository, "git@") {
return fmt.Errorf("Only support ssh protocol(%q), use git@... ", repository)
}
if _, err := os.Stat(pubkey); os.IsNotExist(err) {
return fmt.Errorf("Public Key not found(%q)", pubkey)
}
if _, err := os.Stat(prikey); os.IsNotExist(err) {
return fmt.Errorf("Private Key not found(%q)", prikey)
}

return nil
}

// SourceCode clone code from repository into path, by revision
func (g *GitScm) SourceCode(repository, path, revision string) error {
pubkey := g.Config.PublicKey
prikey := g.Config.PrivateKey

if err := gitcheck(repository, pubkey, prikey); err != nil {
return err
}

credentialsCallback := func(url, username string, allowedTypes git.CredType) (git.ErrorCode, *git.Cred) {
ret, cred := git.NewCredSshKey("git", pubkey, prikey, "")
return git.ErrorCode(ret), &cred
}

cloneOpts := &git.CloneOptions{
FetchOptions: &git.FetchOptions{
RemoteCallbacks: git.RemoteCallbacks{
CredentialsCallback: credentialsCallback,
CertificateCheckCallback: certificateCheckCallback,
},
},
}

repo, err := git.Clone(repository, path, cloneOpts)
if err != nil {
log.Errorf("Error during Clone: %v", err.Error())
return err
}

if err := repo.CheckoutHead(nil); err != nil {
log.Errorf("Error during CheckoutHead: %v", err.Error())
return err
}

object, err := repo.RevparseSingle(revision)
if err != nil {
log.Errorf("Error during RevparseSingle: %v", err.Error())
return err
}
defer object.Free()
commit, err := object.AsCommit()

return repo.ResetToCommit(commit, git.ResetHard, &git.CheckoutOpts{Strategy: git.CheckoutSafe})
}

// Artifact download the artifact to the path, then unzip it
func (g *GitScm) Artifact(artifact, path string) error {
req, err := http.NewRequest("GET", artifact, nil)
if err != nil {
return err
}

for k, v := range g.AuthHeaders {
req.Header.Add(k, v)
}

log.Debugf("Downloading artifacts from %q", artifact)
resp, err := g.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("Download artifact error %q", artifact)
}
log.Debugf("Download artifacts from %q finished", artifact)

// extract files from zipfile
log.Debugf("Extracting files from %q", artifact)
if err := UnzipFile(resp.Body, path); err != nil {
return err
}
log.Debugf("Extraction from %q done", artifact)

return nil
}

// UnzipFile unzip a file(from resp.Body) to the spec path
func UnzipFile(body io.ReadCloser, path string) error {
content, err := ioutil.ReadAll(body)
if err != nil {
return err
}

reader, err := zip.NewReader(bytes.NewReader(content), int64(len(content)))
if err != nil {
return err
}

// extract files from zipfile
for _, f := range reader.File {
zipped, err := f.Open()
if err != nil {
return err
}

defer zipped.Close()

p := filepath.Join(path, f.Name)

if f.FileInfo().IsDir() {
os.MkdirAll(p, f.Mode())
continue
}

writer, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE, f.Mode())
if err != nil {
return err
}

defer writer.Close()
if _, err = io.Copy(writer, zipped); err != nil {
return err
}
}
return nil
}

// ZipFiles compresses one or many files into a single zip archive file
func ZipFiles(filename string, files []string) error {

newfile, err := os.Create(filename)
if err != nil {
return err
}
defer newfile.Close()

zipWriter := zip.NewWriter(newfile)
defer zipWriter.Close()

// Add files to zip
for _, file := range files {

zipfile, err := os.Open(file)
if err != nil {
return err
}
defer zipfile.Close()

// Get the file information
info, err := zipfile.Stat()
if err != nil {
return err
}

header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}

// Change to deflate to gain better compression
// see http://golang.org/pkg/archive/zip/#pkg-constants
header.Method = zip.Deflate

writer, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
_, err = io.Copy(writer, zipfile)
if err != nil {
return err
}
}
return nil
}

// Security remove the .git folder
func (g *GitScm) Security(path string) error {
return os.RemoveAll(filepath.Join(path, ".git"))
}
Loading

0 comments on commit ce6cb2e

Please sign in to comment.