(ctx context.Context, containerID string, srcPath string, dstPath string, opts api.CopyOptions)
| 143 | } |
| 144 | |
| 145 | func (s *composeService) copyToContainer(ctx context.Context, containerID string, srcPath string, dstPath string, opts api.CopyOptions) error { |
| 146 | var err error |
| 147 | if srcPath != "-" { |
| 148 | // Get an absolute source path. |
| 149 | srcPath, err = resolveLocalPath(srcPath) |
| 150 | if err != nil { |
| 151 | return err |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | // Prepare destination copy info by stat-ing the container path. |
| 156 | dstInfo := archive.CopyInfo{Path: dstPath} |
| 157 | var dstStat container.PathStat |
| 158 | res, err := s.apiClient().ContainerStatPath(ctx, containerID, client.ContainerStatPathOptions{ |
| 159 | Path: dstPath, |
| 160 | }) |
| 161 | if err == nil { |
| 162 | dstStat = res.Stat |
| 163 | } |
| 164 | |
| 165 | // If the destination is a symbolic link, we should evaluate it. |
| 166 | if err == nil && dstStat.Mode&os.ModeSymlink != 0 { |
| 167 | linkTarget := dstStat.LinkTarget |
| 168 | if !isAbs(linkTarget) { |
| 169 | // Join with the parent directory. |
| 170 | dstParent, _ := archive.SplitPathDirEntry(dstPath) |
| 171 | linkTarget = filepath.Join(dstParent, linkTarget) |
| 172 | } |
| 173 | |
| 174 | dstInfo.Path = linkTarget |
| 175 | res, err = s.apiClient().ContainerStatPath(ctx, containerID, client.ContainerStatPathOptions{ |
| 176 | Path: linkTarget, |
| 177 | }) |
| 178 | if err == nil { |
| 179 | dstStat = res.Stat |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | // Validate the destination path |
| 184 | if err := command.ValidateOutputPathFileMode(dstStat.Mode); err != nil { |
| 185 | return fmt.Errorf(`destination "%s:%s" must be a directory or a regular file: %w`, containerID, dstPath, err) |
| 186 | } |
| 187 | |
| 188 | // Ignore any error and assume that the parent directory of the destination |
| 189 | // path exists, in which case the copy may still succeed. If there is any |
| 190 | // type of conflict (e.g., non-directory overwriting an existing directory |
| 191 | // or vice versa) the extraction will fail. If the destination simply did |
| 192 | // not exist, but the parent directory does, the extraction will still |
| 193 | // succeed. |
| 194 | if err == nil { |
| 195 | dstInfo.Exists, dstInfo.IsDir = true, dstStat.Mode.IsDir() |
| 196 | } |
| 197 | |
| 198 | var ( |
| 199 | content io.Reader |
| 200 | resolvedDstPath string |
| 201 | ) |
| 202 |
nothing calls this directly
no test coverage detected