mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 02:09:56 +00:00
Merge pull request #16160 from kargakis/windows-fixes-for-edit
edit: Windows fixes
This commit is contained in:
commit
6219b50280
@ -498,6 +498,7 @@ _kubectl_edit()
|
|||||||
flags+=("--output=")
|
flags+=("--output=")
|
||||||
two_word_flags+=("-o")
|
two_word_flags+=("-o")
|
||||||
flags+=("--output-version=")
|
flags+=("--output-version=")
|
||||||
|
flags+=("--windows-line-endings")
|
||||||
|
|
||||||
must_have_one_flag=()
|
must_have_one_flag=()
|
||||||
must_have_one_noun=()
|
must_have_one_noun=()
|
||||||
|
@ -18,15 +18,16 @@ Edit a resource from the default editor.
|
|||||||
.PP
|
.PP
|
||||||
The edit command allows you to directly edit any API resource you can retrieve via the
|
The edit command allows you to directly edit any API resource you can retrieve via the
|
||||||
command line tools. It will open the editor defined by your KUBE\_EDITOR, GIT\_EDITOR,
|
command line tools. It will open the editor defined by your KUBE\_EDITOR, GIT\_EDITOR,
|
||||||
or EDITOR environment variables, or fall back to 'vi'. You can edit multiple objects,
|
or EDITOR environment variables, or fall back to 'vi' for Linux or 'notepad' for Windows.
|
||||||
although changes are applied one at a time. The command accepts filenames as well as
|
You can edit multiple objects, although changes are applied one at a time. The command
|
||||||
command line arguments, although the files you point to must be previously saved
|
accepts filenames as well as command line arguments, although the files you point to must
|
||||||
versions of resources.
|
be previously saved versions of resources.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
The files to edit will be output in the default API version, or a version specified
|
The files to edit will be output in the default API version, or a version specified
|
||||||
by \-\-output\-version. The default format is YAML \- if you would like to edit in JSON
|
by \-\-output\-version. The default format is YAML \- if you would like to edit in JSON
|
||||||
pass \-o json.
|
pass \-o json. The flag \-\-windows\-line\-endings can be used to force Windows line endings,
|
||||||
|
otherwise the default for your operating system will be used.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
In the event an error occurs while updating, a temporary file will be created on disk
|
In the event an error occurs while updating, a temporary file will be created on disk
|
||||||
@ -49,6 +50,10 @@ saved copy to include the latest resource version.
|
|||||||
\fB\-\-output\-version\fP=""
|
\fB\-\-output\-version\fP=""
|
||||||
Output the formatted object with the given version (default api\-version).
|
Output the formatted object with the given version (default api\-version).
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-windows\-line\-endings\fP=false
|
||||||
|
Use Windows line\-endings (default Unix line\-endings)
|
||||||
|
|
||||||
|
|
||||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||||
.PP
|
.PP
|
||||||
|
@ -42,14 +42,15 @@ Edit a resource from the default editor.
|
|||||||
|
|
||||||
The edit command allows you to directly edit any API resource you can retrieve via the
|
The edit command allows you to directly edit any API resource you can retrieve via the
|
||||||
command line tools. It will open the editor defined by your KUBE_EDITOR, GIT_EDITOR,
|
command line tools. It will open the editor defined by your KUBE_EDITOR, GIT_EDITOR,
|
||||||
or EDITOR environment variables, or fall back to 'vi'. You can edit multiple objects,
|
or EDITOR environment variables, or fall back to 'vi' for Linux or 'notepad' for Windows.
|
||||||
although changes are applied one at a time. The command accepts filenames as well as
|
You can edit multiple objects, although changes are applied one at a time. The command
|
||||||
command line arguments, although the files you point to must be previously saved
|
accepts filenames as well as command line arguments, although the files you point to must
|
||||||
versions of resources.
|
be previously saved versions of resources.
|
||||||
|
|
||||||
The files to edit will be output in the default API version, or a version specified
|
The files to edit will be output in the default API version, or a version specified
|
||||||
by --output-version. The default format is YAML - if you would like to edit in JSON
|
by --output-version. The default format is YAML - if you would like to edit in JSON
|
||||||
pass -o json.
|
pass -o json. The flag --windows-line-endings can be used to force Windows line endings,
|
||||||
|
otherwise the default for your operating system will be used.
|
||||||
|
|
||||||
In the event an error occurs while updating, a temporary file will be created on disk
|
In the event an error occurs while updating, a temporary file will be created on disk
|
||||||
that contains your unapplied changes. The most common error when updating a resource
|
that contains your unapplied changes. The most common error when updating a resource
|
||||||
@ -80,6 +81,7 @@ kubectl edit (RESOURCE/NAME | -f FILENAME)
|
|||||||
-f, --filename=[]: Filename, directory, or URL to file to use to edit the resource
|
-f, --filename=[]: Filename, directory, or URL to file to use to edit the resource
|
||||||
-o, --output="yaml": Output format. One of: yaml|json.
|
-o, --output="yaml": Output format. One of: yaml|json.
|
||||||
--output-version="": Output the formatted object with the given version (default api-version).
|
--output-version="": Output the formatted object with the given version (default api-version).
|
||||||
|
--windows-line-endings[=false]: Use Windows line-endings (default Unix line-endings)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Options inherited from parent commands
|
### Options inherited from parent commands
|
||||||
@ -114,7 +116,7 @@ kubectl edit (RESOURCE/NAME | -f FILENAME)
|
|||||||
|
|
||||||
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra at 2015-09-22 12:53:42.290401559 +0000 UTC
|
###### Auto generated by spf13/cobra on 23-Oct-2015
|
||||||
|
|
||||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||||
[]()
|
[]()
|
||||||
|
@ -487,6 +487,10 @@ runTests() {
|
|||||||
kube::test::get_object_assert pods "{{range.items}}{{$image_field}}:{{end}}" 'gcr.io/google_containers/serve_hostname:'
|
kube::test::get_object_assert pods "{{range.items}}{{$image_field}}:{{end}}" 'gcr.io/google_containers/serve_hostname:'
|
||||||
# cleaning
|
# cleaning
|
||||||
rm /tmp/tmp-editor.sh
|
rm /tmp/tmp-editor.sh
|
||||||
|
[ "$(EDITOR=cat kubectl edit pod/valid-pod 2>&1 | grep 'Edit cancelled')" ]
|
||||||
|
[ "$(EDITOR=cat kubectl edit pod/valid-pod | grep 'name: valid-pod')" ]
|
||||||
|
[ "$(EDITOR=cat kubectl edit --windows-line-endings pod/valid-pod | file - | grep CRLF)" ]
|
||||||
|
[ ! "$(EDITOR=cat kubectl edit --windows-line-endings=false pod/valid-pod | file - | grep CRLF)" ]
|
||||||
|
|
||||||
### Overwriting an existing label is not permitted
|
### Overwriting an existing label is not permitted
|
||||||
# Pre-condition: name is valid-pod
|
# Pre-condition: name is valid-pod
|
||||||
|
@ -304,6 +304,7 @@ user-whitelist
|
|||||||
watch-cache
|
watch-cache
|
||||||
watch-only
|
watch-only
|
||||||
whitelist-override-label
|
whitelist-override-label
|
||||||
|
windows-line-endings
|
||||||
www-prefix
|
www-prefix
|
||||||
retry_time
|
retry_time
|
||||||
file_content_in_loop
|
file_content_in_loop
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@ -33,6 +34,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/jsonmerge"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/util/jsonmerge"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
|
"k8s.io/kubernetes/pkg/util"
|
||||||
"k8s.io/kubernetes/pkg/util/strategicpatch"
|
"k8s.io/kubernetes/pkg/util/strategicpatch"
|
||||||
"k8s.io/kubernetes/pkg/util/yaml"
|
"k8s.io/kubernetes/pkg/util/yaml"
|
||||||
|
|
||||||
@ -45,14 +47,15 @@ const (
|
|||||||
|
|
||||||
The edit command allows you to directly edit any API resource you can retrieve via the
|
The edit command allows you to directly edit any API resource you can retrieve via the
|
||||||
command line tools. It will open the editor defined by your KUBE_EDITOR, GIT_EDITOR,
|
command line tools. It will open the editor defined by your KUBE_EDITOR, GIT_EDITOR,
|
||||||
or EDITOR environment variables, or fall back to 'vi'. You can edit multiple objects,
|
or EDITOR environment variables, or fall back to 'vi' for Linux or 'notepad' for Windows.
|
||||||
although changes are applied one at a time. The command accepts filenames as well as
|
You can edit multiple objects, although changes are applied one at a time. The command
|
||||||
command line arguments, although the files you point to must be previously saved
|
accepts filenames as well as command line arguments, although the files you point to must
|
||||||
versions of resources.
|
be previously saved versions of resources.
|
||||||
|
|
||||||
The files to edit will be output in the default API version, or a version specified
|
The files to edit will be output in the default API version, or a version specified
|
||||||
by --output-version. The default format is YAML - if you would like to edit in JSON
|
by --output-version. The default format is YAML - if you would like to edit in JSON
|
||||||
pass -o json.
|
pass -o json. The flag --windows-line-endings can be used to force Windows line endings,
|
||||||
|
otherwise the default for your operating system will be used.
|
||||||
|
|
||||||
In the event an error occurs while updating, a temporary file will be created on disk
|
In the event an error occurs while updating, a temporary file will be created on disk
|
||||||
that contains your unapplied changes. The most common error when updating a resource
|
that contains your unapplied changes. The most common error when updating a resource
|
||||||
@ -91,6 +94,7 @@ func NewCmdEdit(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
kubectl.AddJsonFilenameFlag(cmd, &filenames, usage)
|
kubectl.AddJsonFilenameFlag(cmd, &filenames, usage)
|
||||||
cmd.Flags().StringP("output", "o", "yaml", "Output format. One of: yaml|json.")
|
cmd.Flags().StringP("output", "o", "yaml", "Output format. One of: yaml|json.")
|
||||||
cmd.Flags().String("output-version", "", "Output the formatted object with the given version (default api-version).")
|
cmd.Flags().String("output-version", "", "Output the formatted object with the given version (default api-version).")
|
||||||
|
cmd.Flags().Bool("windows-line-endings", runtime.GOOS == "windows", "Use Windows line-endings (default Unix line-endings)")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +146,8 @@ func RunEdit(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
windowsLineEndings := cmdutil.GetFlagBool(cmd, "windows-line-endings")
|
||||||
|
edit := editor.NewDefaultEditor()
|
||||||
defaultVersion := cmdutil.OutputVersion(cmd, clientConfig.Version)
|
defaultVersion := cmdutil.OutputVersion(cmd, clientConfig.Version)
|
||||||
results := editResults{}
|
results := editResults{}
|
||||||
for {
|
for {
|
||||||
@ -156,16 +162,19 @@ func RunEdit(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin
|
|||||||
|
|
||||||
// generate the file to edit
|
// generate the file to edit
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
if err := results.header.writeTo(buf); err != nil {
|
var w io.Writer = buf
|
||||||
|
if windowsLineEndings {
|
||||||
|
w = util.NewCRLFWriter(w)
|
||||||
|
}
|
||||||
|
if err := results.header.writeTo(w); err != nil {
|
||||||
return preservedFile(err, results.file, out)
|
return preservedFile(err, results.file, out)
|
||||||
}
|
}
|
||||||
if err := printer.PrintObj(obj, buf); err != nil {
|
if err := printer.PrintObj(obj, w); err != nil {
|
||||||
return preservedFile(err, results.file, out)
|
return preservedFile(err, results.file, out)
|
||||||
}
|
}
|
||||||
original := buf.Bytes()
|
original := buf.Bytes()
|
||||||
|
|
||||||
// launch the editor
|
// launch the editor
|
||||||
edit := editor.NewDefaultEditor()
|
|
||||||
edited, file, err := edit.LaunchTempFile("kubectl-edit-", ext, buf)
|
edited, file, err := edit.LaunchTempFile("kubectl-edit-", ext, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return preservedFile(err, results.file, out)
|
return preservedFile(err, results.file, out)
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/term"
|
"github.com/docker/docker/pkg/term"
|
||||||
@ -33,8 +34,13 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// sorry, blame Git
|
// sorry, blame Git
|
||||||
|
// TODO: on Windows rely on 'start' to launch the editor associated
|
||||||
|
// with the given file type. If we can't because of the need of
|
||||||
|
// blocking, use a script with 'ftype' and 'assoc' to detect it.
|
||||||
defaultEditor = "vi"
|
defaultEditor = "vi"
|
||||||
defaultShell = "/bin/bash"
|
defaultShell = "/bin/bash"
|
||||||
|
windowsEditor = "notepad"
|
||||||
|
windowsShell = "cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Editor struct {
|
type Editor struct {
|
||||||
@ -58,15 +64,19 @@ func NewDefaultEditor() Editor {
|
|||||||
func defaultEnvShell() []string {
|
func defaultEnvShell() []string {
|
||||||
shell := os.Getenv("SHELL")
|
shell := os.Getenv("SHELL")
|
||||||
if len(shell) == 0 {
|
if len(shell) == 0 {
|
||||||
shell = defaultShell
|
shell = platformize(defaultShell, windowsShell)
|
||||||
}
|
}
|
||||||
return []string{shell, "-c"}
|
flag := "-c"
|
||||||
|
if shell == windowsShell {
|
||||||
|
flag = "/C"
|
||||||
|
}
|
||||||
|
return []string{shell, flag}
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultEnvEditor() ([]string, bool) {
|
func defaultEnvEditor() ([]string, bool) {
|
||||||
editor := os.Getenv("EDITOR")
|
editor := os.Getenv("EDITOR")
|
||||||
if len(editor) == 0 {
|
if len(editor) == 0 {
|
||||||
editor = defaultEditor
|
editor = platformize(defaultEditor, windowsEditor)
|
||||||
}
|
}
|
||||||
if !strings.Contains(editor, " ") {
|
if !strings.Contains(editor, " ") {
|
||||||
return []string{editor}, false
|
return []string{editor}, false
|
||||||
@ -133,6 +143,8 @@ func (e Editor) LaunchTempFile(prefix, suffix string, r io.Reader) ([]byte, stri
|
|||||||
os.Remove(path)
|
os.Remove(path)
|
||||||
return nil, path, err
|
return nil, path, err
|
||||||
}
|
}
|
||||||
|
// This file descriptor needs to close so the next process (Launch) can claim it.
|
||||||
|
f.Close()
|
||||||
if err := e.Launch(path); err != nil {
|
if err := e.Launch(path); err != nil {
|
||||||
return nil, path, err
|
return nil, path, err
|
||||||
}
|
}
|
||||||
@ -197,3 +209,10 @@ func randSeq(n int) string {
|
|||||||
}
|
}
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func platformize(linux, windows string) string {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
return windows
|
||||||
|
}
|
||||||
|
return linux
|
||||||
|
}
|
||||||
|
57
pkg/util/crlf.go
Normal file
57
pkg/util/crlf.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 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 util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type crlfWriter struct {
|
||||||
|
io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCRLFWriter implements a CR/LF line ending writer used for normalizing
|
||||||
|
// text for Windows platforms.
|
||||||
|
func NewCRLFWriter(w io.Writer) io.Writer {
|
||||||
|
return crlfWriter{w}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w crlfWriter) Write(b []byte) (n int, err error) {
|
||||||
|
for i, written := 0, 0; ; {
|
||||||
|
next := bytes.Index(b[i:], []byte("\n"))
|
||||||
|
if next == -1 {
|
||||||
|
n, err := w.Writer.Write(b[i:])
|
||||||
|
return written + n, err
|
||||||
|
}
|
||||||
|
next = next + i
|
||||||
|
n, err := w.Writer.Write(b[i:next])
|
||||||
|
if err != nil {
|
||||||
|
return written + n, err
|
||||||
|
}
|
||||||
|
written += n
|
||||||
|
n, err = w.Writer.Write([]byte("\r\n"))
|
||||||
|
if err != nil {
|
||||||
|
if n > 1 {
|
||||||
|
n = 1
|
||||||
|
}
|
||||||
|
return written + n, err
|
||||||
|
}
|
||||||
|
written += 1
|
||||||
|
i = next + 1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user