code: func (c *Calcium) Copy(ctx context.Context, opts *types.CopyOptions) (chan *types.CopyMessage, error) {
  	ch := make(chan *types.CopyMessage)
  	go func() {
  		defer close(ch)
  		wg := sync.WaitGroup{}
  		log.Infof("[Copy] Copy %d containers files", len(opts.Targets))
  		// container one by one
  		for cid, paths := range opts.Targets {
  			wg.Add(1)
  			go func(cid string, paths []string) {
  				defer wg.Done()
  				container, err := c.GetContainer(ctx, cid)
  				if err != nil {
  					log.Errorf("[Copy] Error when get container %s, err %v", cid, err)
  					ch <- makeCopyMessage(cid, cluster.CopyFailed, "", "", err, nil)
  					return
  				}
  				for _, path := range paths {
  					wg.Add(1)
  					go func(path string) {
  						defer wg.Done()
  						resp, name, err := container.Engine.VirtualizationCopyFrom(ctx, container.ID, path)
  						if err != nil {
  							log.Errorf("[Copy] Error during CopyFromContainer: %v", err)
  							ch <- makeCopyMessage(cid, cluster.CopyFailed, "", path, err, nil)
  							return
  						}
  						ch <- makeCopyMessage(cid, cluster.CopyOK, name, path, nil, resp)
  					}(path)
  				}
  			}(cid, paths)
  		}
  		wg.Wait()
  	}()
  	return ch, nil
  }
docs: // Copy uses VirtualizationCopyFrom cp to copy specified things and send to remote