mirror of https://github.com/k3s-io/k3s
Add --watch to get command
parent
0348a67413
commit
02a0593df0
|
@ -20,6 +20,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -50,7 +51,7 @@ Examples:
|
|||
mapping, namespace, name := ResourceOrTypeFromArgs(cmd, args, f.Mapper)
|
||||
|
||||
selector := GetFlagString(cmd, "selector")
|
||||
labels, err := labels.ParseSelector(selector)
|
||||
labelSelector, err := labels.ParseSelector(selector)
|
||||
checkErr(err)
|
||||
|
||||
client, err := f.Client(cmd, mapping)
|
||||
|
@ -68,12 +69,26 @@ Examples:
|
|||
printer, err := kubectl.GetPrinter(outputVersion, outputFormat, templateFile, defaultPrinter)
|
||||
checkErr(err)
|
||||
|
||||
obj, err := kubectl.NewRESTHelper(client, mapping).Get(namespace, name, labels)
|
||||
restHelper := kubectl.NewRESTHelper(client, mapping)
|
||||
obj, err := restHelper.Get(namespace, name, labelSelector)
|
||||
checkErr(err)
|
||||
|
||||
if err := printer.PrintObj(obj, out); err != nil {
|
||||
checkErr(fmt.Errorf("Unable to output the provided object: %v", err))
|
||||
}
|
||||
|
||||
if GetFlagBool(cmd, "watch") {
|
||||
vi, err := latest.InterfacesFor(outputVersion)
|
||||
checkErr(err)
|
||||
|
||||
rv, err := vi.MetadataAccessor.ResourceVersion(obj)
|
||||
checkErr(err)
|
||||
|
||||
w, err := restHelper.Watch(namespace, rv, labelSelector, labels.Set{}.AsSelector())
|
||||
checkErr(err)
|
||||
|
||||
kubectl.WatchLoop(w, printer, out)
|
||||
}
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringP("output", "o", "", "Output format: json|yaml|template|templatefile")
|
||||
|
@ -81,5 +96,6 @@ Examples:
|
|||
cmd.Flags().Bool("no-headers", false, "When using the default output, don't print headers")
|
||||
cmd.Flags().StringP("template", "t", "", "Template string or path to template file to use when --output=template or --output=templatefile")
|
||||
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
|
||||
cmd.Flags().BoolP("watch", "w", false, "After listing/getting the requested object, watch for changes.")
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -154,10 +154,14 @@ type handlerEntry struct {
|
|||
printFunc reflect.Value
|
||||
}
|
||||
|
||||
// HumanReadablePrinter is an implementation of ResourcePrinter which attempts to provide more elegant output.
|
||||
// HumanReadablePrinter is an implementation of ResourcePrinter which attempts to provide
|
||||
// more elegant output. It is not threadsafe, but you may call PrintObj repeatedly; headers
|
||||
// will only be printed if the object type changes. This makes it useful for printing items
|
||||
// recieved from watches.
|
||||
type HumanReadablePrinter struct {
|
||||
handlerMap map[reflect.Type]*handlerEntry
|
||||
noHeaders bool
|
||||
lastType reflect.Type
|
||||
}
|
||||
|
||||
// IsVersioned returns false-- human readable printers do not make versioned output.
|
||||
|
@ -348,9 +352,11 @@ func printEventList(list *api.EventList, w io.Writer) error {
|
|||
func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) error {
|
||||
w := tabwriter.NewWriter(output, 20, 5, 3, ' ', 0)
|
||||
defer w.Flush()
|
||||
if handler := h.handlerMap[reflect.TypeOf(obj)]; handler != nil {
|
||||
if !h.noHeaders {
|
||||
t := reflect.TypeOf(obj)
|
||||
if handler := h.handlerMap[t]; handler != nil {
|
||||
if !h.noHeaders && t != h.lastType {
|
||||
h.printHeader(handler.columns, w)
|
||||
h.lastType = t
|
||||
}
|
||||
args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(w)}
|
||||
resultValue := handler.printFunc.Call(args)[0]
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// RESTHelper provides methods for retrieving or mutating a RESTful
|
||||
|
@ -49,6 +50,17 @@ func (m *RESTHelper) Get(namespace, name string, selector labels.Selector) (runt
|
|||
return m.RESTClient.Get().Path(m.Resource).Namespace(namespace).Path(name).SelectorParam("labels", selector).Do().Get()
|
||||
}
|
||||
|
||||
func (m *RESTHelper) Watch(namespace, resourceVersion string, labelSelector, fieldSelector labels.Selector) (watch.Interface, error) {
|
||||
return m.RESTClient.Get().
|
||||
Path("watch").
|
||||
Path(m.Resource).
|
||||
Namespace(namespace).
|
||||
Param("resourceVersion", resourceVersion).
|
||||
SelectorParam("labels", labelSelector).
|
||||
SelectorParam("fields", fieldSelector).
|
||||
Watch()
|
||||
}
|
||||
|
||||
func (m *RESTHelper) Delete(namespace, name string) error {
|
||||
return m.RESTClient.Delete().Path(m.Resource).Namespace(namespace).Path(name).Do().Error()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. 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 kubectl
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// WatchLoop loops, writing objects in the events from w to printer.
|
||||
// If user sends interrupt signal, shut down cleanly. Otherwise, never return.
|
||||
func WatchLoop(w watch.Interface, printer ResourcePrinter, out io.Writer) {
|
||||
signals := make(chan os.Signal, 1)
|
||||
signal.Notify(signals, os.Interrupt)
|
||||
defer signal.Stop(signals)
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-w.ResultChan():
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
// TODO: need to print out added/modified/deleted!
|
||||
if err := printer.PrintObj(event.Object, out); err != nil {
|
||||
w.Stop()
|
||||
}
|
||||
case <-signals:
|
||||
w.Stop()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue