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
|
// AppsProcessor encapsulates functions for apps manipulation
|
||||||
|
// This handles only the database part but not containers
|
||||||
type AppsProcessor struct {
|
type AppsProcessor struct {
|
||||||
DB *gorm.DB
|
DB *gorm.DB
|
||||||
}
|
}
|
||||||
@ -17,19 +18,19 @@ func (a *AppsProcessor) Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get returns one app
|
// Get returns one app
|
||||||
func (a *AppsProcessor) Get(name string) (*App, error) {
|
func (a *AppsProcessor) Get(name string) (App, error) {
|
||||||
var app App
|
var app App
|
||||||
|
|
||||||
err := a.DB.Preload("Labels").Where("name = ?", name).First(&app).Error
|
err := a.DB.Preload("Labels").Where("name = ?", name).First(&app).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return app, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &app, nil
|
return app, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns all apps located on this node
|
// List returns all apps located on this node
|
||||||
func (a *AppsProcessor) List() (*Apps, error) {
|
func (a *AppsProcessor) List() (Apps, error) {
|
||||||
var apps Apps
|
var apps Apps
|
||||||
|
|
||||||
err := a.DB.Preload("Labels").Find(&apps).Error
|
err := a.DB.Preload("Labels").Find(&apps).Error
|
||||||
@ -37,7 +38,7 @@ func (a *AppsProcessor) List() (*Apps, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &apps, nil
|
return apps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates new record about application in the database
|
// 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 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)
|
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
|
return snapshots, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,14 +276,14 @@ func (c *Container) SetTechnology(tech string, version string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetProcessList returns list of processes managed by supervisor.
|
// GetProcessList returns list of processes managed by supervisor.
|
||||||
func (c *Container) GetProcessList() (*[]Process, error) {
|
func (c *Container) GetProcessList() ([]Process, error) {
|
||||||
driver := c.getDriver()
|
driver := c.getDriver()
|
||||||
|
|
||||||
processes := []Process{}
|
processes := []Process{}
|
||||||
|
|
||||||
stdouterr, err := driver.Exec(c.App.Name, []string{"supervisorctl", "status"}, "", []string{}, true)
|
stdouterr, err := driver.Exec(c.App.Name, []string{"supervisorctl", "status"}, "", []string{}, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &processes, nil
|
return processes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
trimmed := strings.TrimSpace(string(*stdouterr))
|
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
|
// 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 (
|
import (
|
||||||
"log"
|
"log"
|
||||||
@ -20,7 +20,7 @@ func updateUsage(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
container := docker.Container{
|
container := docker.Container{
|
||||||
App: app,
|
App: &app,
|
||||||
}
|
}
|
||||||
|
|
||||||
state, err := container.GetState()
|
state, err := container.GetState()
|
||||||
@ -52,7 +52,7 @@ func updateState(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
container := docker.Container{
|
container := docker.Container{
|
||||||
App: app,
|
App: &app,
|
||||||
}
|
}
|
||||||
state, err := container.Status()
|
state, err := container.Status()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -76,7 +76,7 @@ func gatherStats() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, app := range *appList {
|
for _, app := range appList {
|
||||||
err := updateUsage(app.Name)
|
err := updateUsage(app.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("STATS ERROR:", err.Error())
|
log.Println("STATS ERROR:", err.Error())
|
||||||
@ -96,7 +96,7 @@ func gatherStates() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, app := range *appList {
|
for _, app := range appList {
|
||||||
err := updateState(app.Name)
|
err := updateState(app.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("STATE ERROR:", err.Error())
|
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/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/jinzhu/gorm v1.9.14
|
github.com/jinzhu/gorm v1.9.14
|
||||||
|
github.com/jinzhu/now v1.1.4 // indirect
|
||||||
github.com/kelseyhightower/envconfig v1.4.0
|
github.com/kelseyhightower/envconfig v1.4.0
|
||||||
github.com/labstack/echo v3.3.10+incompatible
|
github.com/labstack/echo v3.3.10+incompatible
|
||||||
github.com/labstack/gommon v0.3.0 // indirect
|
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/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 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
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.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-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/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=
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
|
377
handlers.go
377
handlers.go
@ -6,12 +6,12 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/labstack/echo"
|
"github.com/labstack/echo"
|
||||||
"github.com/rosti-cz/node-api/apps"
|
"github.com/rosti-cz/node-api/apps"
|
||||||
"github.com/rosti-cz/node-api/common"
|
"github.com/rosti-cz/node-api/common"
|
||||||
docker "github.com/rosti-cz/node-api/containers"
|
"github.com/rosti-cz/node-api/glue"
|
||||||
"github.com/rosti-cz/node-api/node"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func homeHandler(c echo.Context) error {
|
func homeHandler(c echo.Context) error {
|
||||||
@ -21,16 +21,11 @@ func homeHandler(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func listAppsHandler(c echo.Context) error {
|
func listAppsHandler(c echo.Context) error {
|
||||||
err := gatherStates()
|
processor := glue.Processor{
|
||||||
if err != nil {
|
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
|
||||||
}
|
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
|
||||||
DB: common.GetDBConnection(),
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
applications, err := processor.List()
|
|
||||||
|
|
||||||
|
applications, err := processor.List()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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 {
|
func getAppHandler(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
|
|
||||||
err := updateState(name)
|
processor := glue.Processor{
|
||||||
if err != nil {
|
AppName: name,
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
|
app, err := processor.Get()
|
||||||
processor := apps.AppsProcessor{
|
|
||||||
DB: common.GetDBConnection(),
|
|
||||||
}
|
|
||||||
app, err := processor.Get(name)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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 {
|
func createAppHandler(c echo.Context) error {
|
||||||
registerOnly := c.QueryParam("register_only") == "1"
|
registerOnly := c.QueryParam("register_only") == "1"
|
||||||
|
|
||||||
app := apps.App{}
|
appTemplate := apps.App{}
|
||||||
err := c.Bind(&app)
|
err := c.Bind(&appTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: appTemplate.Name,
|
||||||
}
|
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !registerOnly {
|
if registerOnly {
|
||||||
container := docker.Container{
|
err = processor.Register(appTemplate)
|
||||||
App: &app,
|
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||||
}
|
return c.JSONPretty(http.StatusBadRequest, Message{Errors: []string{err.Error()}}, JSONIndent)
|
||||||
|
} else if err != nil {
|
||||||
err = container.Create()
|
|
||||||
if err != nil {
|
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
err = container.Start()
|
err = processor.Create(appTemplate)
|
||||||
if err != nil {
|
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)
|
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 {
|
func updateAppHandler(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
|
|
||||||
app := apps.App{}
|
appTemplate := apps.App{}
|
||||||
err := c.Bind(&app)
|
err := c.Bind(&appTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
appPointer, err := processor.Update(name, app.SSHPort, app.HTTPPort, app.Image, app.CPU, app.Memory)
|
err = processor.Update(appTemplate)
|
||||||
if err != nil {
|
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||||
if validationError, ok := err.(apps.ValidationError); ok {
|
return c.JSONPretty(http.StatusBadRequest, Message{Errors: []string{err.Error()}}, JSONIndent)
|
||||||
return c.JSONPretty(http.StatusBadRequest, Message{Errors: validationError.Errors}, JSONIndent)
|
} else if err != nil {
|
||||||
}
|
|
||||||
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 {
|
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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 {
|
func stopAppHandler(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
app, err := processor.Get(name)
|
err := processor.Stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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"})
|
return c.JSON(http.StatusOK, Message{Message: "ok"})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,30 +128,11 @@ func stopAppHandler(c echo.Context) error {
|
|||||||
func startAppHandler(c echo.Context) error {
|
func startAppHandler(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
app, err := processor.Get(name)
|
err := processor.Start()
|
||||||
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()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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 {
|
func restartAppHandler(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
app, err := processor.Get(name)
|
err := processor.Restart()
|
||||||
if err != nil {
|
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
|
||||||
}
|
|
||||||
|
|
||||||
container := docker.Container{
|
|
||||||
App: app,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = container.Restart()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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)
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
app, err := processor.Get(name)
|
err = processor.SetPassword(password.Password)
|
||||||
if err != nil {
|
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
|
||||||
}
|
|
||||||
|
|
||||||
container := docker.Container{
|
|
||||||
App: app,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = container.SetPassword(password.Password)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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)
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
app, err := processor.Get(name)
|
err = processor.UpdateKeys(string(body) + "\n")
|
||||||
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")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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 {
|
func setServicesHandler(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
|
|
||||||
quickServices := &QuickServices{}
|
tech := &Technology{}
|
||||||
err := c.Bind(quickServices)
|
err := c.Bind(tech)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
app, err := processor.Get(name)
|
|
||||||
|
err = processor.EnableTech(tech.Name, tech.Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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"})
|
return c.JSON(http.StatusOK, Message{Message: "ok"})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,33 +225,11 @@ func setServicesHandler(c echo.Context) error {
|
|||||||
func rebuildAppHandler(c echo.Context) error {
|
func rebuildAppHandler(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
app, err := processor.Get(name)
|
err := processor.Rebuild()
|
||||||
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()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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)
|
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
err = processor.AddLabel(name, label.Value)
|
err = processor.AddLabel(label.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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)
|
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
err = processor.RemoveLabel(name, label.Value)
|
err = processor.RemoveLabel(label.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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 {
|
func deleteAppHandler(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
go func(name string) {
|
||||||
DB: common.GetDBConnection(),
|
processor := glue.Processor{
|
||||||
}
|
AppName: name,
|
||||||
app, err := processor.Get(name)
|
DB: common.GetDBConnection(),
|
||||||
if err != nil {
|
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func(app *apps.App) {
|
|
||||||
container := docker.Container{
|
|
||||||
App: app,
|
|
||||||
}
|
}
|
||||||
|
err := processor.Delete()
|
||||||
status, err := container.Status()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR delete application problem: " + err.Error())
|
log.Printf("Deletion of application failed: %v", err)
|
||||||
|
|
||||||
}
|
}
|
||||||
if status != "no-container" {
|
}(name)
|
||||||
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)
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, Message{Message: "deleted"})
|
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
|
// Return info about the node including performance index
|
||||||
func getNodeInfoHandler(c echo.Context) error {
|
func getNodeInfoHandler(c echo.Context) error {
|
||||||
node, err := node.GetNodeInfo()
|
processor := glue.Processor{
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
}
|
||||||
|
node, err := processor.GetNode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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 {
|
func getAppProcessesHandler(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
app, err := processor.Get(name)
|
processes, err := processor.Processes()
|
||||||
if err != nil {
|
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
|
||||||
}
|
|
||||||
|
|
||||||
container := docker.Container{
|
|
||||||
App: app,
|
|
||||||
}
|
|
||||||
|
|
||||||
processes, err := container.GetProcessList()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
@ -534,7 +339,10 @@ func metricsHandler(c echo.Context) error {
|
|||||||
var metrics string
|
var metrics string
|
||||||
|
|
||||||
// Node indexes
|
// Node indexes
|
||||||
node, err := node.GetNodeInfo()
|
processor := glue.Processor{
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
}
|
||||||
|
node, err := processor.GetNode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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_memory_index{hostname=\"%s\"} %f\n", hostname, node.MemoryIndex)
|
||||||
metrics += fmt.Sprintf("rosti_node_sold_memory{hostname=\"%s\"} %d\n", hostname, node.SoldMemory)
|
metrics += fmt.Sprintf("rosti_node_sold_memory{hostname=\"%s\"} %d\n", hostname, node.SoldMemory)
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
|
||||||
DB: common.GetDBConnection(),
|
|
||||||
}
|
|
||||||
apps, err := processor.List()
|
apps, err := processor.List()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
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_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)
|
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/pkg/errors"
|
||||||
"github.com/rosti-cz/node-api/apps"
|
"github.com/rosti-cz/node-api/apps"
|
||||||
"github.com/rosti-cz/node-api/common"
|
"github.com/rosti-cz/node-api/common"
|
||||||
docker "github.com/rosti-cz/node-api/containers"
|
"github.com/rosti-cz/node-api/glue"
|
||||||
"github.com/rosti-cz/node-api/detector"
|
|
||||||
"github.com/rosti-cz/node-api/node"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// This handler only passes messages to another function for easier testing
|
// This handler only passes messages to another function for easier testing
|
||||||
@ -59,7 +57,7 @@ func _messageHandler(m *nats.Msg) error {
|
|||||||
"add_label": addLabelEventHandler,
|
"add_label": addLabelEventHandler,
|
||||||
"remove_label": removeLabelEventHandler,
|
"remove_label": removeLabelEventHandler,
|
||||||
"list_orphans": listOrphansEventHandler,
|
"list_orphans": listOrphansEventHandler,
|
||||||
"node": getNoteEventHandler,
|
"node": getNodeEventHandler,
|
||||||
"create_snapshot": createSnapshotEventHandler,
|
"create_snapshot": createSnapshotEventHandler,
|
||||||
"restore_from_snapshot": restoreFromSnapshotEventHandler,
|
"restore_from_snapshot": restoreFromSnapshotEventHandler,
|
||||||
"list_snapshots": listSnapshotsEventHandler,
|
"list_snapshots": listSnapshotsEventHandler,
|
||||||
@ -94,17 +92,12 @@ func _messageHandler(m *nats.Msg) error {
|
|||||||
func listEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func listEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
log.Println("> List")
|
log.Println("> List")
|
||||||
|
|
||||||
err := gatherStates()
|
processor := glue.Processor{
|
||||||
if err != nil {
|
AppName: message.AppName,
|
||||||
return errorReplyFormater(m, "backend error", err)
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
|
||||||
DB: common.GetDBConnection(),
|
|
||||||
}
|
|
||||||
processor.Init()
|
|
||||||
applications, err := processor.List()
|
applications, err := processor.List()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errorReplyFormater(m, "backend error", err)
|
return errorReplyFormater(m, "backend error", err)
|
||||||
}
|
}
|
||||||
@ -128,56 +121,15 @@ func listEventHandler(m *nats.Msg, message *RequestMessage) error {
|
|||||||
|
|
||||||
// Returns one app
|
// Returns one app
|
||||||
func getEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func getEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
|
processor := glue.Processor{
|
||||||
err := updateState(message.AppName)
|
|
||||||
if err != nil {
|
|
||||||
return errorReplyFormater(m, "backend error", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
|
||||||
DB: common.GetDBConnection(),
|
DB: common.GetDBConnection(),
|
||||||
}
|
}
|
||||||
app, err := processor.Get(message.AppName)
|
|
||||||
if err != nil {
|
|
||||||
return errorReplyFormater(m, "backend error", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gather runtime info about the container
|
app, err := processor.Get()
|
||||||
container := docker.Container{
|
|
||||||
App: app,
|
|
||||||
}
|
|
||||||
|
|
||||||
status, err := container.Status()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("backend error: %v\n", err)
|
log.Printf("backend error: %v\n", err)
|
||||||
return errorReplyFormater(m, "backend error", 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
|
// Assembling reply message
|
||||||
reply := ReplyMessage{
|
reply := ReplyMessage{
|
||||||
@ -200,7 +152,6 @@ func getEventHandler(m *nats.Msg, message *RequestMessage) error {
|
|||||||
|
|
||||||
// Create a new app
|
// Create a new app
|
||||||
func createEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func createEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
|
|
||||||
appTemplate := apps.App{}
|
appTemplate := apps.App{}
|
||||||
body := []byte(message.Payload)
|
body := []byte(message.Payload)
|
||||||
err := json.Unmarshal(body, &appTemplate)
|
err := json.Unmarshal(body, &appTemplate)
|
||||||
@ -210,48 +161,17 @@ func createEventHandler(m *nats.Msg, message *RequestMessage) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
}
|
}
|
||||||
err = processor.New(message.AppName, appTemplate.SSHPort, appTemplate.HTTPPort, appTemplate.Image, appTemplate.CPU, appTemplate.Memory)
|
err = processor.Create(appTemplate)
|
||||||
if err != nil {
|
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||||
if validationError, ok := err.(apps.ValidationError); ok {
|
publish(message.AppName, "validation error", true)
|
||||||
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)
|
|
||||||
return err
|
return err
|
||||||
}
|
} else if err != nil {
|
||||||
|
log.Println("ERROR create application problem: " + err.Error())
|
||||||
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())
|
|
||||||
publish(message.AppName, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -273,17 +193,17 @@ func registerEventHandler(m *nats.Msg, message *RequestMessage) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
}
|
}
|
||||||
err = processor.New(message.AppName, appTemplate.SSHPort, appTemplate.HTTPPort, appTemplate.Image, appTemplate.CPU, appTemplate.Memory)
|
err = processor.Create(appTemplate)
|
||||||
if err != nil {
|
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||||
if validationError, ok := err.(apps.ValidationError); ok {
|
publish(message.AppName, "validation error", true)
|
||||||
log.Println("ERROR create application problem (validation): " + validationError.Error())
|
return err
|
||||||
publish(message.AppName, "validation problem", true)
|
} else if err != nil {
|
||||||
return err
|
log.Println("ERROR create application problem: " + err.Error())
|
||||||
}
|
|
||||||
log.Println("ERROR create application problem (processor.New): " + err.Error())
|
|
||||||
publish(message.AppName, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -304,306 +224,155 @@ func updateEventHandler(m *nats.Msg, message *RequestMessage) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
}
|
}
|
||||||
app, err := processor.Update(message.AppName, appTemplate.SSHPort, appTemplate.HTTPPort, appTemplate.Image, appTemplate.CPU, appTemplate.Memory)
|
err = processor.Update(appTemplate)
|
||||||
if err != nil {
|
if err != nil && strings.Contains(err.Error(), "validation error") {
|
||||||
if validationError, ok := err.(apps.ValidationError); ok {
|
publish(message.AppName, "validation error", true)
|
||||||
log.Println("ERROR update application problem: " + validationError.Error())
|
return err
|
||||||
publish(message.AppName, "backend problem", true)
|
} else if err != nil {
|
||||||
return err
|
log.Println("ERROR create application problem: " + err.Error())
|
||||||
}
|
|
||||||
log.Println("ERROR update application problem: " + err.Error())
|
|
||||||
publish(message.AppName, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
container := docker.Container{
|
publish(message.AppName, "updated", false)
|
||||||
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)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete one app
|
// Delete one app
|
||||||
func deleteEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func deleteEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
}
|
}
|
||||||
app, err := processor.Get(message.AppName)
|
err := processor.Delete()
|
||||||
if err != nil {
|
|
||||||
log.Println("ERROR: delete app:", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
container := docker.Container{
|
|
||||||
App: app,
|
|
||||||
}
|
|
||||||
|
|
||||||
status, err := container.Status()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR delete application problem: " + err.Error())
|
log.Println("ERROR delete application problem: " + err.Error())
|
||||||
publish(app.Name, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if status != "no-container" {
|
publish(message.AppName, "deleted", false)
|
||||||
// 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)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop existing app
|
// Stop existing app
|
||||||
func stopEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func stopEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
}
|
}
|
||||||
app, err := processor.Get(message.AppName)
|
err := processor.Stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR stop application problem: " + err.Error())
|
log.Println("ERROR stop application problem: " + err.Error())
|
||||||
publish(app.Name, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
container := docker.Container{
|
publish(message.AppName, "stopped", false)
|
||||||
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)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start existing app
|
// Start existing app
|
||||||
func startEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func startEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
}
|
}
|
||||||
app, err := processor.Get(message.AppName)
|
err := processor.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR start application problem: " + err.Error())
|
log.Println("ERROR start application problem: " + err.Error())
|
||||||
publish(app.Name, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
container := docker.Container{
|
publish(message.AppName, "started", false)
|
||||||
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)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restart existing app
|
// Restart existing app
|
||||||
func restartEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func restartEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
}
|
}
|
||||||
app, err := processor.Get(message.AppName)
|
err := processor.Restart()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR restart application problem: " + err.Error())
|
log.Println("ERROR restart application problem: " + err.Error())
|
||||||
publish(app.Name, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
container := docker.Container{
|
publish(message.AppName, "restarted", false)
|
||||||
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)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copies body of the request into /srv/.ssh/authorized_keys
|
// Copies body of the request into /srv/.ssh/authorized_keys
|
||||||
func updateKeysEventHandler(m *nats.Msg, message *RequestMessage) error {
|
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 {
|
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)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
body := message.Payload
|
publish(message.AppName, "keys updated", false)
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set password for the app user in the container
|
// Set password for the app user in the container
|
||||||
func setPasswordEventHandler(m *nats.Msg, message *RequestMessage) error {
|
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 {
|
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)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
password := message.Payload
|
publish(message.AppName, "password updated", false)
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Application processes
|
// Application processes
|
||||||
func processesEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func processesEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
}
|
DB: common.GetDBConnection(),
|
||||||
app, err := processor.Get(message.AppName)
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
if err != nil {
|
|
||||||
log.Println("ERROR processes list problem: " + err.Error())
|
|
||||||
publish(app.Name, "backend problem", true)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
container := docker.Container{
|
processes, err := processor.Processes()
|
||||||
App: app,
|
|
||||||
}
|
|
||||||
|
|
||||||
processes, err := container.GetProcessList()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR processes list problem: " + err.Error())
|
log.Println("ERROR processes list problem: " + err.Error())
|
||||||
publish(app.Name, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,7 +383,7 @@ func processesEventHandler(m *nats.Msg, message *RequestMessage) error {
|
|||||||
data, err := json.Marshal(reply)
|
data, err := json.Marshal(reply)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR processes list problem: " + err.Error())
|
log.Println("ERROR processes list problem: " + err.Error())
|
||||||
publish(app.Name, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = m.Respond(data)
|
err = m.Respond(data)
|
||||||
@ -653,81 +422,39 @@ func enableTechEventHandler(m *nats.Msg, message *RequestMessage) error {
|
|||||||
version = parts[1]
|
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 {
|
if err != nil {
|
||||||
log.Println("ERROR enable tech problem: " + err.Error())
|
log.Println("ERROR enable tech problem: " + err.Error())
|
||||||
publish(message.AppName, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
publish(message.AppName, "tech updated", false)
|
||||||
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)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rebuilds existing app, it keeps the data but creates the container again
|
// Rebuilds existing app, it keeps the data but creates the container again
|
||||||
func rebuildEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func rebuildEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
}
|
}
|
||||||
app, err := processor.Get(message.AppName)
|
|
||||||
|
err := processor.Rebuild()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR rebuild app problem: " + err.Error())
|
log.Println("ERROR rebuild app problem: " + err.Error())
|
||||||
publish(app.Name, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
container := docker.Container{
|
publish(message.AppName, "app rebuild", false)
|
||||||
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)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -736,10 +463,12 @@ func rebuildEventHandler(m *nats.Msg, message *RequestMessage) error {
|
|||||||
func addLabelEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func addLabelEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
label := message.Payload
|
label := message.Payload
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
}
|
}
|
||||||
err := processor.AddLabel(message.AppName, label)
|
err := processor.AddLabel(label)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR add label problem: " + err.Error())
|
log.Println("ERROR add label problem: " + err.Error())
|
||||||
publish(message.AppName, "backend problem", true)
|
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 {
|
func removeLabelEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
label := message.Payload
|
label := message.Payload
|
||||||
|
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
}
|
}
|
||||||
err := processor.RemoveLabel(message.AppName, label)
|
err := processor.RemoveLabel(label)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR remove label problem: " + err.Error())
|
log.Println("ERROR remove label problem: " + err.Error())
|
||||||
publish(message.AppName, "backend problem", true)
|
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 {
|
func getNodeEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
node, err := node.GetNodeInfo()
|
processor := glue.Processor{
|
||||||
|
AppName: message.AppName,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
|
}
|
||||||
|
|
||||||
|
node, err := processor.GetNode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR performance index problem: " + err.Error())
|
log.Println("ERROR performance index problem: " + err.Error())
|
||||||
publish(message.AppName, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
@ -834,7 +571,13 @@ Payload: no payload needed
|
|||||||
Response: notification when it's done or error
|
Response: notification when it's done or error
|
||||||
*/
|
*/
|
||||||
func createSnapshotEventHandler(m *nats.Msg, message *RequestMessage) 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 {
|
if err != nil {
|
||||||
log.Println("ERROR create snapshot error: " + err.Error())
|
log.Println("ERROR create snapshot error: " + err.Error())
|
||||||
publish(message.AppName, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
@ -858,64 +601,16 @@ Payload: string with the snapshot name
|
|||||||
Response: notification when it's done or error
|
Response: notification when it's done or error
|
||||||
*/
|
*/
|
||||||
func restoreFromSnapshotEventHandler(m *nats.Msg, message *RequestMessage) error {
|
func restoreFromSnapshotEventHandler(m *nats.Msg, message *RequestMessage) error {
|
||||||
processor := apps.AppsProcessor{
|
processor := glue.Processor{
|
||||||
DB: common.GetDBConnection(),
|
AppName: message.AppName,
|
||||||
}
|
DB: common.GetDBConnection(),
|
||||||
app, err := processor.Get(message.AppName)
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
if err != nil {
|
|
||||||
log.Println("ERROR restore snapshot problem: " + err.Error())
|
|
||||||
publish(app.Name, "backend problem", true)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
container := docker.Container{
|
err := processor.RestoreFromSnapshot(message.Payload)
|
||||||
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()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR start application problem: " + err.Error())
|
log.Println("ERROR start application problem: " + err.Error())
|
||||||
publish(app.Name, "backend problem", true)
|
publish(message.AppName, "backend problem", true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -934,21 +629,18 @@ Payload: no payload needed
|
|||||||
Response: replies with list of snapshots or an error message
|
Response: replies with list of snapshots or an error message
|
||||||
*/
|
*/
|
||||||
func listSnapshotsEventHandler(m *nats.Msg, message *RequestMessage) error {
|
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 {
|
if err != nil {
|
||||||
return errorReplyFormater(m, "backend error", err)
|
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{
|
reply := ReplyMessage{
|
||||||
Payload: output,
|
Payload: snapshots,
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := json.Marshal(reply)
|
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
|
Response: replies with list of snapshots or an error message
|
||||||
*/
|
*/
|
||||||
func listAppsSnapshotsEventHandler(m *nats.Msg, message *RequestMessage) error {
|
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 {
|
if err != nil {
|
||||||
return errorReplyFormater(m, "backend error", err)
|
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{
|
reply := ReplyMessage{
|
||||||
Payload: output,
|
Payload: snapshots,
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := json.Marshal(reply)
|
data, err := json.Marshal(reply)
|
||||||
@ -1006,21 +695,18 @@ Payload: snapshot label
|
|||||||
Response: replies with list of snapshots or an error message
|
Response: replies with list of snapshots or an error message
|
||||||
*/
|
*/
|
||||||
func listSnapshotsByLabelEventHandler(m *nats.Msg, message *RequestMessage) error {
|
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 {
|
if err != nil {
|
||||||
return errorReplyFormater(m, "backend error", err)
|
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{
|
reply := ReplyMessage{
|
||||||
Payload: output,
|
Payload: snapshots,
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := json.Marshal(reply)
|
data, err := json.Marshal(reply)
|
||||||
@ -1042,16 +728,17 @@ Payload: snapshot's key
|
|||||||
Response: snapshot metadata
|
Response: snapshot metadata
|
||||||
*/
|
*/
|
||||||
func getSnapshotEventHandler(m *nats.Msg, message *RequestMessage) error {
|
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 {
|
if err != nil {
|
||||||
return errorReplyFormater(m, "backend error", err)
|
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 {
|
if err != nil {
|
||||||
return errorReplyFormater(m, "reply formatter error", err)
|
return errorReplyFormater(m, "reply formatter error", err)
|
||||||
}
|
}
|
||||||
@ -1071,7 +758,12 @@ Payload: string with a snapshot name (key)
|
|||||||
Response: string with the URL
|
Response: string with the URL
|
||||||
*/
|
*/
|
||||||
func getSnapshotDownloadLinkEventHandler(m *nats.Msg, message *RequestMessage) error {
|
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 {
|
if err != nil {
|
||||||
return errorReplyFormater(m, "backend error", err)
|
return errorReplyFormater(m, "backend error", err)
|
||||||
}
|
}
|
||||||
@ -1100,7 +792,13 @@ Payload: string with a snapshot name
|
|||||||
Response: notification when it's done or error
|
Response: notification when it's done or error
|
||||||
*/
|
*/
|
||||||
func deleteSnapshotEventHandler(m *nats.Msg, message *RequestMessage) 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 {
|
if err != nil {
|
||||||
return errorReplyFormater(m, "backend error", err)
|
return errorReplyFormater(m, "backend error", err)
|
||||||
}
|
}
|
||||||
@ -1119,7 +817,13 @@ Payload: no payload needed
|
|||||||
Response: notification when it's done or error
|
Response: notification when it's done or error
|
||||||
*/
|
*/
|
||||||
func deleteAppSnapshotsEventHandler(m *nats.Msg, message *RequestMessage) 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 {
|
if err != nil {
|
||||||
return errorReplyFormater(m, "backend error", err)
|
return errorReplyFormater(m, "backend error", err)
|
||||||
}
|
}
|
||||||
|
26
main.go
26
main.go
@ -66,19 +66,19 @@ func main() {
|
|||||||
t := &Template{}
|
t := &Template{}
|
||||||
|
|
||||||
// Stats loop
|
// Stats loop
|
||||||
go func() {
|
// go func() {
|
||||||
for {
|
// for {
|
||||||
log.Println("Stats gathering started")
|
// log.Println("Stats gathering started")
|
||||||
start := time.Now()
|
// start := time.Now()
|
||||||
err := gatherStats()
|
// err := gatherStats()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Println("LOOP ERROR:", err.Error())
|
// log.Println("LOOP ERROR:", err.Error())
|
||||||
}
|
// }
|
||||||
elapsed := time.Since(start)
|
// elapsed := time.Since(start)
|
||||||
log.Printf("Stats gathering elapsed time: %.2fs\n", elapsed.Seconds())
|
// log.Printf("Stats gathering elapsed time: %.2fs\n", elapsed.Seconds())
|
||||||
time.Sleep(300 * time.Second)
|
// time.Sleep(300 * time.Second)
|
||||||
}
|
// }
|
||||||
}()
|
// }()
|
||||||
|
|
||||||
// Node stats
|
// Node stats
|
||||||
go func() {
|
go func() {
|
||||||
|
45
tools.go
45
tools.go
@ -2,15 +2,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/nats-io/nats.go"
|
"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 {
|
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())
|
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 (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/rosti-cz/node-api/apps"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Path where authorized keys are
|
|
||||||
const sshPubKeysLocation = "/srv/.ssh/authorized_keys"
|
|
||||||
|
|
||||||
// RequestMessage message
|
// RequestMessage message
|
||||||
type RequestMessage struct {
|
type RequestMessage struct {
|
||||||
AppName string `json:"name"`
|
AppName string `json:"name"`
|
||||||
@ -65,11 +60,8 @@ type QuickServices struct {
|
|||||||
Redis bool `json:"redis"`
|
Redis bool `json:"redis"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SnapshotMetadata is snapshot structure encapsulation that combines key and metadata about the snapshot
|
// Set technology
|
||||||
type SnapshotMetadata struct {
|
type Technology struct {
|
||||||
Key string `json:"key"`
|
Name string
|
||||||
Metadata apps.Snapshot `json:"metadata"`
|
Version string
|
||||||
}
|
}
|
||||||
|
|
||||||
// SnapshotsMetadata is returned by handlers
|
|
||||||
type SnapshotsMetadata []SnapshotMetadata
|
|
||||||
|
Loading…
Reference in New Issue
Block a user