Massive handlers refactoring
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Taking logic from handler into glue module Add tests for apps Updated docker library
This commit is contained in:
parent
fdcdca237f
commit
e58d6462a9
13
apps/main.go
13
apps/main.go
@ -7,6 +7,7 @@ import (
|
||||
)
|
||||
|
||||
// AppsProcessor encapsulates functions for apps manipulation
|
||||
// This handles only the database part but not containers
|
||||
type AppsProcessor struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
@ -17,19 +18,19 @@ func (a *AppsProcessor) Init() {
|
||||
}
|
||||
|
||||
// Get returns one app
|
||||
func (a *AppsProcessor) Get(name string) (*App, error) {
|
||||
func (a *AppsProcessor) Get(name string) (App, error) {
|
||||
var app App
|
||||
|
||||
err := a.DB.Preload("Labels").Where("name = ?", name).First(&app).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return app, err
|
||||
}
|
||||
|
||||
return &app, nil
|
||||
return app, nil
|
||||
}
|
||||
|
||||
// List returns all apps located on this node
|
||||
func (a *AppsProcessor) List() (*Apps, error) {
|
||||
func (a *AppsProcessor) List() (Apps, error) {
|
||||
var apps Apps
|
||||
|
||||
err := a.DB.Preload("Labels").Find(&apps).Error
|
||||
@ -37,7 +38,7 @@ func (a *AppsProcessor) List() (*Apps, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &apps, nil
|
||||
return apps, nil
|
||||
}
|
||||
|
||||
// New creates new record about application in the database
|
||||
@ -180,5 +181,5 @@ func (a *AppsProcessor) RemoveLabel(appName string, label string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return a.DB.Where("label = ? AND app_id = ?", label, app.ID).Delete(&Label{}).Error
|
||||
return a.DB.Where("value = ? AND app_id = ?", label, app.ID).Delete(&Label{}).Error
|
||||
}
|
||||
|
189
apps/main_test.go
Normal file
189
apps/main_test.go
Normal file
@ -0,0 +1,189 @@
|
||||
package apps
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/rosti-cz/node-api/detector"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
// This is line from GORM documentation that imports database dialect
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
)
|
||||
|
||||
const testDBPath = "file::memory:?cache=shared"
|
||||
|
||||
func testDB() *gorm.DB {
|
||||
db, err := gorm.Open("sqlite3", testDBPath)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
func TestAppsProcessorGet(t *testing.T) {
|
||||
processor := AppsProcessor{
|
||||
DB: testDB(),
|
||||
}
|
||||
processor.Init()
|
||||
|
||||
err := processor.New("testapp_1234", 1000, 1001, "testimage", 2, 256)
|
||||
assert.Nil(t, err)
|
||||
|
||||
app, err := processor.Get("testapp_1234")
|
||||
assert.Nil(t, err)
|
||||
assert.Greater(t, int(app.ID), 0)
|
||||
}
|
||||
|
||||
func TestAppsProcessorList(t *testing.T) {
|
||||
processor := AppsProcessor{
|
||||
DB: testDB(),
|
||||
}
|
||||
processor.Init()
|
||||
|
||||
err := processor.New("testapp_2234", 1002, 1003, "testimage", 2, 256)
|
||||
assert.Nil(t, err)
|
||||
|
||||
apps, err := processor.List()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "testapp_1234", apps[0].Name)
|
||||
}
|
||||
|
||||
func TestAppsProcessorNew(t *testing.T) {
|
||||
processor := AppsProcessor{
|
||||
DB: testDB(),
|
||||
}
|
||||
processor.Init()
|
||||
|
||||
err := processor.New("testapp_1234", 1002, 1003, "testimage", 2, 256)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestAppsProcessorUpdate(t *testing.T) {
|
||||
processor := AppsProcessor{
|
||||
DB: testDB(),
|
||||
}
|
||||
processor.Init()
|
||||
|
||||
err := processor.New("updateapp_1224", 1002, 1003, "testimage", 2, 256)
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = processor.Update("updateapp_1224", 1052, 1053, "testimage2", 4, 512)
|
||||
assert.Nil(t, err)
|
||||
|
||||
app, err := processor.Get("updateapp_1224")
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 1052, app.SSHPort)
|
||||
assert.Equal(t, 1053, app.HTTPPort)
|
||||
assert.Equal(t, "testimage2", app.Image)
|
||||
assert.Equal(t, 4, app.CPU)
|
||||
assert.Equal(t, 512, app.Memory)
|
||||
}
|
||||
|
||||
func TestAppsProcessorUpdateResources(t *testing.T) {
|
||||
processor := AppsProcessor{
|
||||
DB: testDB(),
|
||||
}
|
||||
processor.Init()
|
||||
|
||||
err := processor.New("updateresources_1224", 1002, 1003, "testimage", 2, 256)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = processor.UpdateResources("updateresources_1224", "running", 1000, 256, 100, 200, detector.Flags{"test"})
|
||||
assert.Nil(t, err)
|
||||
|
||||
app, err := processor.Get("updateresources_1224")
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, "running", app.State)
|
||||
assert.Equal(t, float64(1000), app.CPUUsage)
|
||||
assert.Equal(t, 256, app.MemoryUsage)
|
||||
assert.Equal(t, 100, app.DiskUsageBytes)
|
||||
assert.Equal(t, 200, app.DiskUsageInodes)
|
||||
assert.Contains(t, app.Flags, "test")
|
||||
}
|
||||
|
||||
func TestAppsProcessorUpdateState(t *testing.T) {
|
||||
processor := AppsProcessor{
|
||||
DB: testDB(),
|
||||
}
|
||||
processor.Init()
|
||||
|
||||
err := processor.New("update_1224", 1002, 1003, "testimage", 2, 256)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = processor.UpdateState("update_1224", "no-container")
|
||||
assert.Nil(t, err)
|
||||
|
||||
app, err := processor.Get("update_1224")
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, "no-container", app.State)
|
||||
}
|
||||
|
||||
func TestAppsProcessorAddLabel(t *testing.T) {
|
||||
processor := AppsProcessor{
|
||||
DB: testDB(),
|
||||
}
|
||||
processor.Init()
|
||||
|
||||
err := processor.New("label_1224", 1002, 1003, "testimage", 2, 256)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = processor.AddLabel("label_1224", "testlabel")
|
||||
assert.Nil(t, err)
|
||||
|
||||
app, err := processor.Get("label_1224")
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, "testlabel", app.Labels[0].Value)
|
||||
}
|
||||
|
||||
func TestAppsProcessorRemoveLabel(t *testing.T) {
|
||||
processor := AppsProcessor{
|
||||
DB: testDB(),
|
||||
}
|
||||
processor.Init()
|
||||
|
||||
err := processor.New("label_1223", 1002, 1003, "testimage", 2, 256)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = processor.AddLabel("label_1223", "testlabel")
|
||||
assert.Nil(t, err)
|
||||
|
||||
app, err := processor.Get("label_1223")
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, "testlabel", app.Labels[0].Value)
|
||||
|
||||
err = processor.RemoveLabel("label_1223", "testlabel")
|
||||
assert.Nil(t, err)
|
||||
|
||||
app, err = processor.Get("label_1223")
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, 0, len(app.Labels))
|
||||
}
|
||||
|
||||
func TestAppsProcessorDelete(t *testing.T) {
|
||||
processor := AppsProcessor{
|
||||
DB: testDB(),
|
||||
}
|
||||
processor.Init()
|
||||
|
||||
err := processor.New("testapp_5234", 1002, 1003, "testimage", 2, 256)
|
||||
assert.Nil(t, err)
|
||||
|
||||
app, err := processor.Get("testapp_5234")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 256, app.Memory)
|
||||
|
||||
err = processor.Delete("testapp_5234")
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = processor.Get("testapp_5234")
|
||||
assert.Error(t, err, "record not found")
|
||||
}
|
@ -305,7 +305,10 @@ func (s *SnapshotProcessor) ListAppsSnapshotsByLabel(labelValue string) ([]Snaps
|
||||
}
|
||||
|
||||
snapshot, err := s.metadataForSnapshotKey(key)
|
||||
if err != nil {
|
||||
if err != nil && strings.Contains(err.Error(), "wrong snapshot key format") {
|
||||
log.Printf("WARNING: Snapshot storage: invalid key found (%s)", key)
|
||||
continue
|
||||
} else if err != nil {
|
||||
return snapshots, err
|
||||
}
|
||||
|
||||
|
@ -276,14 +276,14 @@ func (c *Container) SetTechnology(tech string, version string) error {
|
||||
}
|
||||
|
||||
// GetProcessList returns list of processes managed by supervisor.
|
||||
func (c *Container) GetProcessList() (*[]Process, error) {
|
||||
func (c *Container) GetProcessList() ([]Process, error) {
|
||||
driver := c.getDriver()
|
||||
|
||||
processes := []Process{}
|
||||
|
||||
stdouterr, err := driver.Exec(c.App.Name, []string{"supervisorctl", "status"}, "", []string{}, true)
|
||||
if err != nil {
|
||||
return &processes, nil
|
||||
return processes, nil
|
||||
}
|
||||
|
||||
trimmed := strings.TrimSpace(string(*stdouterr))
|
||||
@ -297,7 +297,7 @@ func (c *Container) GetProcessList() (*[]Process, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return &processes, nil
|
||||
return processes, nil
|
||||
}
|
||||
|
||||
// GetSystemProcesses return list of running system processes
|
||||
|
652
glue/main.go
Normal file
652
glue/main.go
Normal file
@ -0,0 +1,652 @@
|
||||
package glue
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/rosti-cz/node-api/apps"
|
||||
"github.com/rosti-cz/node-api/containers"
|
||||
docker "github.com/rosti-cz/node-api/containers"
|
||||
"github.com/rosti-cz/node-api/detector"
|
||||
"github.com/rosti-cz/node-api/node"
|
||||
)
|
||||
|
||||
// Processor separates logic of apps, containers, detector and node from handlers.
|
||||
// It defines common interface for both types of handlers, HTTP and the events.
|
||||
type Processor struct {
|
||||
AppName string
|
||||
DB *gorm.DB
|
||||
SnapshotProcessor *apps.SnapshotProcessor
|
||||
WaitForAppLoops uint // each loop is five seconds
|
||||
}
|
||||
|
||||
// Return prepared Container instance
|
||||
func (p *Processor) getContainer() (containers.Container, error) {
|
||||
container := containers.Container{}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: p.DB,
|
||||
}
|
||||
app, err := processor.Get(p.AppName)
|
||||
if err != nil {
|
||||
return container, err
|
||||
}
|
||||
|
||||
container = docker.Container{
|
||||
App: &app,
|
||||
}
|
||||
|
||||
return container, nil
|
||||
}
|
||||
|
||||
// returns instance of getAppProcessor
|
||||
func (p *Processor) getAppProcessor() apps.AppsProcessor {
|
||||
return apps.AppsProcessor{
|
||||
DB: p.DB,
|
||||
}
|
||||
}
|
||||
|
||||
// waits until app is ready
|
||||
func (p *Processor) waitForApp() error {
|
||||
sleepFor := 5 * time.Second
|
||||
loops := 6
|
||||
if p.WaitForAppLoops != 0 {
|
||||
loops = int(p.WaitForAppLoops)
|
||||
}
|
||||
|
||||
for i := 0; i < loops; i++ {
|
||||
err := updateState(p.AppName)
|
||||
if err != nil {
|
||||
time.Sleep(sleepFor)
|
||||
continue
|
||||
}
|
||||
|
||||
container, err := p.getContainer()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status == "running" {
|
||||
return nil
|
||||
}
|
||||
|
||||
time.Sleep(sleepFor)
|
||||
}
|
||||
|
||||
return errors.New("timeout reached")
|
||||
}
|
||||
|
||||
// List returns list of apps
|
||||
func (p *Processor) List() (apps.Apps, error) {
|
||||
appList := apps.Apps{}
|
||||
|
||||
err := gatherStates()
|
||||
if err != nil {
|
||||
return appList, fmt.Errorf("backend error: %v", err)
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: p.DB,
|
||||
}
|
||||
appList, err = processor.List()
|
||||
|
||||
if err != nil {
|
||||
return appList, fmt.Errorf("backend error: %v", err)
|
||||
}
|
||||
|
||||
return appList, err
|
||||
}
|
||||
|
||||
// Get returns one app
|
||||
func (p *Processor) Get() (apps.App, error) {
|
||||
app := apps.App{}
|
||||
|
||||
err := updateState(p.AppName)
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: p.DB,
|
||||
}
|
||||
app, err = processor.Get(p.AppName)
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
|
||||
// Gather runtime info about the container
|
||||
container := docker.Container{
|
||||
App: &app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
if status == "running" {
|
||||
var err error
|
||||
app.Techs, err = container.GetTechs()
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
app.PrimaryTech, err = container.GetPrimaryTech()
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
|
||||
processList, err := container.GetSystemProcesses()
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
|
||||
flags, err := detector.Check(processList)
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
app.Flags = flags.String()
|
||||
}
|
||||
|
||||
return app, nil
|
||||
}
|
||||
|
||||
// Create creates a single app in the system
|
||||
func (p *Processor) Create(appTemplate apps.App) error {
|
||||
err := p.Register(appTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: &appTemplate,
|
||||
}
|
||||
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Restore from snapshot if it's noted in the request
|
||||
if len(appTemplate.Snapshot) > 0 {
|
||||
log.Printf("App %s is going to be created from %s snapshot\n", appTemplate.Name, appTemplate.Snapshot)
|
||||
|
||||
// Restore the data
|
||||
err = p.SnapshotProcessor.RestoreSnapshot(appTemplate.Snapshot, appTemplate.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
return err
|
||||
}
|
||||
|
||||
// Register registers app without creating a container for it
|
||||
// Returns app name and an error
|
||||
func (p *Processor) Register(appTemplate apps.App) error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: p.DB,
|
||||
}
|
||||
err := processor.New(appTemplate.Name, appTemplate.SSHPort, appTemplate.HTTPPort, appTemplate.Image, appTemplate.CPU, appTemplate.Memory)
|
||||
if err != nil {
|
||||
if validationError, ok := err.(apps.ValidationError); ok {
|
||||
return fmt.Errorf("validation error: %v", validationError.Error())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update updates application
|
||||
func (p *Processor) Update(appTemplate apps.App) error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: p.DB,
|
||||
}
|
||||
app, err := processor.Update(appTemplate.Name, appTemplate.SSHPort, appTemplate.HTTPPort, appTemplate.Image, appTemplate.CPU, appTemplate.Memory)
|
||||
if err != nil {
|
||||
if validationError, ok := err.(apps.ValidationError); ok {
|
||||
return fmt.Errorf("validation error: %v", validationError.Error())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.Destroy()
|
||||
if err != nil && err.Error() == "no container found" {
|
||||
// We don't care if the container didn't exist anyway
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete removes app from the system
|
||||
func (p *Processor) Delete() error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: p.DB,
|
||||
}
|
||||
app, err := processor.Get(p.AppName)
|
||||
if err != nil {
|
||||
log.Println("ERROR: delete app:", err.Error())
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: &app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if status != "no-container" {
|
||||
// We stop the container first
|
||||
err = container.Stop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Then delete it
|
||||
err = container.Delete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = processor.Delete(app.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop stops app
|
||||
func (p *Processor) Stop() error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: p.DB,
|
||||
}
|
||||
app, err := processor.Get(p.AppName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: &app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Stop the container only when it exists
|
||||
if status != "no-container" {
|
||||
err = container.Stop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start starts app
|
||||
func (p *Processor) Start() error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: p.DB,
|
||||
}
|
||||
app, err := processor.Get(p.AppName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: &app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status == "no-container" {
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Restart restarts app
|
||||
func (p *Processor) Restart() error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: p.DB,
|
||||
}
|
||||
app, err := processor.Get(p.AppName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: &app,
|
||||
}
|
||||
|
||||
err = container.Restart()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateKeys uploads SSH keys into the container
|
||||
// keys parameters is just a string, one key per line
|
||||
func (p *Processor) UpdateKeys(keys string) error {
|
||||
err := p.waitForApp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container, err := p.getContainer()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.SetFileContent(sshPubKeysLocation, keys+"\n", "0600")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPassword sets up a new password to access the SSH user
|
||||
func (p *Processor) SetPassword(password string) error {
|
||||
err := p.waitForApp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container, err := p.getContainer()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.SetPassword(password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Processes returns list of supervisord processes
|
||||
func (p *Processor) Processes() ([]docker.Process, error) {
|
||||
container, err := p.getContainer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
processes, err := container.GetProcessList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return processes, nil
|
||||
}
|
||||
|
||||
// EnableTech sets up runtime for new tech or new version a tech
|
||||
func (p *Processor) EnableTech(service, version string) error {
|
||||
err := p.waitForApp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container, err := p.getContainer()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.SetTechnology(service, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rebuild recreates container for app
|
||||
func (p *Processor) Rebuild() error {
|
||||
container, err := p.getContainer()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.Destroy()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddLabel adds a label to the app
|
||||
func (p *Processor) AddLabel(label string) error {
|
||||
appProcessor := p.getAppProcessor()
|
||||
err := appProcessor.AddLabel(p.AppName, label)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveLabel removes a label from the app
|
||||
func (p *Processor) RemoveLabel(label string) error {
|
||||
appProcessor := p.getAppProcessor()
|
||||
err := appProcessor.RemoveLabel(p.AppName, label)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetNote returns node's info
|
||||
func (p *Processor) GetNode() (*node.Node, error) {
|
||||
node, err := node.GetNodeInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// CreateSnapshot creates a snapshot of given app
|
||||
func (p *Processor) CreateSnapshot(labels []string) error {
|
||||
_, err := p.SnapshotProcessor.CreateSnapshot(p.AppName, labels)
|
||||
return err
|
||||
}
|
||||
|
||||
// RestoreFromSnapshot restores app from given snapshot
|
||||
func (p *Processor) RestoreFromSnapshot(snapshotName string) error {
|
||||
container, err := p.getContainer()
|
||||
|
||||
// Stop the container
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Stop the container only when it exists
|
||||
if status != "no-container" {
|
||||
err = container.Stop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the data
|
||||
err = p.SnapshotProcessor.RestoreSnapshot(snapshotName, p.AppName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Start the container
|
||||
status, err = container.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status == "no-container" {
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListSnapshots returns list of snapshots
|
||||
func (p *Processor) ListSnapshots() (SnapshotsMetadata, error) {
|
||||
snapshots, err := p.SnapshotProcessor.ListAppSnapshots(p.AppName)
|
||||
if err != nil {
|
||||
return SnapshotsMetadata{}, err
|
||||
}
|
||||
|
||||
var output SnapshotsMetadata
|
||||
for _, snapshot := range snapshots {
|
||||
output = append(output, SnapshotMetadata{
|
||||
Key: snapshot.KeyName(p.SnapshotProcessor.IndexLabel),
|
||||
Metadata: snapshot,
|
||||
})
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// ListAppsSnapshots returns list of snapshots for given app list
|
||||
func (p *Processor) ListAppsSnapshots(appNames []string) (SnapshotsMetadata, error) {
|
||||
snapshots, err := p.SnapshotProcessor.ListAppsSnapshots(appNames)
|
||||
if err != nil {
|
||||
return SnapshotsMetadata{}, err
|
||||
}
|
||||
|
||||
var output SnapshotsMetadata
|
||||
for _, snapshot := range snapshots {
|
||||
output = append(output, SnapshotMetadata{
|
||||
Key: snapshot.KeyName(p.SnapshotProcessor.IndexLabel),
|
||||
Metadata: snapshot,
|
||||
})
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// ListSnapshotsByLabel returns list of snapshots by given label
|
||||
func (p *Processor) ListSnapshotsByLabel(label string) (SnapshotsMetadata, error) {
|
||||
snapshots, err := p.SnapshotProcessor.ListAppsSnapshotsByLabel(label)
|
||||
if err != nil {
|
||||
return SnapshotsMetadata{}, err
|
||||
}
|
||||
|
||||
var output SnapshotsMetadata
|
||||
for _, snapshot := range snapshots {
|
||||
output = append(output, SnapshotMetadata{
|
||||
Key: snapshot.KeyName(p.SnapshotProcessor.IndexLabel),
|
||||
Metadata: snapshot,
|
||||
})
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// GetSnapshot returns info about a single snapshot
|
||||
func (p *Processor) GetSnapshot(snapshotName string) (SnapshotMetadata, error) {
|
||||
snapshot, err := p.SnapshotProcessor.GetSnapshot(snapshotName)
|
||||
if err != nil {
|
||||
return SnapshotMetadata{}, err
|
||||
}
|
||||
output := SnapshotMetadata{
|
||||
Key: snapshot.KeyName(p.SnapshotProcessor.IndexLabel),
|
||||
Metadata: snapshot,
|
||||
}
|
||||
|
||||
return output, nil
|
||||
|
||||
}
|
||||
|
||||
// GetSnapshotDownloadLink return download link for a snapshot
|
||||
func (p *Processor) GetSnapshotDownloadLink(snapshotName string) (string, error) {
|
||||
link, err := p.SnapshotProcessor.GetDownloadLink(snapshotName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
// DeleteSnapshot deletes a snapshot
|
||||
func (p *Processor) DeleteSnapshot(snapshotName string) error {
|
||||
err := p.SnapshotProcessor.DeleteSnapshot(snapshotName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteAppSnapshots deletes all snapshot of given app
|
||||
func (p *Processor) DeleteAppSnapshots() error {
|
||||
err := p.SnapshotProcessor.DeleteAppSnapshots(p.AppName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package glue
|
||||
|
||||
import (
|
||||
"log"
|
||||
@ -20,7 +20,7 @@ func updateUsage(name string) error {
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
App: &app,
|
||||
}
|
||||
|
||||
state, err := container.GetState()
|
||||
@ -52,7 +52,7 @@ func updateState(name string) error {
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
App: &app,
|
||||
}
|
||||
state, err := container.Status()
|
||||
if err != nil {
|
||||
@ -76,7 +76,7 @@ func gatherStats() error {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, app := range *appList {
|
||||
for _, app := range appList {
|
||||
err := updateUsage(app.Name)
|
||||
if err != nil {
|
||||
log.Println("STATS ERROR:", err.Error())
|
||||
@ -96,7 +96,7 @@ func gatherStates() error {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, app := range *appList {
|
||||
for _, app := range appList {
|
||||
err := updateState(app.Name)
|
||||
if err != nil {
|
||||
log.Println("STATE ERROR:", err.Error())
|
15
glue/types.go
Normal file
15
glue/types.go
Normal file
@ -0,0 +1,15 @@
|
||||
package glue
|
||||
|
||||
import "github.com/rosti-cz/node-api/apps"
|
||||
|
||||
// Path where authorized keys are
|
||||
const sshPubKeysLocation = "/srv/.ssh/authorized_keys"
|
||||
|
||||
// SnapshotMetadata is snapshot structure encapsulation that combines key and metadata about the snapshot
|
||||
type SnapshotMetadata struct {
|
||||
Key string `json:"key"`
|
||||
Metadata apps.Snapshot `json:"metadata"`
|
||||
}
|
||||
|
||||
// SnapshotsMetadata is returned by handlers
|
||||
type SnapshotsMetadata []SnapshotMetadata
|
1
go.mod
1
go.mod
@ -13,6 +13,7 @@ require (
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/jinzhu/gorm v1.9.14
|
||||
github.com/jinzhu/now v1.1.4 // indirect
|
||||
github.com/kelseyhightower/envconfig v1.4.0
|
||||
github.com/labstack/echo v3.3.10+incompatible
|
||||
github.com/labstack/gommon v0.3.0 // indirect
|
||||
|
3
go.sum
3
go.sum
@ -422,8 +422,9 @@ github.com/jinzhu/gorm v1.9.14 h1:Kg3ShyTPcM6nzVo148fRrcMO6MNKuqtOUwnzqMgVniM=
|
||||
github.com/jinzhu/gorm v1.9.14/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
|
||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||
|
377
handlers.go
377
handlers.go
@ -6,12 +6,12 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/rosti-cz/node-api/apps"
|
||||
"github.com/rosti-cz/node-api/common"
|
||||
docker "github.com/rosti-cz/node-api/containers"
|
||||
"github.com/rosti-cz/node-api/node"
|
||||
"github.com/rosti-cz/node-api/glue"
|
||||
)
|
||||
|
||||
func homeHandler(c echo.Context) error {
|
||||
@ -21,16 +21,11 @@ func homeHandler(c echo.Context) error {
|
||||
}
|
||||
|
||||
func listAppsHandler(c echo.Context) error {
|
||||
err := gatherStates()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
processor := glue.Processor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
applications, err := processor.List()
|
||||
|
||||
applications, err := processor.List()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -42,15 +37,11 @@ func listAppsHandler(c echo.Context) error {
|
||||
func getAppHandler(c echo.Context) error {
|
||||
name := c.Param("name")
|
||||
|
||||
err := updateState(name)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(name)
|
||||
app, err := processor.Get()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -63,35 +54,29 @@ func getAppHandler(c echo.Context) error {
|
||||
func createAppHandler(c echo.Context) error {
|
||||
registerOnly := c.QueryParam("register_only") == "1"
|
||||
|
||||
app := apps.App{}
|
||||
err := c.Bind(&app)
|
||||
appTemplate := apps.App{}
|
||||
err := c.Bind(&appTemplate)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
err = processor.New(app.Name, app.SSHPort, app.HTTPPort, app.Image, app.CPU, app.Memory)
|
||||
if err != nil {
|
||||
if validationError, ok := err.(apps.ValidationError); ok {
|
||||
return c.JSONPretty(http.StatusBadRequest, Message{Errors: validationError.Errors}, JSONIndent)
|
||||
}
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
processor := glue.Processor{
|
||||
AppName: appTemplate.Name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
|
||||
if !registerOnly {
|
||||
container := docker.Container{
|
||||
App: &app,
|
||||
}
|
||||
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
if registerOnly {
|
||||
err = processor.Register(appTemplate)
|
||||
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||
return c.JSONPretty(http.StatusBadRequest, Message{Errors: []string{err.Error()}}, JSONIndent)
|
||||
} else if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
if err != nil {
|
||||
} else {
|
||||
err = processor.Create(appTemplate)
|
||||
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||
return c.JSONPretty(http.StatusBadRequest, Message{Errors: []string{err.Error()}}, JSONIndent)
|
||||
} else if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
}
|
||||
@ -103,45 +88,20 @@ func createAppHandler(c echo.Context) error {
|
||||
func updateAppHandler(c echo.Context) error {
|
||||
name := c.Param("name")
|
||||
|
||||
app := apps.App{}
|
||||
err := c.Bind(&app)
|
||||
appTemplate := apps.App{}
|
||||
err := c.Bind(&appTemplate)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
appPointer, err := processor.Update(name, app.SSHPort, app.HTTPPort, app.Image, app.CPU, app.Memory)
|
||||
if err != nil {
|
||||
if validationError, ok := err.(apps.ValidationError); ok {
|
||||
return c.JSONPretty(http.StatusBadRequest, Message{Errors: validationError.Errors}, JSONIndent)
|
||||
}
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
app = *appPointer
|
||||
|
||||
container := docker.Container{
|
||||
App: &app,
|
||||
}
|
||||
|
||||
err = container.Destroy()
|
||||
if err != nil && err.Error() == "no container found" {
|
||||
// We don't care if the container didn't exist anyway
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
if err != nil {
|
||||
err = processor.Update(appTemplate)
|
||||
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||
return c.JSONPretty(http.StatusBadRequest, Message{Errors: []string{err.Error()}}, JSONIndent)
|
||||
} else if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
@ -152,31 +112,15 @@ func updateAppHandler(c echo.Context) error {
|
||||
func stopAppHandler(c echo.Context) error {
|
||||
name := c.Param("name")
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(name)
|
||||
err := processor.Stop()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
// Stop the container only when it exists
|
||||
if status != "no-container" {
|
||||
err = container.Stop()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, Message{Message: "ok"})
|
||||
}
|
||||
|
||||
@ -184,30 +128,11 @@ func stopAppHandler(c echo.Context) error {
|
||||
func startAppHandler(c echo.Context) error {
|
||||
name := c.Param("name")
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(name)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status == "no-container" {
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
err := processor.Start()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -219,19 +144,11 @@ func startAppHandler(c echo.Context) error {
|
||||
func restartAppHandler(c echo.Context) error {
|
||||
name := c.Param("name")
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(name)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.Restart()
|
||||
err := processor.Restart()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -249,19 +166,11 @@ func setPasswordHandler(c echo.Context) error {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(name)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.SetPassword(password.Password)
|
||||
err = processor.SetPassword(password.Password)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -278,19 +187,11 @@ func setKeysHandler(c echo.Context) error {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(name)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.SetFileContent(sshPubKeysLocation, string(body)+"\n", "0600")
|
||||
err = processor.UpdateKeys(string(body) + "\n")
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -301,73 +202,22 @@ func setKeysHandler(c echo.Context) error {
|
||||
func setServicesHandler(c echo.Context) error {
|
||||
name := c.Param("name")
|
||||
|
||||
quickServices := &QuickServices{}
|
||||
err := c.Bind(quickServices)
|
||||
tech := &Technology{}
|
||||
err := c.Bind(tech)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(name)
|
||||
|
||||
err = processor.EnableTech(tech.Name, tech.Version)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
if quickServices.Python {
|
||||
err = container.SetTechnology("python", "")
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
}
|
||||
|
||||
if quickServices.PHP {
|
||||
err = container.SetTechnology("php", "")
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
}
|
||||
|
||||
if quickServices.Node {
|
||||
err = container.SetTechnology("node", "")
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
}
|
||||
|
||||
if quickServices.Ruby {
|
||||
err = container.SetTechnology("ruby", "")
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
}
|
||||
|
||||
if quickServices.Deno {
|
||||
err = container.SetTechnology("deno", "")
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
}
|
||||
|
||||
if quickServices.Memcached {
|
||||
err = container.SetTechnology("memcached", "")
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
}
|
||||
|
||||
if quickServices.Redis {
|
||||
err = container.SetTechnology("redis", "")
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, Message{Message: "ok"})
|
||||
}
|
||||
|
||||
@ -375,33 +225,11 @@ func setServicesHandler(c echo.Context) error {
|
||||
func rebuildAppHandler(c echo.Context) error {
|
||||
name := c.Param("name")
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(name)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.Destroy()
|
||||
if err != nil && err.Error() == "no container found" {
|
||||
// We don't care if the container didn't exist anyway
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
err := processor.Rebuild()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -419,10 +247,11 @@ func addLabelHandler(c echo.Context) error {
|
||||
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
err = processor.AddLabel(name, label.Value)
|
||||
err = processor.AddLabel(label.Value)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -440,10 +269,11 @@ func deleteLabelHandler(c echo.Context) error {
|
||||
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
err = processor.RemoveLabel(name, label.Value)
|
||||
err = processor.RemoveLabel(label.Value)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -456,36 +286,16 @@ func deleteLabelHandler(c echo.Context) error {
|
||||
func deleteAppHandler(c echo.Context) error {
|
||||
name := c.Param("name")
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(name)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
go func(app *apps.App) {
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
go func(name string) {
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
err := processor.Delete()
|
||||
if err != nil {
|
||||
log.Println("ERROR delete application problem: " + err.Error())
|
||||
|
||||
log.Printf("Deletion of application failed: %v", err)
|
||||
}
|
||||
if status != "no-container" {
|
||||
err = container.Delete()
|
||||
if err != nil {
|
||||
log.Println("ERROR delete application problem: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
err = processor.Delete(app.Name)
|
||||
if err != nil {
|
||||
log.Println("ERROR delete application problem: " + err.Error())
|
||||
}
|
||||
}(app)
|
||||
}(name)
|
||||
|
||||
return c.JSON(http.StatusOK, Message{Message: "deleted"})
|
||||
}
|
||||
@ -497,7 +307,10 @@ func getOrphansHander(c echo.Context) error {
|
||||
|
||||
// Return info about the node including performance index
|
||||
func getNodeInfoHandler(c echo.Context) error {
|
||||
node, err := node.GetNodeInfo()
|
||||
processor := glue.Processor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
node, err := processor.GetNode()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -509,19 +322,11 @@ func getNodeInfoHandler(c echo.Context) error {
|
||||
func getAppProcessesHandler(c echo.Context) error {
|
||||
name := c.Param("name")
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: name,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(name)
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
processes, err := container.GetProcessList()
|
||||
processes, err := processor.Processes()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -534,7 +339,10 @@ func metricsHandler(c echo.Context) error {
|
||||
var metrics string
|
||||
|
||||
// Node indexes
|
||||
node, err := node.GetNodeInfo()
|
||||
processor := glue.Processor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
node, err := processor.GetNode()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
@ -552,15 +360,12 @@ func metricsHandler(c echo.Context) error {
|
||||
metrics += fmt.Sprintf("rosti_node_memory_index{hostname=\"%s\"} %f\n", hostname, node.MemoryIndex)
|
||||
metrics += fmt.Sprintf("rosti_node_sold_memory{hostname=\"%s\"} %d\n", hostname, node.SoldMemory)
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
apps, err := processor.List()
|
||||
if err != nil {
|
||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||
}
|
||||
|
||||
for _, app := range *apps {
|
||||
for _, app := range apps {
|
||||
metrics += fmt.Sprintf("rosti_node_app_disk_usage_bytes{hostname=\"%s\", app=\"%s\"} %d\n", hostname, app.Name, app.DiskUsageBytes)
|
||||
metrics += fmt.Sprintf("rosti_node_app_disk_usage_inodes{hostname=\"%s\", app=\"%s\"} %d\n", hostname, app.Name, app.DiskUsageInodes)
|
||||
}
|
||||
|
670
handlers_nats.go
670
handlers_nats.go
@ -22,9 +22,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rosti-cz/node-api/apps"
|
||||
"github.com/rosti-cz/node-api/common"
|
||||
docker "github.com/rosti-cz/node-api/containers"
|
||||
"github.com/rosti-cz/node-api/detector"
|
||||
"github.com/rosti-cz/node-api/node"
|
||||
"github.com/rosti-cz/node-api/glue"
|
||||
)
|
||||
|
||||
// This handler only passes messages to another function for easier testing
|
||||
@ -59,7 +57,7 @@ func _messageHandler(m *nats.Msg) error {
|
||||
"add_label": addLabelEventHandler,
|
||||
"remove_label": removeLabelEventHandler,
|
||||
"list_orphans": listOrphansEventHandler,
|
||||
"node": getNoteEventHandler,
|
||||
"node": getNodeEventHandler,
|
||||
"create_snapshot": createSnapshotEventHandler,
|
||||
"restore_from_snapshot": restoreFromSnapshotEventHandler,
|
||||
"list_snapshots": listSnapshotsEventHandler,
|
||||
@ -94,17 +92,12 @@ func _messageHandler(m *nats.Msg) error {
|
||||
func listEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
log.Println("> List")
|
||||
|
||||
err := gatherStates()
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
processor.Init()
|
||||
applications, err := processor.List()
|
||||
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
@ -128,56 +121,15 @@ func listEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
|
||||
// Returns one app
|
||||
func getEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
|
||||
err := updateState(message.AppName)
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
processor := glue.Processor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
|
||||
// Gather runtime info about the container
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
app, err := processor.Get()
|
||||
if err != nil {
|
||||
log.Printf("backend error: %v\n", err)
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
if status == "running" {
|
||||
var err error
|
||||
app.Techs, err = container.GetTechs()
|
||||
if err != nil {
|
||||
log.Printf("backend error: %v\n", err)
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
app.PrimaryTech, err = container.GetPrimaryTech()
|
||||
if err != nil {
|
||||
log.Printf("backend error: %v\n", err)
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
|
||||
processList, err := container.GetSystemProcesses()
|
||||
if err != nil {
|
||||
log.Printf("backend error: %v\n", err)
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
|
||||
flags, err := detector.Check(processList)
|
||||
if err != nil {
|
||||
log.Printf("backend error: %v\n", err)
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
app.Flags = flags.String()
|
||||
}
|
||||
|
||||
// Assembling reply message
|
||||
reply := ReplyMessage{
|
||||
@ -200,7 +152,6 @@ func getEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
|
||||
// Create a new app
|
||||
func createEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
|
||||
appTemplate := apps.App{}
|
||||
body := []byte(message.Payload)
|
||||
err := json.Unmarshal(body, &appTemplate)
|
||||
@ -210,48 +161,17 @@ func createEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
return err
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
err = processor.New(message.AppName, appTemplate.SSHPort, appTemplate.HTTPPort, appTemplate.Image, appTemplate.CPU, appTemplate.Memory)
|
||||
if err != nil {
|
||||
if validationError, ok := err.(apps.ValidationError); ok {
|
||||
log.Println("ERROR create application problem (validation problem): " + validationError.Error())
|
||||
publish(message.AppName, "validation problem", true)
|
||||
return err
|
||||
}
|
||||
log.Println("ERROR create application problem (processor.New): " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
err = processor.Create(appTemplate)
|
||||
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||
publish(message.AppName, "validation error", true)
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: &appTemplate,
|
||||
}
|
||||
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
log.Println("ERROR create application problem (container.Create): " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
// Restore from snapshot if it's noted in the request
|
||||
if len(appTemplate.Snapshot) > 0 {
|
||||
log.Printf("App %s is going to be created from %s snapshot\n", message.AppName, appTemplate.Snapshot)
|
||||
|
||||
// Restore the data
|
||||
err = snapshotProcessor.RestoreSnapshot(appTemplate.Snapshot, message.AppName)
|
||||
if err != nil {
|
||||
log.Println("ERROR restore snapshot error: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
if err != nil {
|
||||
log.Println("ERROR create application problem (container.Start): " + err.Error())
|
||||
} else if err != nil {
|
||||
log.Println("ERROR create application problem: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
@ -273,17 +193,17 @@ func registerEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
return err
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
err = processor.New(message.AppName, appTemplate.SSHPort, appTemplate.HTTPPort, appTemplate.Image, appTemplate.CPU, appTemplate.Memory)
|
||||
if err != nil {
|
||||
if validationError, ok := err.(apps.ValidationError); ok {
|
||||
log.Println("ERROR create application problem (validation): " + validationError.Error())
|
||||
publish(message.AppName, "validation problem", true)
|
||||
return err
|
||||
}
|
||||
log.Println("ERROR create application problem (processor.New): " + err.Error())
|
||||
err = processor.Create(appTemplate)
|
||||
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||
publish(message.AppName, "validation error", true)
|
||||
return err
|
||||
} else if err != nil {
|
||||
log.Println("ERROR create application problem: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
@ -304,306 +224,155 @@ func updateEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
return err
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
app, err := processor.Update(message.AppName, appTemplate.SSHPort, appTemplate.HTTPPort, appTemplate.Image, appTemplate.CPU, appTemplate.Memory)
|
||||
if err != nil {
|
||||
if validationError, ok := err.(apps.ValidationError); ok {
|
||||
log.Println("ERROR update application problem: " + validationError.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
log.Println("ERROR update application problem: " + err.Error())
|
||||
err = processor.Update(appTemplate)
|
||||
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||
publish(message.AppName, "validation error", true)
|
||||
return err
|
||||
} else if err != nil {
|
||||
log.Println("ERROR create application problem: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.Destroy()
|
||||
if err != nil && err.Error() == "no container found" {
|
||||
// We don't care if the container didn't exist anyway
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
log.Println("ERROR update application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
log.Println("ERROR update application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
if err != nil {
|
||||
log.Println("ERROR update application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
publish(app.Name, "updated", false)
|
||||
publish(message.AppName, "updated", false)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete one app
|
||||
func deleteEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
if err != nil {
|
||||
log.Println("ERROR: delete app:", err.Error())
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
err := processor.Delete()
|
||||
if err != nil {
|
||||
log.Println("ERROR delete application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
if status != "no-container" {
|
||||
// We stop the container first
|
||||
err = container.Stop()
|
||||
if err != nil {
|
||||
log.Println("ERROR delete application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
// Then delete it
|
||||
err = container.Delete()
|
||||
if err != nil {
|
||||
log.Println("ERROR delete application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = processor.Delete(app.Name)
|
||||
if err != nil {
|
||||
log.Println("ERROR delete application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
publish(app.Name, "deleted", false)
|
||||
publish(message.AppName, "deleted", false)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop existing app
|
||||
func stopEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
err := processor.Stop()
|
||||
if err != nil {
|
||||
log.Println("ERROR stop application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
log.Println("ERROR stop application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
// Stop the container only when it exists
|
||||
if status != "no-container" {
|
||||
err = container.Stop()
|
||||
if err != nil {
|
||||
log.Println("ERROR stop application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
publish(app.Name, "stopped", false)
|
||||
publish(message.AppName, "stopped", false)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start existing app
|
||||
func startEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
err := processor.Start()
|
||||
if err != nil {
|
||||
log.Println("ERROR start application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status == "no-container" {
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
log.Println("ERROR start application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
if err != nil {
|
||||
log.Println("ERROR start application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
publish(app.Name, "started", false)
|
||||
publish(message.AppName, "started", false)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Restart existing app
|
||||
func restartEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
err := processor.Restart()
|
||||
if err != nil {
|
||||
log.Println("ERROR restart application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.Restart()
|
||||
if err != nil {
|
||||
log.Println("ERROR restart application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
publish(app.Name, "restarted", false)
|
||||
publish(message.AppName, "restarted", false)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Copies body of the request into /srv/.ssh/authorized_keys
|
||||
func updateKeysEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
err := waitForApp(message.AppName)
|
||||
body := message.Payload
|
||||
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
err := processor.UpdateKeys(body)
|
||||
if err != nil {
|
||||
log.Println("ERROR enable tech problem: " + err.Error())
|
||||
log.Println("ERROR update keys problem: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
body := message.Payload
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
if err != nil {
|
||||
log.Println("ERROR keys update problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.SetFileContent(sshPubKeysLocation, body+"\n", "0600")
|
||||
if err != nil {
|
||||
log.Println("ERROR keys update problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
publish(app.Name, "keys updated", false)
|
||||
publish(message.AppName, "keys updated", false)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set password for the app user in the container
|
||||
func setPasswordEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
err := waitForApp(message.AppName)
|
||||
password := message.Payload
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
err := processor.SetPassword(password)
|
||||
|
||||
if err != nil {
|
||||
log.Println("ERROR enable tech problem: " + err.Error())
|
||||
log.Println("ERROR password update problem: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
password := message.Payload
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
if err != nil {
|
||||
log.Println("ERROR password update problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.SetPassword(password)
|
||||
if err != nil {
|
||||
log.Println("ERROR password update problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
publish(app.Name, "password updated", false)
|
||||
publish(message.AppName, "password updated", false)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Application processes
|
||||
func processesEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
if err != nil {
|
||||
log.Println("ERROR processes list problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
processes, err := container.GetProcessList()
|
||||
processes, err := processor.Processes()
|
||||
if err != nil {
|
||||
log.Println("ERROR processes list problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -614,7 +383,7 @@ func processesEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
data, err := json.Marshal(reply)
|
||||
if err != nil {
|
||||
log.Println("ERROR processes list problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
err = m.Respond(data)
|
||||
@ -653,81 +422,39 @@ func enableTechEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
version = parts[1]
|
||||
}
|
||||
|
||||
err = waitForApp(message.AppName)
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
processor.EnableTech(service, version)
|
||||
if err != nil {
|
||||
log.Println("ERROR enable tech problem: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
if err != nil {
|
||||
log.Println("ERROR enable tech problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.SetTechnology(service, version)
|
||||
if err != nil {
|
||||
log.Println("ERROR enable tech problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
publish(app.Name, "tech updated", false)
|
||||
publish(message.AppName, "tech updated", false)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rebuilds existing app, it keeps the data but creates the container again
|
||||
func rebuildEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
|
||||
err := processor.Rebuild()
|
||||
if err != nil {
|
||||
log.Println("ERROR rebuild app problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
err = container.Destroy()
|
||||
if err != nil && err.Error() == "no container found" {
|
||||
// We don't care if the container didn't exist anyway
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
log.Println("ERROR rebuild app problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
log.Println("ERROR rebuild app problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
if err != nil {
|
||||
log.Println("ERROR rebuild app problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
publish(app.Name, "app rebuild", false)
|
||||
publish(message.AppName, "app rebuild", false)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -736,10 +463,12 @@ func rebuildEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
func addLabelEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
label := message.Payload
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
err := processor.AddLabel(message.AppName, label)
|
||||
err := processor.AddLabel(label)
|
||||
if err != nil {
|
||||
log.Println("ERROR add label problem: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
@ -755,10 +484,12 @@ func addLabelEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
func removeLabelEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
label := message.Payload
|
||||
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
err := processor.RemoveLabel(message.AppName, label)
|
||||
err := processor.RemoveLabel(label)
|
||||
if err != nil {
|
||||
log.Println("ERROR remove label problem: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
@ -793,12 +524,18 @@ func listOrphansEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
}
|
||||
|
||||
/*
|
||||
getNoteEventHandler returns info about the node including performance index
|
||||
getNodeEventHandler returns info about the node including performance index
|
||||
|
||||
|
||||
*/
|
||||
func getNoteEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
node, err := node.GetNodeInfo()
|
||||
func getNodeEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
|
||||
node, err := processor.GetNode()
|
||||
if err != nil {
|
||||
log.Println("ERROR performance index problem: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
@ -834,7 +571,13 @@ Payload: no payload needed
|
||||
Response: notification when it's done or error
|
||||
*/
|
||||
func createSnapshotEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
_, err := snapshotProcessor.CreateSnapshot(message.AppName, strings.Split(message.Payload, ","))
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
|
||||
err := processor.CreateSnapshot(strings.Split(message.Payload, ","))
|
||||
if err != nil {
|
||||
log.Println("ERROR create snapshot error: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
@ -858,64 +601,16 @@ Payload: string with the snapshot name
|
||||
Response: notification when it's done or error
|
||||
*/
|
||||
func restoreFromSnapshotEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
app, err := processor.Get(message.AppName)
|
||||
if err != nil {
|
||||
log.Println("ERROR restore snapshot problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
// Stop the container
|
||||
status, err := container.Status()
|
||||
if err != nil {
|
||||
log.Println("ERROR restore snapshot problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
// Stop the container only when it exists
|
||||
if status != "no-container" {
|
||||
err = container.Stop()
|
||||
if err != nil {
|
||||
log.Println("ERROR restore snapshot problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the data
|
||||
err = snapshotProcessor.RestoreSnapshot(message.Payload, message.AppName)
|
||||
if err != nil {
|
||||
log.Println("ERROR restore snapshot error: " + err.Error())
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
// Start the container
|
||||
status, err = container.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status == "no-container" {
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
log.Println("ERROR start application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = container.Start()
|
||||
err := processor.RestoreFromSnapshot(message.Payload)
|
||||
if err != nil {
|
||||
log.Println("ERROR start application problem: " + err.Error())
|
||||
publish(app.Name, "backend problem", true)
|
||||
publish(message.AppName, "backend problem", true)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -934,21 +629,18 @@ Payload: no payload needed
|
||||
Response: replies with list of snapshots or an error message
|
||||
*/
|
||||
func listSnapshotsEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
snapshots, err := snapshotProcessor.ListAppSnapshots(message.AppName)
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
snapshots, err := processor.ListSnapshots()
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
|
||||
var output SnapshotsMetadata
|
||||
for _, snapshot := range snapshots {
|
||||
output = append(output, SnapshotMetadata{
|
||||
Key: snapshot.KeyName(snapshotProcessor.IndexLabel),
|
||||
Metadata: snapshot,
|
||||
})
|
||||
}
|
||||
|
||||
reply := ReplyMessage{
|
||||
Payload: output,
|
||||
Payload: snapshots,
|
||||
}
|
||||
|
||||
data, err := json.Marshal(reply)
|
||||
@ -970,21 +662,18 @@ Payload: list of appNames separated by comma (no spaces)
|
||||
Response: replies with list of snapshots or an error message
|
||||
*/
|
||||
func listAppsSnapshotsEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
snapshots, err := snapshotProcessor.ListAppsSnapshots(strings.Split(message.Payload, ","))
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
snapshots, err := processor.ListAppsSnapshots(strings.Split(message.Payload, ","))
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
|
||||
var output SnapshotsMetadata
|
||||
for _, snapshot := range snapshots {
|
||||
output = append(output, SnapshotMetadata{
|
||||
Key: snapshot.KeyName(snapshotProcessor.IndexLabel),
|
||||
Metadata: snapshot,
|
||||
})
|
||||
}
|
||||
|
||||
reply := ReplyMessage{
|
||||
Payload: output,
|
||||
Payload: snapshots,
|
||||
}
|
||||
|
||||
data, err := json.Marshal(reply)
|
||||
@ -1006,21 +695,18 @@ Payload: snapshot label
|
||||
Response: replies with list of snapshots or an error message
|
||||
*/
|
||||
func listSnapshotsByLabelEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
snapshots, err := snapshotProcessor.ListAppsSnapshotsByLabel(message.Payload)
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
snapshots, err := processor.ListSnapshotsByLabel(message.Payload)
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
|
||||
var output SnapshotsMetadata
|
||||
for _, snapshot := range snapshots {
|
||||
output = append(output, SnapshotMetadata{
|
||||
Key: snapshot.KeyName(snapshotProcessor.IndexLabel),
|
||||
Metadata: snapshot,
|
||||
})
|
||||
}
|
||||
|
||||
reply := ReplyMessage{
|
||||
Payload: output,
|
||||
Payload: snapshots,
|
||||
}
|
||||
|
||||
data, err := json.Marshal(reply)
|
||||
@ -1042,16 +728,17 @@ Payload: snapshot's key
|
||||
Response: snapshot metadata
|
||||
*/
|
||||
func getSnapshotEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
snapshot, err := snapshotProcessor.GetSnapshot(message.Payload)
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
snapshot, err := processor.GetSnapshot(message.Payload)
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
output := SnapshotMetadata{
|
||||
Key: snapshot.KeyName(snapshotProcessor.IndexLabel),
|
||||
Metadata: snapshot,
|
||||
}
|
||||
|
||||
data, err := json.Marshal(output)
|
||||
data, err := json.Marshal(snapshot)
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "reply formatter error", err)
|
||||
}
|
||||
@ -1071,7 +758,12 @@ Payload: string with a snapshot name (key)
|
||||
Response: string with the URL
|
||||
*/
|
||||
func getSnapshotDownloadLinkEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
link, err := snapshotProcessor.GetDownloadLink(message.Payload)
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
link, err := processor.GetSnapshotDownloadLink(message.Payload)
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
@ -1100,7 +792,13 @@ Payload: string with a snapshot name
|
||||
Response: notification when it's done or error
|
||||
*/
|
||||
func deleteSnapshotEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
err := snapshotProcessor.DeleteSnapshot(message.Payload)
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
|
||||
err := processor.DeleteSnapshot(message.Payload)
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
@ -1119,7 +817,13 @@ Payload: no payload needed
|
||||
Response: notification when it's done or error
|
||||
*/
|
||||
func deleteAppSnapshotsEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||
err := snapshotProcessor.DeleteAppSnapshots(message.AppName)
|
||||
processor := glue.Processor{
|
||||
AppName: message.AppName,
|
||||
DB: common.GetDBConnection(),
|
||||
SnapshotProcessor: &snapshotProcessor,
|
||||
}
|
||||
|
||||
err := processor.DeleteAppSnapshots()
|
||||
if err != nil {
|
||||
return errorReplyFormater(m, "backend error", err)
|
||||
}
|
||||
|
26
main.go
26
main.go
@ -66,19 +66,19 @@ func main() {
|
||||
t := &Template{}
|
||||
|
||||
// Stats loop
|
||||
go func() {
|
||||
for {
|
||||
log.Println("Stats gathering started")
|
||||
start := time.Now()
|
||||
err := gatherStats()
|
||||
if err != nil {
|
||||
log.Println("LOOP ERROR:", err.Error())
|
||||
}
|
||||
elapsed := time.Since(start)
|
||||
log.Printf("Stats gathering elapsed time: %.2fs\n", elapsed.Seconds())
|
||||
time.Sleep(300 * time.Second)
|
||||
}
|
||||
}()
|
||||
// go func() {
|
||||
// for {
|
||||
// log.Println("Stats gathering started")
|
||||
// start := time.Now()
|
||||
// err := gatherStats()
|
||||
// if err != nil {
|
||||
// log.Println("LOOP ERROR:", err.Error())
|
||||
// }
|
||||
// elapsed := time.Since(start)
|
||||
// log.Printf("Stats gathering elapsed time: %.2fs\n", elapsed.Seconds())
|
||||
// time.Sleep(300 * time.Second)
|
||||
// }
|
||||
// }()
|
||||
|
||||
// Node stats
|
||||
go func() {
|
||||
|
45
tools.go
45
tools.go
@ -2,15 +2,10 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/rosti-cz/node-api/apps"
|
||||
"github.com/rosti-cz/node-api/common"
|
||||
docker "github.com/rosti-cz/node-api/containers"
|
||||
)
|
||||
|
||||
func errorReplyFormater(m *nats.Msg, message string, err error) error {
|
||||
@ -54,43 +49,3 @@ func publish(appName string, state string, isErr bool) {
|
||||
log.Println("ERROR: publish:", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// waitForApp waits until app is ready or timeout is reached.
|
||||
// It's used in some async calls that need at least part of the
|
||||
// environment prepared.
|
||||
func waitForApp(appName string) error {
|
||||
processor := apps.AppsProcessor{
|
||||
DB: common.GetDBConnection(),
|
||||
}
|
||||
|
||||
sleepFor := 5 * time.Second
|
||||
loops := 6
|
||||
|
||||
for i := 0; i < loops; i++ {
|
||||
err := updateState(appName)
|
||||
if err != nil {
|
||||
time.Sleep(sleepFor)
|
||||
continue
|
||||
}
|
||||
|
||||
app, err := processor.Get(appName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
App: app,
|
||||
}
|
||||
|
||||
status, err := container.Status()
|
||||
|
||||
if status == "running" {
|
||||
return nil
|
||||
}
|
||||
|
||||
time.Sleep(sleepFor)
|
||||
continue
|
||||
}
|
||||
|
||||
return errors.New("timeout reached")
|
||||
}
|
||||
|
16
types.go
16
types.go
@ -2,13 +2,8 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/rosti-cz/node-api/apps"
|
||||
)
|
||||
|
||||
// Path where authorized keys are
|
||||
const sshPubKeysLocation = "/srv/.ssh/authorized_keys"
|
||||
|
||||
// RequestMessage message
|
||||
type RequestMessage struct {
|
||||
AppName string `json:"name"`
|
||||
@ -65,11 +60,8 @@ type QuickServices struct {
|
||||
Redis bool `json:"redis"`
|
||||
}
|
||||
|
||||
// SnapshotMetadata is snapshot structure encapsulation that combines key and metadata about the snapshot
|
||||
type SnapshotMetadata struct {
|
||||
Key string `json:"key"`
|
||||
Metadata apps.Snapshot `json:"metadata"`
|
||||
// Set technology
|
||||
type Technology struct {
|
||||
Name string
|
||||
Version string
|
||||
}
|
||||
|
||||
// SnapshotsMetadata is returned by handlers
|
||||
type SnapshotsMetadata []SnapshotMetadata
|
||||
|
Loading…
Reference in New Issue
Block a user