AppManager: Implement task status API

Change-Id: I70c895d7461ffe4afc45868ca6bf754d37072a0f
diff --git a/core/installer/tasks/release.go b/core/installer/tasks/release.go
index 9a99698..059d1ee 100644
--- a/core/installer/tasks/release.go
+++ b/core/installer/tasks/release.go
@@ -19,7 +19,23 @@
 }
 
 func newMonitorHelm(mon installer.HelmReleaseMonitor, h installer.Resource) Task {
-	t := newLeafTask(h.Info, func() error {
+	rType := h.Annotations["dodo.cloud/resource-type"]
+	var name string
+	switch rType {
+	case "virtual-machine":
+		name = h.Annotations["dodo.cloud/resource.virtual-machine.name"]
+	case "mongodb":
+		name = h.Annotations["dodo.cloud/resource.mongodb.name"]
+	case "postgresql":
+		name = h.Annotations["dodo.cloud/resource.postgresql.name"]
+	case "volume":
+		name = h.Annotations["dodo.cloud/resource.volume.name"]
+	case "ingress":
+		name = h.Annotations["dodo.cloud/resource.ingress.host"]
+	case "service":
+		name = h.Annotations["dodo.cloud/resource.service.name"]
+	}
+	t := newResourceLeafTask(h.Info, &ResourceId{rType, name}, func() error {
 		for {
 			if ok, err := mon.IsReleased(h.Namespace, h.Name); err == nil && ok {
 				break
diff --git a/core/installer/tasks/tasks.go b/core/installer/tasks/tasks.go
index 69ddd17..a391e7e 100644
--- a/core/installer/tasks/tasks.go
+++ b/core/installer/tasks/tasks.go
@@ -13,13 +13,33 @@
 	StatusDone           = 3
 )
 
+func StatusString(s Status) string {
+	switch s {
+	case StatusPending:
+		return "pending"
+	case StatusRunning:
+		return "running"
+	case StatusFailed:
+		return "failed"
+	case StatusDone:
+		return "done"
+	}
+	panic("MUST NOT REACH")
+}
+
 type TaskDoneListener func(err error)
 
 type Subtasks interface {
 	Tasks() []Task
 }
 
+type ResourceId struct {
+	Type string
+	Name string
+}
+
 type Task interface {
+	Resource() *ResourceId
 	Title() string
 	Start()
 	Status() Status
@@ -30,6 +50,7 @@
 
 type basicTask struct {
 	title       string
+	rid         *ResourceId
 	status      Status
 	err         error
 	listeners   []TaskDoneListener
@@ -37,8 +58,9 @@
 	afterDone   func()
 }
 
-func newBasicTask(title string) basicTask {
+func newBasicTask(title string, rid *ResourceId) basicTask {
 	return basicTask{
+		rid:       rid,
 		title:     title,
 		status:    StatusPending,
 		err:       nil,
@@ -46,6 +68,10 @@
 	}
 }
 
+func (b *basicTask) Resource() *ResourceId {
+	return b.rid
+}
+
 func (b *basicTask) Title() string {
 	return b.title
 }
@@ -84,7 +110,14 @@
 
 func newLeafTask(title string, start func() error) leafTask {
 	return leafTask{
-		basicTask: newBasicTask(title),
+		basicTask: newBasicTask(title, nil),
+		start:     start,
+	}
+}
+
+func newResourceLeafTask(title string, rid *ResourceId, start func() error) leafTask {
+	return leafTask{
+		basicTask: newBasicTask(title, rid),
 		start:     start,
 	}
 }