Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Herokuish builds, deployment rework #146

Merged
merged 33 commits into from
Apr 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e356ccf
Complete overhaul of daemon deployment management
bobheadxi Mar 27, 2018
e273f27
Update Travis script for more accurate coverage
bobheadxi Mar 27, 2018
901b18a
Remove docker-compose check on init, streamline error handling in logs
bobheadxi Mar 27, 2018
4e53bca
Remove unused encryption methods
bobheadxi Mar 27, 2018
050559c
Allow access to daemon logs with no deployment
bobheadxi Mar 27, 2018
ccc2eb6
Smarter status messages and log condition
bobheadxi Mar 27, 2018
26eedaf
Experimental Herokuish build
bobheadxi Mar 25, 2018
0287674
Continued experimental Herokuish build
bobheadxi Mar 28, 2018
7552ca0
Rename "repository" to "git"
bobheadxi Mar 29, 2018
4082ce8
Option to skip repo update on deploy, rename kill to stop
bobheadxi Mar 29, 2018
385add0
Use logger.Success
bobheadxi Mar 29, 2018
42a043b
Detect and specify build method
bobheadxi Mar 30, 2018
937e381
Improve feedback and tooltips
bobheadxi Mar 30, 2018
290925f
Fix deployment.Up() test
bobheadxi Mar 30, 2018
6f8863e
Deployer interface and tests
bobheadxi Mar 31, 2018
dab5cba
Update HTTP codes returned by status, fix mock functions
bobheadxi Mar 31, 2018
b7ca975
Merge branch 'master' into rob/#67-buildpacks
bobheadxi Mar 31, 2018
11ff37c
Add missing Branch argument to NewDeployment call
bobheadxi Mar 31, 2018
5ec07c2
Merge branch 'master' into rob/#67-buildpacks
bobheadxi Apr 1, 2018
f14be49
Report build progress and deploy
bobheadxi Apr 2, 2018
7043644
Fix ineffective break, add missing err check
bobheadxi Apr 2, 2018
93d4656
Minor fixes, polish, and comments
bobheadxi Apr 2, 2018
37e04ef
Fix project directory mounting
bobheadxi Apr 2, 2018
a6b6062
Remove test images
bobheadxi Apr 2, 2018
40bd898
Fix incorrect bootstrap wording for test image
bobheadxi Apr 4, 2018
b2d6fda
Fix FlushRoutine stop and Herokuish build process
bobheadxi Apr 4, 2018
8bb5b5c
Merge branch 'master' into rob/#67-buildpacks
bobheadxi Apr 5, 2018
e8c4aa5
Start web process on Heroku build
bobheadxi Apr 5, 2018
47142ca
Refine naming, add note that "web" is only one possible Heroku process
bobheadxi Apr 5, 2018
b62b154
Fix --version support for "inertia init"
bobheadxi Apr 5, 2018
4062d4d
Minor linting fixes
bobheadxi Apr 5, 2018
77b9523
Merge branch 'master' into rob/#67-buildpacks
bobheadxi Apr 7, 2018
e728842
Add build type to Status, warn if build type unknown
bobheadxi Apr 7, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ testdaemon:
rm -f ./inertia-daemon-image
docker build -t ubclaunchpad/inertia:test .
docker save -o ./inertia-daemon-image ubclaunchpad/inertia:test
docker rmi ubclaunchpad/inertia:test
chmod 400 ./test/keys/id_rsa
scp -i ./test/keys/id_rsa \
-o StrictHostKeyChecking=no \
Expand Down
12 changes: 6 additions & 6 deletions client/bootstrap.go

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

4 changes: 2 additions & 2 deletions client/bootstrap/daemon-up.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ if [ "$DAEMON_RELEASE" != "test" ]; then
echo "Pulling Inertia daemon..."
sudo docker pull $IMAGE
else
echo "Launching existing Inertia daemon image..."
sudo docker load -i /daemon-image
echo "Loading existing Inertia daemon image..."
sudo docker load --quiet -i /daemon-image
fi

# Run container with access to the host docker socket and relevant directories -
Expand Down
31 changes: 14 additions & 17 deletions client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ var (

// Config represents the current projects configuration.
type Config struct {
Version string `toml:"inertia"`
Project string `toml:"project"`
Remotes []*RemoteVPS `toml:"remote"`
Writer io.Writer `toml:"-"`
Version string `toml:"inertia"`
Project string `toml:"project-name"`
BuildType string `toml:"build-type"`
Remotes []*RemoteVPS `toml:"remote"`
Writer io.Writer `toml:"-"`
}

// Write writes configuration to Inertia config file.
Expand Down Expand Up @@ -73,7 +74,7 @@ func (config *Config) RemoveRemote(name string) bool {

// InitializeInertiaProject creates the inertia config folder and
// returns an error if we're not in a git project.
func InitializeInertiaProject(version string) error {
func InitializeInertiaProject(version, buildType string) error {
cwd, err := os.Getwd()
if err != nil {
return err
Expand All @@ -82,25 +83,20 @@ func InitializeInertiaProject(version string) error {
if err != nil {
return err
}
err = common.CheckForDockerCompose(cwd)
if err != nil {
return err
}

return createConfigFile(version)
return createConfigFile(version, buildType)
}

// createConfigFile returns an error if the config directory
// already exists (the project is already initialized).
func createConfigFile(version string) error {
func createConfigFile(version, buildType string) error {
configFilePath, err := GetConfigFilePath()
if err != nil {
return err
}

// Check if Inertia is already set up.
s, fileErr := os.Stat(configFilePath)

// Check if everything already exists.
if s != nil {
return errors.New("inertia already properly configured in this folder")
}
Expand All @@ -110,12 +106,13 @@ func createConfigFile(version string) error {
return err
}

// Directory exists. Make sure JSON exists.
// Directory exists. Make sure configuration file exists.
if os.IsNotExist(fileErr) {
config := Config{
Project: filepath.Base(cwd),
Version: version,
Remotes: make([]*RemoteVPS, 0),
Project: filepath.Base(cwd),
Version: version,
BuildType: buildType,
Remotes: make([]*RemoteVPS, 0),
}

path, err := GetConfigFilePath()
Expand Down
2 changes: 1 addition & 1 deletion client/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func TestConfigCreateAndWriteAndRead(t *testing.T) {
err := createConfigFile("")
err := createConfigFile("", "")
assert.Nil(t, err)
config, err := GetProjectConfigFromDisk()
assert.Nil(t, err)
Expand Down
15 changes: 11 additions & 4 deletions client/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Deployment struct {
Repository *git.Repository
Auth string
Project string
BuildType string
}

// GetDeployment returns the local deployment setup
Expand All @@ -44,23 +45,29 @@ func GetDeployment(name string) (*Deployment, error) {
RemoteVPS: remote,
Repository: repo,
Auth: auth,
BuildType: config.BuildType,
Project: config.Project,
}, nil
}

// Up brings the project up on the remote VPS instance specified
// in the deployment object.
func (d *Deployment) Up(project string, stream bool) (*http.Response, error) {
func (d *Deployment) Up(buildType string, stream bool) (*http.Response, error) {
// TODO: Support other Git remotes.
origin, err := d.Repository.Remote("origin")
if err != nil {
return nil, err
}

if buildType == "" {
buildType = d.BuildType
}

reqContent := &common.DaemonRequest{
Stream: stream,
Project: project,
Secret: d.RemoteVPS.Daemon.Secret,
Stream: stream,
Project: d.Project,
BuildType: buildType,
Secret: d.RemoteVPS.Daemon.Secret,
GitOptions: &common.GitOptions{
RemoteURL: common.GetSSHRemoteURL(origin.Config().URLs[0]),
Branch: d.Branch,
Expand Down
6 changes: 4 additions & 2 deletions client/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var (
func getMockDeployment(ts *httptest.Server, s *memory.Storage) (*Deployment, error) {
wholeURL := strings.Split(ts.URL, ":")
url := strings.Trim(wholeURL[1], "/")
port := wholeURL[2]
port := wholeURL[2]
mockRemote := &RemoteVPS{
User: "",
IP: url,
Expand All @@ -48,6 +48,7 @@ func getMockDeployment(ts *httptest.Server, s *memory.Storage) (*Deployment, err
RemoteVPS: mockRemote,
Repository: mockRepo,
Auth: fakeAuth,
Project: "test_project",
}, nil
}

Expand All @@ -68,6 +69,7 @@ func TestUp(t *testing.T) {
assert.Equal(t, "myremote.git", upReq.GitOptions.RemoteURL)
assert.Equal(t, "arjan", upReq.Secret)
assert.Equal(t, "test_project", upReq.Project)
assert.Equal(t, "docker-compose", upReq.BuildType)

// Check correct endpoint called
endpoint := req.URL.Path
Expand All @@ -84,7 +86,7 @@ func TestUp(t *testing.T) {
d, err := getMockDeployment(testServer, memory)
assert.Nil(t, err)

resp, err := d.Up("test_project", false)
resp, err := d.Up("docker-compose", false)
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
}
Expand Down
4 changes: 3 additions & 1 deletion client/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ func (remote *RemoteVPS) Bootstrap(runner SSHSession, name string, config *Confi
return err
}

println("Inertia has been set up and daemon is running on remote!\n")
println("\nInertia has been set up and daemon is running on remote!")
println("You may have to wait briefly for Inertia to set up some dependencies.")
fmt.Printf("Use 'inertia %s logs --stream' to check on the daemon's setup progress.\n\n", name)

println("=============================\n")

Expand Down
8 changes: 6 additions & 2 deletions common/request.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package common

const (
// DaemonOkResp is the OK response upon successfully reaching daemon
DaemonOkResp = "I'm a little Webhook, short and stout!"
// DefaultSecret used for some verification
DefaultSecret = "inertia"

// MsgDaemonOK is the OK response upon successfully reaching daemon
MsgDaemonOK = "I'm a little Webhook, short and stout!"

// DefaultPort defines the standard daemon port
DefaultPort = "8081"
Expand All @@ -13,6 +16,7 @@ type DaemonRequest struct {
Stream bool `json:"stream"`
Container string `json:"container,omitempty"`
Project string `json:"project"`
BuildType string `json:"build_type"`
GitOptions *GitOptions `json:"git_options"`
Secret string `json:"secret"`
}
Expand Down
32 changes: 17 additions & 15 deletions common/util.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package common

import (
"errors"
"io"
"net/http"
"os"
Expand All @@ -10,18 +9,14 @@ import (

// CheckForDockerCompose returns error if current directory is a
// not a docker-compose project
func CheckForDockerCompose(cwd string) error {
func CheckForDockerCompose(cwd string) bool {
dockerComposeYML := filepath.Join(cwd, "docker-compose.yml")
dockerComposeYAML := filepath.Join(cwd, "docker-compose.yaml")
_, err := os.Stat(dockerComposeYML)
YMLpresent := os.IsNotExist(err)
YMLnotPresent := os.IsNotExist(err)
_, err = os.Stat(dockerComposeYAML)
YAMLpresent := os.IsNotExist(err)
if YMLpresent && YAMLpresent {
return errors.New("this does not appear to be a docker-compose project - currently,\n" +
"Inertia only supports docker-compose projects.")
}
return nil
YAMLnotPresent := os.IsNotExist(err)
return !(YMLnotPresent && YAMLnotPresent)
}

// RemoveContents removes all files within given directory, returns nil if successful
Expand All @@ -46,14 +41,21 @@ func RemoveContents(directory string) error {

// FlushRoutine continuously writes everything in given ReadCloser
// to a ResponseWriter. Use this as a goroutine.
func FlushRoutine(w io.Writer, rc io.ReadCloser) {
func FlushRoutine(w io.Writer, rc io.ReadCloser, stop chan struct{}) {
buffer := make([]byte, 100)
ROUTINE:
for {
// Read from pipe then write to ResponseWriter and flush it,
// sending the copied content to the client.
err := Flush(w, rc, buffer)
if err != nil {
break
select {
case <-stop:
Flush(w, rc, buffer)
break ROUTINE
default:
// Read from pipe then write to ResponseWriter and flush it,
// sending the copied content to the client.
err := Flush(w, rc, buffer)
if err != nil {
break ROUTINE
}
}
}
}
Expand Down
33 changes: 23 additions & 10 deletions common/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,35 @@ func TestCheckForDockerCompose(t *testing.T) {
cwd, err := os.Getwd()
assert.Nil(t, err)

yamlPath := path.Join(cwd, "/docker-compose.yml")
ymlPath := path.Join(cwd, "/docker-compose.yml")
yamlPath := path.Join(cwd, "/docker-compose.yaml")

assert.NotEqual(t, nil, CheckForDockerCompose(cwd))
file, err := os.Create(yamlPath)
assert.Nil(t, err)
// No!
b := CheckForDockerCompose(cwd)
assert.False(t, b)

// Yes!
file, err := os.Create(ymlPath)
assert.Nil(t, err)
file.Close()
assert.Equal(t, nil, CheckForDockerCompose(cwd))
os.Remove(yamlPath)
b = CheckForDockerCompose(cwd)
assert.True(t, b)
os.Remove(ymlPath)

// Yes!
file, err = os.Create(yamlPath)
assert.Nil(t, err)
file.Close()

assert.Equal(t, nil, CheckForDockerCompose(cwd))
b = CheckForDockerCompose(cwd)
assert.True(t, b)
os.Remove(yamlPath)
}

func TestFlushRoutine(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
reader, writer := io.Pipe()
go FlushRoutine(w, reader)
stop := make(chan struct{})
go FlushRoutine(w, reader, stop)

fmt.Println(writer, "Hello!")
time.Sleep(time.Millisecond)
Expand All @@ -48,6 +56,9 @@ func TestFlushRoutine(t *testing.T) {

fmt.Println(writer, "Bye!")
time.Sleep(time.Millisecond)

close(stop)
fmt.Println(writer, "Do I live?")
}))
defer testServer.Close()

Expand All @@ -56,7 +67,7 @@ func TestFlushRoutine(t *testing.T) {

reader := bufio.NewReader(resp.Body)
i := 0
for i < 3 {
for i < 4 {
line, err := reader.ReadBytes('\n')
if err != nil {
break
Expand All @@ -69,6 +80,8 @@ func TestFlushRoutine(t *testing.T) {
assert.Equal(t, "Lunch?", string(line))
case 2:
assert.Equal(t, "Bye!", string(line))
case 3:
assert.Equal(t, "", string(line))
}

i++
Expand Down
2 changes: 1 addition & 1 deletion daemon/inertia/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ func GitAuthFailedErr() error {
if err != nil {
bytes = []byte(err.Error() + "\nError reading key - try running 'inertia [REMOTE] init' again: ")
}
return errors.New("Access to project repository rejected; did you forget to add\nInertia's deploy key to your repository settings?\n" + string(bytes[:]))
return errors.New("Access to project repository rejected; did you forget to add\nInertia's deploy key to your repository settings?\n" + string(bytes))
}
Loading