Skip to content

Commit

Permalink
require a minimal filesystem interface
Browse files Browse the repository at this point in the history
  • Loading branch information
andrestc committed Mar 29, 2018
1 parent 437137b commit adb6289
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 63 deletions.
Binary file added deploy-agent
Binary file not shown.
15 changes: 7 additions & 8 deletions deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,28 @@ import (
"log"

"github.com/tsuru/tsuru/exec"
"github.com/tsuru/tsuru/fs"
)

func build(c Client, appName string, cmd []string, filesystem fs.Fs, executor exec.Executor) {
func build(c Client, appName string, cmd []string, fs Filesystem, executor exec.Executor) {
log.SetFlags(0)
envs, err := c.getAppEnvs(appName)
if err != nil {
log.Fatal(err)
}
err = execScript(cmd, envs, nil, filesystem, executor)
err = execScript(cmd, envs, nil, fs, executor)
if err != nil {
log.Fatal(err)
}
}

func deploy(c Client, appName string, filesystem fs.Fs, executor exec.Executor) {
func deploy(c Client, appName string, fs Filesystem, executor exec.Executor) {
log.SetFlags(0)
var yamlData TsuruYaml
envs, err := c.registerUnit(appName, yamlData)
if err != nil {
log.Fatal(err)
}
diff, firstDeploy, err := readDiffDeploy(filesystem)
diff, firstDeploy, err := readDiffDeploy(fs)
if err != nil {
log.Fatal(err)
}
Expand All @@ -40,15 +39,15 @@ func deploy(c Client, appName string, filesystem fs.Fs, executor exec.Executor)
log.Fatal(err)
}
}
yamlData, err = loadTsuruYaml(filesystem)
yamlData, err = loadTsuruYaml(fs)
if err != nil {
log.Fatal(err)
}
err = buildHooks(yamlData, envs, filesystem, executor)
err = buildHooks(yamlData, envs, fs, executor)
if err != nil {
log.Fatal(err)
}
err = loadProcesses(&yamlData, filesystem)
err = loadProcesses(&yamlData, fs)
if err != nil {
log.Fatal(err)
}
Expand Down
38 changes: 38 additions & 0 deletions filesystem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package main

import (
"io/ioutil"
"os"

"github.com/tsuru/tsuru/fs"
)

type Filesystem interface {
ReadFile(name string) ([]byte, error)
CheckFile(name string) (bool, error)
RemoveFile(name string) error
}

// localFS is a wrapper around fs.Fs that implements Filesystem
type localFS struct{ fs.Fs }

func (f *localFS) ReadFile(name string) ([]byte, error) {
file, err := f.Fs.Open(name)
if err != nil {
return nil, err
}
defer file.Close()
return ioutil.ReadAll(file)
}

func (f *localFS) CheckFile(name string) (bool, error) {
_, err := f.Fs.Stat(name)
if os.IsNotExist(err) {
return false, nil
}
return err == nil, err
}

func (f *localFS) RemoveFile(name string) error {
return f.Fs.Remove(name)
}
20 changes: 11 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@ import (
"flag"
"fmt"
"os"

"github.com/tsuru/tsuru/exec"
)

const version = "0.2.8"

var printVersion bool

func init() {
func main() {
var (
printVersion bool
)
flag.BoolVar(&printVersion, "version", false, "Print version and exit")
flag.Parse()
}

func main() {
if printVersion {
fmt.Printf("deploy-agent version %s\n", version)
return
}

c := Client{
URL: os.Args[1],
Token: os.Args[2],
Expand All @@ -33,15 +35,15 @@ func main() {

switch command[len(command)-1] {
case "build":
build(c, appName, command[:len(command)-1], &fs.OsFs{}, &exec.OsExecutor{})
build(c, appName, command[:len(command)-1], &localFS{}, &exec.OsExecutor{})
case "deploy-only":
deploy(c, appName, &fs.OsFs{}, &exec.OsExecutor{})
deploy(c, appName, &localFS{}, &exec.OsExecutor{})
case "deploy":
// backward compatibility with tsuru < 1.4.0
command = command[:len(command)-1]
fallthrough
default:
build(c, appName, command, &fs.OsFs{}, &exec.OsExecutor{})
deploy(c, appName, &fs.OsFs{}, &exec.OsExecutor{})
build(c, appName, command, &localFS{}, &exec.OsExecutor{})
deploy(c, appName, &localFS{}, &exec.OsExecutor{})
}
}
8 changes: 6 additions & 2 deletions suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ import (
func Test(t *testing.T) { check.TestingT(t) }

type S struct {
fs *fstest.RecordingFs
fs *localFS
exec *exectest.FakeExecutor
}

var _ = check.Suite(&S{})

func (s *S) SetUpTest(c *check.C) {
s.fs = &fstest.RecordingFs{}
s.fs = &localFS{Fs: &fstest.RecordingFs{}}
s.exec = &exectest.FakeExecutor{}
err := s.fs.Mkdir(defaultWorkingDir, 0777)
c.Assert(err, check.IsNil)
}

func (s *S) testFS() *fstest.RecordingFs {
return s.fs.Fs.(*fstest.RecordingFs)
}
52 changes: 18 additions & 34 deletions tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/tsuru/deploy-agent/internal/user"
"github.com/tsuru/tsuru/app/bind"
"github.com/tsuru/tsuru/exec"
"github.com/tsuru/tsuru/fs"
"gopkg.in/yaml.v2"
)

Expand All @@ -26,7 +25,7 @@ var (
appEnvsFile = "/tmp/app_envs"
)

func execScript(cmds []string, envs []bind.EnvVar, w io.Writer, filesystem fs.Fs, executor exec.Executor) error {
func execScript(cmds []string, envs []bind.EnvVar, w io.Writer, fs Filesystem, executor exec.Executor) error {
if w == nil {
w = ioutil.Discard
}
Expand All @@ -35,12 +34,12 @@ func execScript(cmds []string, envs []bind.EnvVar, w io.Writer, filesystem fs.Fs
return err
}
workingDir := defaultWorkingDir
if _, err := filesystem.Stat(defaultWorkingDir); err != nil {
if os.IsNotExist(err) {
workingDir = "/"
} else {
return err
}
exists, err := fs.CheckFile(defaultWorkingDir)
if err != nil {
return err
}
if exists == false {
workingDir = "/"
}
formatedEnvs := []string{}
for _, env := range envs {
Expand Down Expand Up @@ -80,19 +79,14 @@ type Hook struct {
func (t *TsuruYaml) isEmpty() bool {
return len(t.Hooks.BuildHooks) == 0 && t.Processes == nil
}
func loadTsuruYaml(filesystem fs.Fs) (TsuruYaml, error) {
func loadTsuruYaml(fs Filesystem) (TsuruYaml, error) {
var tsuruYamlData TsuruYaml
for _, yamlFile := range tsuruYamlFiles {
filePath := fmt.Sprintf("%s/%s", defaultWorkingDir, yamlFile)
f, err := filesystem.Open(filePath)
tsuruYaml, err := fs.ReadFile(filePath)
if err != nil {
continue
}
defer f.Close()
tsuruYaml, err := ioutil.ReadAll(f)
if err != nil {
return TsuruYaml{}, err
}
err = yaml.Unmarshal(tsuruYaml, &tsuruYamlData)
if err != nil {
return TsuruYaml{}, err
Expand All @@ -102,19 +96,14 @@ func loadTsuruYaml(filesystem fs.Fs) (TsuruYaml, error) {
return tsuruYamlData, nil
}

func buildHooks(yamlData TsuruYaml, envs []bind.EnvVar, filesystem fs.Fs, executor exec.Executor) error {
func buildHooks(yamlData TsuruYaml, envs []bind.EnvVar, fs Filesystem, executor exec.Executor) error {
cmds := append([]string{}, yamlData.Hooks.BuildHooks...)
fmt.Fprintln(os.Stdout, "---- Running build hooks ----")
return execScript(cmds, envs, os.Stdout, filesystem, executor)
return execScript(cmds, envs, os.Stdout, fs, executor)
}

func readProcfile(path string, filesystem fs.Fs) (string, error) {
f, err := filesystem.Open(fmt.Sprintf("%v/Procfile", path))
if err != nil {
return "", err
}
defer f.Close()
procfile, err := ioutil.ReadAll(f)
func readProcfile(path string, fs Filesystem) (string, error) {
procfile, err := fs.ReadFile(fmt.Sprintf("%v/Procfile", path))
if err != nil {
return "", err
}
Expand All @@ -123,8 +112,8 @@ func readProcfile(path string, filesystem fs.Fs) (string, error) {

var procfileRegex = regexp.MustCompile(`^([\w-]+):\s*(\S.+)$`)

func loadProcesses(t *TsuruYaml, filesystem fs.Fs) error {
procfile, err := readProcfile(defaultWorkingDir, filesystem)
func loadProcesses(t *TsuruYaml, fs Filesystem) error {
procfile, err := readProcfile(defaultWorkingDir, fs)
if err != nil {
return err
}
Expand All @@ -142,17 +131,12 @@ func loadProcesses(t *TsuruYaml, filesystem fs.Fs) error {
return nil
}

func readDiffDeploy(filesystem fs.Fs) (string, bool, error) {
func readDiffDeploy(fs Filesystem) (string, bool, error) {
filePath := fmt.Sprintf("%s/%s", defaultWorkingDir, "diff")
f, err := filesystem.Open(filePath)
defer f.Close()
defer filesystem.Remove(filePath)
if err != nil {
return "", true, nil
}
deployDiff, err := ioutil.ReadAll(f)
deployDiff, err := fs.ReadFile(filePath)
if err != nil {
return "", true, err
}
defer fs.RemoveFile(filePath)
return string(deployDiff), false, nil
}
20 changes: 10 additions & 10 deletions tasks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ healthcheck:
match: .*OK
allowed_failures: 0`
tsuruYmlPath := fmt.Sprintf("%s/%s", defaultWorkingDir, "tsuru.yml")
s.fs.FileContent = tsuruYmlData
s.testFS().FileContent = tsuruYmlData
_, err := s.fs.Create(tsuruYmlPath)
c.Assert(err, check.IsNil)
c.Assert(s.fs.HasAction(fmt.Sprintf("create %s", tsuruYmlPath)), check.Equals, true)
c.Assert(s.testFS().HasAction(fmt.Sprintf("create %s", tsuruYmlPath)), check.Equals, true)
expected := TsuruYaml{
Hooks: Hook{
BuildHooks: []string{"test", "another_test"},
Expand Down Expand Up @@ -138,10 +138,10 @@ func (s *S) TestHooks(c *check.C) {
func (s *S) TestLoadProcesses(c *check.C) {
procfile := "web: python app.py"
procfilePath := fmt.Sprintf("%s/%s", defaultWorkingDir, "Procfile")
s.fs.FileContent = procfile
s.testFS().FileContent = procfile
_, err := s.fs.Create(procfilePath)
c.Assert(err, check.IsNil)
c.Assert(s.fs.HasAction(fmt.Sprintf("create %s", procfilePath)), check.Equals, true)
c.Assert(s.testFS().HasAction(fmt.Sprintf("create %s", procfilePath)), check.Equals, true)
expected := TsuruYaml{
Processes: map[string]string{
"web": "python app.py",
Expand All @@ -160,10 +160,10 @@ another-worker: run-task
# disabled-worker: run-task
`
procfilePath := fmt.Sprintf("%s/%s", defaultWorkingDir, "Procfile")
s.fs.FileContent = procfile
s.testFS().FileContent = procfile
_, err := s.fs.Create(procfilePath)
c.Assert(err, check.IsNil)
c.Assert(s.fs.HasAction(fmt.Sprintf("create %s", procfilePath)), check.Equals, true)
c.Assert(s.testFS().HasAction(fmt.Sprintf("create %s", procfilePath)), check.Equals, true)
expected := TsuruYaml{
Processes: map[string]string{
"web": "python app.py",
Expand All @@ -180,10 +180,10 @@ func (s *S) TestDontLoadWrongProcfile(c *check.C) {
procfile := `web:
@python test.py`
procfilePath := fmt.Sprintf("%s/%s", defaultWorkingDir, "Procfile")
s.fs.FileContent = procfile
s.testFS().FileContent = procfile
_, err := s.fs.Create(procfilePath)
c.Assert(err, check.IsNil)
c.Assert(s.fs.HasAction(fmt.Sprintf("create %s", procfilePath)), check.Equals, true)
c.Assert(s.testFS().HasAction(fmt.Sprintf("create %s", procfilePath)), check.Equals, true)
t := TsuruYaml{}
err = loadProcesses(&t, s.fs)
c.Assert(err, check.NotNil)
Expand All @@ -208,10 +208,10 @@ func (s *S) TestDiffDeploy(c *check.C) {
}
`
diffPath := fmt.Sprintf("%s/%s", defaultWorkingDir, "diff")
s.fs.FileContent = diff
s.testFS().FileContent = diff
_, err := s.fs.Create(diffPath)
c.Assert(err, check.IsNil)
c.Assert(s.fs.HasAction(fmt.Sprintf("create %s", diffPath)), check.Equals, true)
c.Assert(s.testFS().HasAction(fmt.Sprintf("create %s", diffPath)), check.Equals, true)
result, first, err := readDiffDeploy(s.fs)
c.Assert(err, check.IsNil)
c.Assert(result, check.DeepEquals, diff)
Expand Down

0 comments on commit adb6289

Please sign in to comment.