github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/infrastructure/tasks/pipeline_runner.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package tasks 21 22 import ( 23 "fmt" 24 "io" 25 26 "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/cache" 27 "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/connector" 28 "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/ending" 29 "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/module" 30 "github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/pipeline" 31 32 cfgcore "github.com/1aal/kubeblocks/pkg/configuration/core" 33 ) 34 35 type PipelineWrapper struct { 36 pipeline.Pipeline 37 } 38 39 func NewPipelineRunner(name string, modules []module.Module, runtime connector.Runtime) *PipelineWrapper { 40 return &PipelineWrapper{ 41 Pipeline: pipeline.Pipeline{ 42 Name: name, 43 Modules: modules, 44 Runtime: runtime, 45 PipelineCache: cache.NewCache(), 46 SpecHosts: len(runtime.GetAllHosts()), 47 }, 48 } 49 } 50 51 func (w *PipelineWrapper) Do(output io.Writer) error { 52 defer func() { 53 w.PipelineCache.Clean() 54 w.releaseHostsConnector() 55 }() 56 57 for i := range w.Modules { 58 m := w.Modules[i] 59 if m.IsSkip() { 60 continue 61 } 62 if res := w.safeRunModule(m); res.IsFailed() { 63 return cfgcore.WrapError(res.CombineResult, "failed to execute module: %s", getModuleName(m)) 64 } 65 } 66 fmt.Fprintf(output, "succeed to execute all modules in the pipeline[%s]", w.Name) 67 return nil 68 } 69 70 func (w *PipelineWrapper) safeRunModule(m module.Module) *ending.ModuleResult { 71 newCache := func() *cache.Cache { 72 if moduleCache, ok := w.ModuleCachePool.Get().(*cache.Cache); ok { 73 return moduleCache 74 } 75 return cache.NewCache() 76 } 77 releaseCache := func(cache *cache.Cache) { 78 cache.Clean() 79 w.ModuleCachePool.Put(cache) 80 } 81 82 moduleCache := newCache() 83 defer releaseCache(moduleCache) 84 m.Default(w.Runtime, w.PipelineCache, moduleCache) 85 m.AutoAssert() 86 m.Init() 87 return w.RunModule(m) 88 } 89 90 func (w *PipelineWrapper) releaseHostsConnector() { 91 for _, host := range w.Runtime.GetAllHosts() { 92 if connector := w.Runtime.GetConnector(); connector != nil { 93 connector.Close(host) 94 } 95 } 96 } 97 98 func getModuleName(m module.Module) string { 99 if b, ok := m.(*module.BaseModule); ok { 100 return b.Name 101 } 102 return "" 103 }