devtoolcronjob.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // Copyright 2019 Yunion
  2. //
  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. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package models
  15. import (
  16. "context"
  17. "time"
  18. "yunion.io/x/jsonutils"
  19. "yunion.io/x/log"
  20. "yunion.io/x/onecloud/pkg/cloudcommon/cronman"
  21. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  22. "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
  23. "yunion.io/x/onecloud/pkg/devtool/options"
  24. "yunion.io/x/onecloud/pkg/mcclient"
  25. "yunion.io/x/onecloud/pkg/mcclient/auth"
  26. "yunion.io/x/onecloud/pkg/mcclient/modules/ansible"
  27. )
  28. type SVSCronjob struct {
  29. Day int `json:"day" nullable:"true" create:"optional" list:"user" update:"user" default:"0"`
  30. Hour int `nullable:"true" create:"optional" list:"user" update:"user" default:"0"`
  31. Min int `nullable:"true" create:"optional" list:"user" update:"user" default:"0"`
  32. Sec int `nullable:"true" create:"optional" list:"user" update:"user" default:"0"`
  33. Interval int64 `nullable:"true" create:"optional" list:"user" update:"user" default:"0"`
  34. Start bool `nullable:"true" create:"optional" list:"user" update:"user" default:"false"`
  35. Enabled bool `nullable:"true" create:"optional" list:"user" update:"user" default:"false"`
  36. }
  37. type SCronjob struct {
  38. SVSCronjob
  39. AnsiblePlaybookID string `width:"36" nullable:"false" create:"required" index:"true" list:"user" update:"user"`
  40. TemplateID string `width:"36" nullable:"true" create:"optional" index:"true" list:"user" update:"user"`
  41. ServerID string `width:"36" nullable:"true" create:"optional" index:"true" list:"user" update:"user"`
  42. db.SVirtualResourceBase
  43. }
  44. type SCronjobManager struct {
  45. db.SVirtualResourceBaseManager
  46. }
  47. var (
  48. CronjobManager *SCronjobManager
  49. DevToolCronManager *cronman.SCronJobManager
  50. )
  51. func init() {
  52. CronjobManager = &SCronjobManager{
  53. SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
  54. SCronjob{},
  55. "devtool_cronjobs_tbl",
  56. "devtool_cronjob",
  57. "devtool_cronjobs",
  58. ),
  59. }
  60. CronjobManager.SetVirtualObject(CronjobManager)
  61. }
  62. func RunAnsibleCronjob(id string, s *mcclient.ClientSession) cronman.TCronJobFunction {
  63. return func(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
  64. obj, err := CronjobManager.FetchById(id)
  65. if err != nil {
  66. log.Errorf("No cronjob with id: %s", id)
  67. return
  68. }
  69. log.Debugf("[RunAnsibleCronjob] %+v: ", obj)
  70. item := obj.(*SCronjob)
  71. log.Debugf("[RunAnsibleCronjob] perform ansible cronjob run: %s", item.AnsiblePlaybookID)
  72. ret, err := ansible.AnsiblePlaybooks.PerformAction(s, item.AnsiblePlaybookID, "run", nil)
  73. if err != nil {
  74. log.Errorf("AnsiblePlaybooks.PerformAction error: %s", err)
  75. }
  76. log.Debugf("AnsiblePlaybooks.PerformAction ret: %+v", ret)
  77. }
  78. }
  79. func AddOneCronjob(item *SCronjob, s *mcclient.ClientSession) error {
  80. if !item.Enabled {
  81. log.Debugf("ansible cronjob %s (devtool item.Id: %s) is not enabled", item.Name, item.Id)
  82. return nil
  83. }
  84. if item.Interval > 0 {
  85. err := DevToolCronManager.AddJobAtIntervalsWithStartRun(item.Id, time.Duration(item.Interval)*time.Second, RunAnsibleCronjob(item.Id, s), item.Start)
  86. if err != nil {
  87. log.Errorf("ansible cronjob %s (devtool item.Id: %s) error! %s", item.Name, item.Id, err)
  88. return err
  89. }
  90. log.Infof("ansible cronjob %s (devtool item.Id: %s) registered at item.Interval: %ds", item.Name, item.Id, item.Interval)
  91. } else {
  92. err := DevToolCronManager.AddJobEveryFewDays(item.Id, int(item.Day), int(item.Hour), int(item.Min), int(item.Sec), RunAnsibleCronjob(item.Id, s), item.Start)
  93. if err != nil {
  94. log.Errorf("ansible cronjob %s (devtool item.Id: %s) registered at item.Interval: item.Day(%d) item.Hour(%d) item.Min(%d) item.Sec(%d) error: %s", item.Name, item.Id, int(item.Day), int(item.Hour), int(item.Min), int(item.Sec), err)
  95. return err
  96. }
  97. log.Infof("ansible cronjob %s (devtool item.Id: %s) registered at item.Interval: item.Day(%d) item.Hour(%d) item.Min(%d) item.Sec(%d)", item.Name, item.Id, int(item.Day), int(item.Hour), int(item.Min), int(item.Sec))
  98. }
  99. return nil
  100. }
  101. func InitializeCronjobs(ctx context.Context) error {
  102. err := taskman.TaskManager.InitializeData()
  103. if err != nil {
  104. log.Fatalf("TaskManager.InitializeData fail %s", err)
  105. }
  106. DevToolCronManager = cronman.InitCronJobManager(true, 8, options.Options.TimeZone)
  107. DevToolCronManager.AddJobAtIntervalsWithStartRun("TaskCleanupJob", time.Duration(options.Options.TaskArchiveIntervalMinutes)*time.Minute, taskman.TaskManager.TaskCleanupJob, true)
  108. DevToolCronManager.Start()
  109. Session := auth.GetAdminSession(ctx, "")
  110. go func() {
  111. items := make([]SCronjob, 0)
  112. q := CronjobManager.Query().Equals("enabled", true)
  113. err := q.All(&items)
  114. if err != nil {
  115. log.Errorf("query error: %s", err)
  116. }
  117. for _, item := range items {
  118. AddOneCronjob(&item, Session)
  119. }
  120. }()
  121. return nil
  122. }
  123. func (job *SCronjob) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerID mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
  124. Session := auth.GetAdminSession(ctx, "")
  125. job.SStandaloneResourceBase.PostCreate(ctx, userCred, nil, query, data)
  126. AddOneCronjob(job, Session)
  127. }
  128. func (job *SCronjob) PostDelete(ctx context.Context, userCred mcclient.TokenCredential) {
  129. DevToolCronManager.Remove(job.Id)
  130. }
  131. func (job *SCronjob) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
  132. Session := auth.GetAdminSession(ctx, "")
  133. job.SStandaloneResourceBase.PostUpdate(ctx, userCred, query, data)
  134. DevToolCronManager.Remove(job.Id)
  135. AddOneCronjob(job, Session)
  136. }