feat: ensure mode of dir when using src as dir in copy module

Signed-off-by: William Wang <williamw0825@gmail.com>
This commit is contained in:
William Wang 2025-12-09 16:47:25 +08:00
parent f7db01eba2
commit 73c78a310f
4 changed files with 33 additions and 24 deletions

View File

@ -113,7 +113,7 @@ func (c *kubernetesConnector) PutFile(_ context.Context, src []byte, dst string,
if !os.IsNotExist(err) {
return errors.Wrapf(err, "failed to stat local dir %q for cluster %q", dst, c.clusterName)
}
if err := os.MkdirAll(filepath.Dir(dst), os.ModePerm); err != nil {
if err := os.MkdirAll(filepath.Dir(dst), _const.PermDirPublic); err != nil {
return errors.Wrapf(err, "failed to create local dir of path %q for cluster %q", dst, c.clusterName)
}
}

View File

@ -80,7 +80,7 @@ func (c *localConnector) PutFile(_ context.Context, src []byte, dst string, mode
if !os.IsNotExist(err) {
return errors.Wrapf(err, "failed to stat local dir %q", dst)
}
if err := os.MkdirAll(filepath.Dir(dst), os.ModePerm); err != nil {
if err := os.MkdirAll(filepath.Dir(dst), _const.PermDirPublic); err != nil {
return errors.Wrapf(err, "failed to create local dir of path %q", dst)
}
}

View File

@ -16,6 +16,8 @@ limitations under the License.
package _const
import "os"
// variable specific key in system
const ( // === From Global Parameter ===
// VariableLocalHost is the default local host name in inventory.
@ -123,3 +125,7 @@ const (
// SSHVerifyStatusUnreachable means host server cannot connect to target ssh
SSHVerifyStatusUnreachable = "unreachable"
)
const (
PermDirPublic = os.FileMode(0755)
)

View File

@ -218,6 +218,7 @@ func (ca copyArgs) handleRelativePath(ctx context.Context, options ExecOptions,
// copyAbsoluteDir copies all files from an absolute directory to the remote host.
func (ca copyArgs) copyAbsoluteDir(ctx context.Context, conn connector.Connector) error {
defer ca.ensureDestMode(ctx, conn)
return filepath.WalkDir(ca.src, func(path string, d fs.DirEntry, err error) error {
// Only copy files, skip directories
if d.IsDir() {
@ -234,25 +235,20 @@ func (ca copyArgs) copyAbsoluteDir(ctx context.Context, conn connector.Connector
}
mode := info.Mode()
if ca.mode != nil {
mode = os.FileMode(*ca.mode)
}
// read file
data, err := os.ReadFile(path)
if err != nil {
return errors.Wrapf(err, "failed to read file %q", path)
}
// copy file to remote
dest := ca.dest
if strings.HasSuffix(ca.dest, "/") {
rel, err := filepath.Rel(ca.src, path)
if err != nil {
return errors.Wrap(err, "failed to get relative filepath")
}
dest = filepath.Join(ca.dest, rel)
rel, err := filepath.Rel(ca.src, path)
if err != nil {
return errors.Wrap(err, "failed to get relative filepath")
}
dest := filepath.Join(ca.dest, rel)
tmpDest := filepath.Join("/tmp", ca.dest)
tmpDest := filepath.Join("/tmp", dest)
if err = conn.PutFile(ctx, data, tmpDest, mode); err != nil {
return err
@ -266,6 +262,7 @@ func (ca copyArgs) copyAbsoluteDir(ctx context.Context, conn connector.Connector
// copyRelativeDir copies all files from a relative directory (in the project) to the remote host.
func (ca copyArgs) copyRelativeDir(ctx context.Context, pj project.Project, relPath string, conn connector.Connector) error {
defer ca.ensureDestMode(ctx, conn)
return pj.WalkDir(relPath, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
@ -281,24 +278,19 @@ func (ca copyArgs) copyRelativeDir(ctx context.Context, pj project.Project, relP
}
mode := info.Mode()
if ca.mode != nil {
mode = os.FileMode(*ca.mode)
}
data, err := pj.ReadFile(path)
if err != nil {
return errors.Wrap(err, "failed to read file")
}
dest := ca.dest
if strings.HasSuffix(ca.dest, "/") {
rel, err := pj.Rel(relPath, path)
if err != nil {
return errors.Wrap(err, "failed to get relative file path")
}
dest = filepath.Join(ca.dest, rel)
rel, err := pj.Rel(relPath, path)
if err != nil {
return errors.Wrap(err, "failed to get relative file path")
}
tmpDest := filepath.Join("/tmp", ca.dest)
dest := filepath.Join(ca.dest, rel)
tmpDest := filepath.Join("/tmp", dest)
err = conn.PutFile(ctx, data, tmpDest, mode)
if err != nil {
@ -311,6 +303,17 @@ func (ca copyArgs) copyRelativeDir(ctx context.Context, pj project.Project, relP
})
}
// ensureDestMode if mode args exists, ensure dest dir mode after all files copied
func (ca copyArgs) ensureDestMode(ctx context.Context, conn connector.Connector) error {
if ca.mode != nil {
_, _, err := conn.ExecuteCommand(ctx, fmt.Sprintf("chmod %04o %s", *ca.mode, ca.dest))
if err != nil {
return err
}
}
return nil
}
// copyContent converts the content param and copies it to the destination file on the remote host.
func (ca copyArgs) copyContent(ctx context.Context, mode fs.FileMode, conn connector.Connector) (string, string, error) {
// Content must be copied to a file, not a directory