You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

upstream.go 4.6 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. Copyright 2021 The KubeEdge Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package incrementallearning
  14. import (
  15. "context"
  16. "encoding/json"
  17. "fmt"
  18. "strings"
  19. sednav1 "github.com/kubeedge/sedna/pkg/apis/sedna/v1alpha1"
  20. "github.com/kubeedge/sedna/pkg/globalmanager/runtime"
  21. v1 "k8s.io/api/core/v1"
  22. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  23. )
  24. type Model = runtime.Model
  25. // IncrementalCondData the data of this condition including the input/output to do the next step
  26. type IncrementalCondData struct {
  27. Input *struct {
  28. // Only one model cases
  29. Model *Model `json:"model,omitempty"`
  30. Models []Model `json:"models,omitempty"`
  31. DataURL string `json:"dataURL,omitempty"`
  32. // the data samples reference will be stored into this URL.
  33. // The content of this url would be:
  34. // # the first uncomment line means the directory
  35. // s3://dataset/
  36. // mnist/0.jpg
  37. // mnist/1.jpg
  38. DataIndexURL string `json:"dataIndexURL,omitempty"`
  39. OutputDir string `json:"outputDir,omitempty"`
  40. } `json:"input,omitempty"`
  41. Output *struct {
  42. Model *Model `json:"model,omitempty"`
  43. Models []Model `json:"models,omitempty"`
  44. } `json:"output,omitempty"`
  45. }
  46. func (cd *IncrementalCondData) joinModelURLs(model *Model, models []Model) []string {
  47. var modelURLs []string
  48. if model != nil {
  49. modelURLs = append(modelURLs, model.GetURL())
  50. } else {
  51. for _, m := range models {
  52. modelURLs = append(modelURLs, m.GetURL())
  53. }
  54. }
  55. return modelURLs
  56. }
  57. func (cd *IncrementalCondData) GetInputModelURLs() []string {
  58. return cd.joinModelURLs(cd.Input.Model, cd.Input.Models)
  59. }
  60. func (cd *IncrementalCondData) GetOutputModelURLs() []string {
  61. return cd.joinModelURLs(cd.Output.Model, cd.Output.Models)
  62. }
  63. func (cd *IncrementalCondData) Unmarshal(data []byte) error {
  64. return json.Unmarshal(data, cd)
  65. }
  66. func (cd IncrementalCondData) Marshal() ([]byte, error) {
  67. return json.Marshal(cd)
  68. }
  69. func (c *Controller) appendStatusCondition(name, namespace string, cond sednav1.ILJobCondition) error {
  70. client := c.client.IncrementalLearningJobs(namespace)
  71. return runtime.RetryUpdateStatus(name, namespace, func() error {
  72. job, err := client.Get(context.TODO(), name, metav1.GetOptions{})
  73. if err != nil {
  74. return err
  75. }
  76. job.Status.Conditions = append(job.Status.Conditions, cond)
  77. _, err = client.UpdateStatus(context.TODO(), job, metav1.UpdateOptions{})
  78. return err
  79. })
  80. }
  81. // updateFromEdge syncs the edge updates to k8s
  82. func (c *Controller) updateFromEdge(name, namespace, operation string, content []byte) error {
  83. var jobStatus struct {
  84. Phase string `json:"phase"`
  85. Status string `json:"status"`
  86. }
  87. err := json.Unmarshal(content, &jobStatus)
  88. if err != nil {
  89. return err
  90. }
  91. // Get the condition data.
  92. // Here unmarshal and marshal immediately to skip the unnecessary fields
  93. var condData IncrementalCondData
  94. err = json.Unmarshal(content, &condData)
  95. if err != nil {
  96. return err
  97. }
  98. condDataBytes, _ := json.Marshal(&condData)
  99. cond := sednav1.ILJobCondition{
  100. Status: v1.ConditionTrue,
  101. LastHeartbeatTime: metav1.Now(),
  102. LastTransitionTime: metav1.Now(),
  103. Data: string(condDataBytes),
  104. Message: "reported by lc",
  105. }
  106. switch strings.ToLower(jobStatus.Phase) {
  107. case "train":
  108. cond.Stage = sednav1.ILJobTrain
  109. case "eval":
  110. cond.Stage = sednav1.ILJobEval
  111. case "deploy":
  112. cond.Stage = sednav1.ILJobDeploy
  113. default:
  114. return fmt.Errorf("invalid condition stage: %v", jobStatus.Phase)
  115. }
  116. switch strings.ToLower(jobStatus.Status) {
  117. case "ready":
  118. cond.Type = sednav1.ILJobStageCondReady
  119. case "completed":
  120. cond.Type = sednav1.ILJobStageCondCompleted
  121. case "failed":
  122. cond.Type = sednav1.ILJobStageCondFailed
  123. case "waiting":
  124. cond.Type = sednav1.ILJobStageCondWaiting
  125. default:
  126. return fmt.Errorf("invalid condition type: %v", jobStatus.Status)
  127. }
  128. err = c.appendStatusCondition(name, namespace, cond)
  129. if err != nil {
  130. return fmt.Errorf("failed to append condition, err:%w", err)
  131. }
  132. return nil
  133. }
  134. func (c *Controller) SetUpstreamHandler(addFunc runtime.UpstreamHandlerAddFunc) error {
  135. return addFunc(KindName, c.updateFromEdge)
  136. }