diff --git a/apps/snapshots.go b/apps/snapshots.go index 7a2888f..c32d167 100644 --- a/apps/snapshots.go +++ b/apps/snapshots.go @@ -217,9 +217,9 @@ func (s *SnapshotProcessor) ListAppsSnapshots(appNames []string) ([]Snapshot, er return snapshots, nil } -// ListAppsSnapshotsByLabels returns list of snapshots with given label +// ListAppsSnapshotsByLabel returns list of snapshots with given label // TODO: this will be ok for now but probably little slow when users start using it more -func (s *SnapshotProcessor) ListAppsSnapshotsByLabels(desiredLabel string) ([]Snapshot, error) { +func (s *SnapshotProcessor) ListAppsSnapshotsByLabel(desiredLabel string) ([]Snapshot, error) { snapshots := []Snapshot{} keys, err := s.Driver.List("") diff --git a/apps/snapshots_test.go b/apps/snapshots_test.go index ce1cd96..1b73d10 100644 --- a/apps/snapshots_test.go +++ b/apps/snapshots_test.go @@ -153,3 +153,31 @@ func TestCreateRestoreListSnapshot(t *testing.T) { assert.Equal(t, os.IsNotExist(err), false) } + +func TestListAppsSnapshotsByLabel(t *testing.T) { + appName := "app_0102" + + // Create an app structure + err := os.MkdirAll(path.Join(snapshotProcessor.AppsPath, appName), 0755) + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + + _, err = exec.Command("bash", "-c", "echo content > "+path.Join(snapshotProcessor.AppsPath, appName)+"/a_file.txt").CombinedOutput() + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + + // Create an snapshot + snapshotName, err := snapshotProcessor.CreateSnapshot(appName, []string{"app:test2", "almost_no_content"}) + assert.Nil(t, err) + assert.Equal(t, strings.HasPrefix(snapshotName, appName+":"), true) + + snapshots, err := snapshotProcessor.ListAppsSnapshotsByLabel("app:test2") + assert.Nil(t, err) + assert.True(t, len(snapshots) > 0) + + assert.Equal(t, appName, snapshots[0].AppName) +} diff --git a/handlers_nats.go b/handlers_nats.go index 5ff3433..b1dbbad 100644 --- a/handlers_nats.go +++ b/handlers_nats.go @@ -41,30 +41,31 @@ func _messageHandler(m *nats.Msg) error { fmt.Printf("Received a message: %v\n", message) eventHandlerMap := map[string](func(m *nats.Msg, message *RequestMessage) error){ - "list": listEventHandler, - "get": getEventHandler, - "create": createEventHandler, - "register": registerEventHandler, - "update": updateEventHandler, - "delete": deleteEventHandler, - "stop": stopEventHandler, - "start": startEventHandler, - "restart": restartEventHandler, - "update_keys": updateKeysEventHandler, - "set_password": setPasswordEventHandler, - "processes": processesEventHandler, - "enable_tech": enableTechEventHandler, - "rebuild": rebuildEventHandler, - "add_label": addLabelEventHandler, - "remove_label": removeLabelEventHandler, - "list_orphans": listOrphansEventHandler, - "node": getNoteEventHandler, - "create_snapshot": createSnapshotEventHandler, - "restore_from_snapshot": restoreFromSnapshotEventHandler, - "list_snapshots": listSnapshotsEventHandler, - "list_apps_snapshots": listAppsSnapshotsEventHandler, - "delete_snapshot": deleteSnapshotEventHandler, - "delete_app_snapshots": deleteAppSnapshotsEventHandler, + "list": listEventHandler, + "get": getEventHandler, + "create": createEventHandler, + "register": registerEventHandler, + "update": updateEventHandler, + "delete": deleteEventHandler, + "stop": stopEventHandler, + "start": startEventHandler, + "restart": restartEventHandler, + "update_keys": updateKeysEventHandler, + "set_password": setPasswordEventHandler, + "processes": processesEventHandler, + "enable_tech": enableTechEventHandler, + "rebuild": rebuildEventHandler, + "add_label": addLabelEventHandler, + "remove_label": removeLabelEventHandler, + "list_orphans": listOrphansEventHandler, + "node": getNoteEventHandler, + "create_snapshot": createSnapshotEventHandler, + "restore_from_snapshot": restoreFromSnapshotEventHandler, + "list_snapshots": listSnapshotsEventHandler, + "list_apps_snapshots": listAppsSnapshotsEventHandler, + "list_snapshots_by_label": listSnapshotsByLabelEventHandler, + "delete_snapshot": deleteSnapshotEventHandler, + "delete_app_snapshots": deleteAppSnapshotsEventHandler, } if eventHandler, ok := eventHandlerMap[message.Type]; ok { @@ -958,6 +959,47 @@ func listAppsSnapshotsEventHandler(m *nats.Msg, message *RequestMessage) error { return nil } +/* +listSnapshotsByLabelEventHandler returns list of snapshots with given label + +Payload: snapshot label +Response: replies with list of snapshots or an error message +*/ +func listSnapshotsByLabelEventHandler(m *nats.Msg, message *RequestMessage) error { + processor := apps.SnapshotProcessor{ + AppsPath: config.AppsPath, + TmpSnapshotPath: config.SnapshotsPath, + + Driver: drivers.S3Driver{ + S3AccessKey: config.SnapshotsS3AccessKey, + S3SecretKey: config.SnapshotsS3SecretKey, + S3Endpoint: config.SnapshotsS3Endpoint, + S3SSL: config.SnapshotsS3SSL, + Bucket: config.SnapshotsS3Bucket, + }, + } + + snapshots, err := processor.ListAppsSnapshotsByLabel(message.Payload) + if err != nil { + return errorReplyFormater(m, "backend error", err) + } + + reply := ReplyMessage{ + Payload: snapshots, + } + + data, err := json.Marshal(reply) + if err != nil { + return errorReplyFormater(m, "reply formatter error", err) + } + + err = m.Respond(data) + if err != nil { + log.Println("ERROR: list of snapshots:", err.Error()) + } + return nil +} + /* deleteSnapshotEventHandler delete a single snapshot. This is not bound to application name.