未验证 提交 3e869e0b 编写于 作者: M Medya Ghazizadeh 提交者: GitHub

Merge pull request #10198 from anencore94/minikube-scp

Add minikube cp command as new feature
/*
Copyright 2021 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"os"
pt "path"
"path/filepath"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/reason"
)
// placeholders for flag values
var (
srcPath string
dstPath string
)
// cpCmd represents the cp command, similar to docker cp
var cpCmd = &cobra.Command{
Use: "cp <source file path> <target file absolute path>",
Short: "Copy the specified file into minikube",
Long: "Copy the specified file into minikube, it will be saved at path <target file absolute path> in your minikube.\n" +
"Example Command : \"minikube cp a.txt /home/docker/b.txt\"\n",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
exit.Message(reason.Usage, `Please specify the path to copy:
minikube cp <source file path> <target file absolute path> (example: "minikube cp a/b.txt /copied.txt")`)
}
srcPath = args[0]
dstPath = args[1]
validateArgs(srcPath, dstPath)
co := mustload.Running(ClusterFlagValue())
fa, err := assets.NewFileAsset(srcPath, pt.Dir(dstPath), pt.Base(dstPath), "0644")
if err != nil {
out.ErrLn("%v", errors.Wrap(err, "getting file asset"))
os.Exit(1)
}
if err = co.CP.Runner.Copy(fa); err != nil {
out.ErrLn("%v", errors.Wrap(err, "copying file"))
os.Exit(1)
}
},
}
func init() {
}
func validateArgs(srcPath string, dstPath string) {
if srcPath == "" {
exit.Message(reason.Usage, "Source {{.path}} can not be empty", out.V{"path": srcPath})
}
if dstPath == "" {
exit.Message(reason.Usage, "Target {{.path}} can not be empty", out.V{"path": dstPath})
}
if _, err := os.Stat(srcPath); err != nil {
if os.IsNotExist(err) {
exit.Message(reason.HostPathMissing, "Cannot find directory {{.path}} for copy", out.V{"path": srcPath})
} else {
exit.Error(reason.HostPathStat, "stat failed", err)
}
}
if !filepath.IsAbs(dstPath) {
exit.Message(reason.Usage, `<target file absolute path> must be an absolute Path. Relative Path is not allowed (example: "/home/docker/copied.txt")`)
}
}
......@@ -243,6 +243,7 @@ func init() {
sshCmd,
kubectlCmd,
nodeCmd,
cpCmd,
},
},
{
......
---
title: "cp"
description: >
Copy the specified file into minikube
---
## minikube cp
Copy the specified file into minikube
### Synopsis
Copy the specified file into minikube, it will be saved at path <target file absolute path> in your minikube.
Example Command : "minikube cp a.txt /home/docker/b.txt"
```shell
minikube cp <source file path> <target file absolute path> [flags]
```
### Options inherited from parent commands
```
--add_dir_header If true, adds the file directory to the header of the log messages
--alsologtostderr log to standard error as well as files
-b, --bootstrapper string The name of the cluster bootstrapper that will set up the Kubernetes cluster. (default "kubeadm")
-h, --help
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--log_file string If non-empty, use this log file
--log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
--logtostderr log to standard error instead of files
--one_output If true, only write logs to their native severity level (vs also writing to each lower severity level
-p, --profile string The name of the minikube VM being used. This can be set to allow having multiple instances of minikube independently. (default "minikube")
--skip_headers If true, avoid header prefixes in the log messages
--skip_log_headers If true, avoid headers when opening log files
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
--user string Specifies the user executing the operation. Useful for auditing operations executed by 3rd party tools. Defaults to the operating system username.
-v, --v Level number for the log level verbosity
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
```
......@@ -125,6 +125,7 @@ func TestFunctional(t *testing.T) {
{"PersistentVolumeClaim", validatePersistentVolumeClaim},
{"TunnelCmd", validateTunnelCmd},
{"SSHCmd", validateSSHCmd},
{"CpCmd", validateCpCmd},
{"MySQL", validateMySQL},
{"FileSync", validateFileSync},
{"CertSync", validateCertSync},
......@@ -1176,6 +1177,34 @@ func validateSSHCmd(ctx context.Context, t *testing.T, profile string) {
}
}
// validateCpCmd asserts basic "cp" command functionality
func validateCpCmd(ctx context.Context, t *testing.T, profile string) {
if NoneDriver() {
t.Skipf("skipping: cp is unsupported by none driver")
}
cpPath := filepath.Join(*testdataDir, "cp-test.txt")
rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "cp", cpPath, "/home/docker/hello_cp.txt"))
if ctx.Err() == context.DeadlineExceeded {
t.Errorf("failed to run command by deadline. exceeded timeout : %s", rr.Command())
}
if err != nil {
t.Errorf("failed to run an cp command. args %q : %v", rr.Command(), err)
}
expected := "Test file for checking file cp process"
rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "ssh", "cat /home/docker/hello_cp.txt"))
if ctx.Err() == context.DeadlineExceeded {
t.Errorf("failed to run command by deadline. exceeded timeout : %s", rr.Command())
}
if err != nil {
t.Errorf("failed to run an cp command. args %q : %v", rr.Command(), err)
}
if diff := cmp.Diff(expected, rr.Stdout.String()); diff != "" {
t.Errorf("/testdata/cp-test.txt content mismatch (-want +got):\n%s", diff)
}
}
// validateMySQL validates a minimalist MySQL deployment
func validateMySQL(ctx context.Context, t *testing.T, profile string) {
if arm64Platform() {
......
Test file for checking file cp process
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册