github.com/projecteru2/core@v0.0.0-20240321043226-06bcc1c23f58/cluster/calcium/send.go (about) 1 package calcium 2 3 import ( 4 "bytes" 5 "context" 6 "sync" 7 8 "github.com/projecteru2/core/engine" 9 "github.com/projecteru2/core/log" 10 "github.com/projecteru2/core/types" 11 ) 12 13 // Send files to workload 14 func (c *Calcium) Send(ctx context.Context, opts *types.SendOptions) (chan *types.SendMessage, error) { 15 logger := log.WithFunc("calcium.Send").WithField("opts", opts) 16 if err := opts.Validate(); err != nil { 17 logger.Error(ctx, err) 18 return nil, err 19 } 20 ch := make(chan *types.SendMessage) 21 _ = c.pool.Invoke(func() { 22 defer close(ch) 23 wg := &sync.WaitGroup{} 24 wg.Add(len(opts.IDs)) 25 26 for _, ID := range opts.IDs { 27 logger.Infof(ctx, "Send files to %s", ID) 28 _ = c.pool.Invoke(func(ID string) func() { 29 return func() { 30 defer wg.Done() 31 if err := c.withWorkloadLocked(ctx, ID, false, func(ctx context.Context, workload *types.Workload) error { 32 for _, file := range opts.Files { 33 err := c.doSendFileToWorkload(ctx, workload.Engine, workload.ID, file) 34 logger.Error(ctx, err) 35 ch <- &types.SendMessage{ID: ID, Path: file.Filename, Error: err} 36 } 37 return nil 38 }); err != nil { 39 logger.Error(ctx, err) 40 ch <- &types.SendMessage{ID: ID, Error: err} 41 } 42 } 43 }(ID)) 44 } 45 wg.Wait() 46 }) 47 return ch, nil 48 } 49 50 func (c *Calcium) doSendFileToWorkload(ctx context.Context, engine engine.API, ID string, file types.LinuxFile) error { 51 log.WithFunc("calcium.doSendFileToWorkload").Infof(ctx, "Send file to %s:%s", ID, file.Filename) 52 return engine.VirtualizationCopyChunkTo(ctx, ID, file.Filename, int64(len(file.Content)), bytes.NewReader(file.Clone().Content), file.UID, file.GID, file.Mode) 53 }