mirror of https://github.com/k3s-io/k3s
edit: Windows fixes
Contains the following fixes for Windows users of kubectl edit: * Defaults to notepad as the default Windows editor * Uses CRLF line endings * Ensures a file lock is freedpull/6/head
parent
e05819f36a
commit
73713ce268
|
@ -498,6 +498,7 @@ _kubectl_edit()
|
|||
flags+=("--output=")
|
||||
two_word_flags+=("-o")
|
||||
flags+=("--output-version=")
|
||||
flags+=("--windows-line-endings")
|
||||
|
||||
must_have_one_flag=()
|
||||
must_have_one_noun=()
|
||||
|
|
|
@ -18,15 +18,16 @@ Edit a resource from the default editor.
|
|||
.PP
|
||||
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,
|
||||
or EDITOR environment variables, or fall back to 'vi'. You can edit multiple objects,
|
||||
although changes are applied one at a time. The command accepts filenames as well as
|
||||
command line arguments, although the files you point to must be previously saved
|
||||
versions of resources.
|
||||
or EDITOR environment variables, or fall back to 'vi' for Linux or 'notepad' for Windows.
|
||||
You can edit multiple objects, although changes are applied one at a time. The command
|
||||
accepts filenames as well as command line arguments, although the files you point to must
|
||||
be previously saved versions of resources.
|
||||
|
||||
.PP
|
||||
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
|
||||
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
|
||||
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=""
|
||||
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
|
||||
.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
|
||||
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,
|
||||
although changes are applied one at a time. The command accepts filenames as well as
|
||||
command line arguments, although the files you point to must be previously saved
|
||||
versions of resources.
|
||||
or EDITOR environment variables, or fall back to 'vi' for Linux or 'notepad' for Windows.
|
||||
You can edit multiple objects, although changes are applied one at a time. The command
|
||||
accepts filenames as well as command line arguments, although the files you point to must
|
||||
be previously saved versions of resources.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
-o, --output="yaml": Output format. One of: yaml|json.
|
||||
--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
|
||||
|
@ -114,7 +116,7 @@ kubectl edit (RESOURCE/NAME | -f FILENAME)
|
|||
|
||||
* [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 -->
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_edit.md?pixel)]()
|
||||
|
|
|
@ -485,6 +485,10 @@ runTests() {
|
|||
kube::test::get_object_assert pods "{{range.items}}{{$image_field}}:{{end}}" 'gcr.io/google_containers/serve_hostname:'
|
||||
# cleaning
|
||||
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
|
||||
# Pre-condition: name is valid-pod
|
||||
|
|
|
@ -304,6 +304,7 @@ user-whitelist
|
|||
watch-cache
|
||||
watch-only
|
||||
whitelist-override-label
|
||||
windows-line-endings
|
||||
www-prefix
|
||||
retry_time
|
||||
file_content_in_loop
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"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/jsonmerge"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/pkg/util/strategicpatch"
|
||||
"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
|
||||
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,
|
||||
although changes are applied one at a time. The command accepts filenames as well as
|
||||
command line arguments, although the files you point to must be previously saved
|
||||
versions of resources.
|
||||
or EDITOR environment variables, or fall back to 'vi' for Linux or 'notepad' for Windows.
|
||||
You can edit multiple objects, although changes are applied one at a time. The command
|
||||
accepts filenames as well as command line arguments, although the files you point to must
|
||||
be previously saved versions of resources.
|
||||
|
||||
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
|
||||
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
|
||||
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)
|
||||
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().Bool("windows-line-endings", runtime.GOOS == "windows", "Use Windows line-endings (default Unix line-endings)")
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -142,6 +146,8 @@ func RunEdit(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin
|
|||
return err
|
||||
}
|
||||
|
||||
windowsLineEndings := cmdutil.GetFlagBool(cmd, "windows-line-endings")
|
||||
edit := editor.NewDefaultEditor()
|
||||
defaultVersion := cmdutil.OutputVersion(cmd, clientConfig.Version)
|
||||
results := editResults{}
|
||||
for {
|
||||
|
@ -156,16 +162,19 @@ func RunEdit(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin
|
|||
|
||||
// generate the file to edit
|
||||
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)
|
||||
}
|
||||
if err := printer.PrintObj(obj, buf); err != nil {
|
||||
if err := printer.PrintObj(obj, w); err != nil {
|
||||
return preservedFile(err, results.file, out)
|
||||
}
|
||||
original := buf.Bytes()
|
||||
|
||||
// launch the editor
|
||||
edit := editor.NewDefaultEditor()
|
||||
edited, file, err := edit.LaunchTempFile("kubectl-edit-", ext, buf)
|
||||
if err != nil {
|
||||
return preservedFile(err, results.file, out)
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/term"
|
||||
|
@ -33,8 +34,13 @@ import (
|
|||
|
||||
const (
|
||||
// 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"
|
||||
defaultShell = "/bin/bash"
|
||||
windowsEditor = "notepad"
|
||||
windowsShell = "cmd"
|
||||
)
|
||||
|
||||
type Editor struct {
|
||||
|
@ -58,15 +64,19 @@ func NewDefaultEditor() Editor {
|
|||
func defaultEnvShell() []string {
|
||||
shell := os.Getenv("SHELL")
|
||||
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) {
|
||||
editor := os.Getenv("EDITOR")
|
||||
if len(editor) == 0 {
|
||||
editor = defaultEditor
|
||||
editor = platformize(defaultEditor, windowsEditor)
|
||||
}
|
||||
if !strings.Contains(editor, " ") {
|
||||
return []string{editor}, false
|
||||
|
@ -133,6 +143,8 @@ func (e Editor) LaunchTempFile(prefix, suffix string, r io.Reader) ([]byte, stri
|
|||
os.Remove(path)
|
||||
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 {
|
||||
return nil, path, err
|
||||
}
|
||||
|
@ -197,3 +209,10 @@ func randSeq(n int) string {
|
|||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func platformize(linux, windows string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return windows
|
||||
}
|
||||
return linux
|
||||
}
|
||||
|
|
|
@ -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