checkpoint
parent
4bf67dd4e1
commit
67884d1735
6
go.mod
6
go.mod
|
|
@ -47,15 +47,19 @@ require (
|
|||
github.com/hashicorp/golang-lru v0.5.1 // indirect
|
||||
github.com/imdario/mergo v0.3.7 // indirect
|
||||
github.com/json-iterator/go v1.1.6 // indirect
|
||||
github.com/junegunn/fzf v0.0.0-20190808063552-509589924557
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/ktr0731/go-fuzzyfinder v0.1.2
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.4
|
||||
github.com/onsi/ginkgo v1.8.0 // indirect
|
||||
github.com/onsi/gomega v1.5.0 // indirect
|
||||
github.com/petergtz/pegomock v0.0.0-20181206220228-b113d17a7e81
|
||||
github.com/rakyll/hey v0.1.2
|
||||
github.com/rs/zerolog v1.14.3
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/sahilm/fuzzy v0.1.0
|
||||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/pflag v1.0.3 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 // indirect
|
||||
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6 // indirect
|
||||
|
|
|
|||
22
go.sum
22
go.sum
|
|
@ -94,8 +94,10 @@ github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8
|
|||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gdamore/encoding v0.0.0-20151215212835-b23993cbb635/go.mod h1:yrQYJKKDTrHmbYxI7CYi+/hbdiDT2m4Hj+t0ikCjsrQ=
|
||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||
github.com/gdamore/tcell v0.0.0-20170915061752-0a0db94084df/go.mod h1:tqyG50u7+Ctv1w5VX67kLzKcj9YXR/JSBZQq/+mLl1A=
|
||||
github.com/gdamore/tcell v1.1.1 h1:U73YL+jMem2XfhvaIUfPO6MpJawaG92B2funXVb9qLs=
|
||||
github.com/gdamore/tcell v1.1.1/go.mod h1:K1udHkiR3cOtlpKG5tZPD5XxrF7v2y7lDq7Whcj+xkQ=
|
||||
github.com/gdamore/tcell v1.1.2 h1:Afe8cU6SECC06UmvaJ55Jr3Eh0tz/ywLjqWYqjGZp3s=
|
||||
|
|
@ -167,6 +169,7 @@ github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:
|
|||
github.com/gophercloud/gophercloud v0.0.0-20190427020117-60507118a582 h1:04A8HIFV8Ix2XtGB6BiLpygW6ILmO8ZTc+fMnUDPCeo=
|
||||
github.com/gophercloud/gophercloud v0.0.0-20190427020117-60507118a582/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
|
|
@ -198,7 +201,10 @@ github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwK
|
|||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jteeuwen/go-bindata v0.0.0-20151023091102-a0ff2567cfb7/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/junegunn/fzf v0.0.0-20190808063552-509589924557 h1:KLUZiqiMfcwH3YItRzwxIWGFEVg8qjvxIyaWFNaQ1lE=
|
||||
github.com/junegunn/fzf v0.0.0-20190808063552-509589924557/go.mod h1:mW81EF7s4wSvB4dnjrdXv/kCV+eAOXL4vqVT9h8aXsw=
|
||||
github.com/kardianos/osext v0.0.0-20150410034420-8fef92e41e22/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
|
|
@ -215,10 +221,13 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/ktr0731/go-fuzzyfinder v0.1.2 h1:Y+Vm86X/QmE/+DitA2RrLndZU134cZtBUOtO18CTVcE=
|
||||
github.com/ktr0731/go-fuzzyfinder v0.1.2/go.mod h1:RzAqRU8h8f4uSLSP+THd87krOFnBploGlGn/8RQhd7M=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/libopenstorage/openstorage v0.0.0-20170906232338-093a0c388875/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
|
||||
github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA=
|
||||
github.com/lucasb-eyer/go-colorful v0.0.0-20170223221042-c900de9dbbc7/go.mod h1:NXg0ArsFk0Y01623LgUqoqcouGDB+PwCCQlrwrG6xJ4=
|
||||
github.com/lucasb-eyer/go-colorful v0.0.0-20181028223441-12d3b2882a08 h1:5MnxBC15uMxFv5FY/J/8vzyaBiArCOkMdFT9Jsw78iY=
|
||||
github.com/lucasb-eyer/go-colorful v0.0.0-20181028223441-12d3b2882a08/go.mod h1:NXg0ArsFk0Y01623LgUqoqcouGDB+PwCCQlrwrG6xJ4=
|
||||
<<<<<<< HEAD
|
||||
|
|
@ -235,10 +244,17 @@ github.com/magiconair/properties v0.0.0-20160816085511-61b492c03cf4/go.mod h1:Pp
|
|||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> update to k8s 1.15.1
|
||||
=======
|
||||
github.com/mattn/go-isatty v0.0.0-20160806122752-66b8e73f3f5c h1:3nKFouDdpgGUV/uerJcYWH45ZbJzX0SiVWfTgmUeTzc=
|
||||
github.com/mattn/go-isatty v0.0.0-20160806122752-66b8e73f3f5c/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.0-20170201023540-14207d285c6c/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
>>>>>>> checkpoint
|
||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-shellwords v0.0.0-20180605041737-f8471b0a71de/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
<<<<<<< HEAD
|
||||
|
|
@ -340,12 +356,15 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
|
|||
=======
|
||||
github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
|
||||
github.com/russross/blackfriday v0.0.0-20151117072312-300106c228d5/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
|
||||
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/seccomp/libseccomp-golang v0.0.0-20150813023252-1b506fc7c24e/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20151028001915-10ef21a441db/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sigma/go-inotify v0.0.0-20181102212354-c87b6cf5033d/go.mod h1:stlh9OsqBQSdwxTxX73mu41BBtRbIpZLQ7flcAoxAfo=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spf13/afero v0.0.0-20160816080757-b28a7effac97 h1:Gv1HykSEG+RKWWWkM69nPrJKhE/EM2oFb1nBWogHNv8=
|
||||
|
|
@ -386,6 +405,7 @@ github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxt
|
|||
go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20170728183002-558b6879de74/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
<<<<<<< HEAD
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
|
@ -434,8 +454,10 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae h1:mQLHiymj/JXKnnjc62tb7nD5pZLs940/sXJu+Xp3DBA=
|
||||
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10=
|
||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170530162606-4ee4af566555/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"github.com/derailed/k9s/internal/resource"
|
||||
)
|
||||
|
||||
// TableListener tracks tabular data changes.
|
||||
type TableListener interface {
|
||||
Refreshed(resource.TableData)
|
||||
RowAdded(resource.RowEvent)
|
||||
RowUpdated(resource.RowEvent)
|
||||
RowDeleted(resource.RowEvent)
|
||||
}
|
||||
|
||||
// Table represents tabular data.
|
||||
type Table struct {
|
||||
data resource.TableData
|
||||
|
||||
listeners []TableListener
|
||||
}
|
||||
|
||||
// NewTable returns a new table.
|
||||
func NewTable() *Table {
|
||||
return &Table{}
|
||||
}
|
||||
|
||||
// Load the initial tabular data
|
||||
func (t *Table) Load(data resource.TableData) {
|
||||
t.data = data
|
||||
t.fireTableRefreshed()
|
||||
}
|
||||
|
||||
func (t *Table) fireTableRefreshed() {
|
||||
for _, l := range t.listeners {
|
||||
l.Refreshed(t.data)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package views
|
||||
package perf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/resource"
|
||||
"github.com/rakyll/hey/requester"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
|
@ -20,24 +21,26 @@ const (
|
|||
k9sUA = "k9s/0.0.7"
|
||||
)
|
||||
|
||||
// K9sBenchDir directory to store K9s benchmark files.
|
||||
// K9sBenchDir directory to store K9s Benchmark files.
|
||||
var K9sBenchDir = filepath.Join(os.TempDir(), fmt.Sprintf("k9s-bench-%s", config.MustK9sUser()))
|
||||
|
||||
type benchmark struct {
|
||||
// Benchmark puts a workload under load.
|
||||
type Benchmark struct {
|
||||
canceled bool
|
||||
config config.BenchConfig
|
||||
worker *requester.Work
|
||||
}
|
||||
|
||||
func newBenchmark(base string, cfg config.BenchConfig) (*benchmark, error) {
|
||||
b := benchmark{config: cfg}
|
||||
// NewBenchmark returns a new benchmark.
|
||||
func NewBenchmark(base string, cfg config.BenchConfig) (*Benchmark, error) {
|
||||
b := Benchmark{config: cfg}
|
||||
if err := b.init(base); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &b, nil
|
||||
}
|
||||
|
||||
func (b *benchmark) init(base string) error {
|
||||
func (b *Benchmark) init(base string) error {
|
||||
req, err := http.NewRequest(b.config.HTTP.Method, base, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -71,11 +74,12 @@ func (b *benchmark) init(base string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *benchmark) annulled() bool {
|
||||
func (b *Benchmark) annulled() bool {
|
||||
return b.canceled
|
||||
}
|
||||
|
||||
func (b *benchmark) cancel() {
|
||||
// Cancel kills the benchmark in progress.
|
||||
func (b *Benchmark) Cancel() {
|
||||
if b == nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -83,25 +87,31 @@ func (b *benchmark) cancel() {
|
|||
b.worker.Stop()
|
||||
}
|
||||
|
||||
func (b *benchmark) run(cluster string, done func()) {
|
||||
// Canceled checks if the benchmark was canceled.
|
||||
func (b *Benchmark) Canceled() bool {
|
||||
return b.canceled
|
||||
}
|
||||
|
||||
// Run starts a benchmark,
|
||||
func (b *Benchmark) Run(cluster string, done func()) {
|
||||
buff := new(bytes.Buffer)
|
||||
b.worker.Writer = buff
|
||||
b.worker.Run()
|
||||
if !b.canceled {
|
||||
if err := b.save(cluster, buff); err != nil {
|
||||
log.Error().Err(err).Msg("Saving benchmark")
|
||||
log.Error().Err(err).Msg("Saving Benchmark")
|
||||
}
|
||||
}
|
||||
done()
|
||||
}
|
||||
|
||||
func (b *benchmark) save(cluster string, r io.Reader) error {
|
||||
func (b *Benchmark) save(cluster string, r io.Reader) error {
|
||||
dir := filepath.Join(K9sBenchDir, cluster)
|
||||
if err := os.MkdirAll(dir, 0744); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ns, n := namespaced(b.config.Name)
|
||||
ns, n := resource.Namespaced(b.config.Name)
|
||||
file := filepath.Join(dir, fmt.Sprintf(benchFmat, ns, n, time.Now().UnixNano()))
|
||||
f, err := os.Create(file)
|
||||
if err != nil {
|
||||
|
|
@ -108,7 +108,7 @@ func (*Base) ExtFields() Properties {
|
|||
|
||||
// Get a resource by name
|
||||
func (b *Base) Get(path string) (Columnar, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := b.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -157,7 +157,7 @@ func (b *Base) Describe(kind, pa string) (string, error) {
|
|||
}
|
||||
|
||||
func (b *Base) doDescribe(pa string, mapping *meta.RESTMapping) (string, error) {
|
||||
ns, n := namespaced(pa)
|
||||
ns, n := Namespaced(pa)
|
||||
d, err := versioned.Describer(b.Connection.Config().Flags(), mapping)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("Unable to find describer for %#v", mapping)
|
||||
|
|
@ -169,7 +169,7 @@ func (b *Base) doDescribe(pa string, mapping *meta.RESTMapping) (string, error)
|
|||
|
||||
// Delete a resource by name.
|
||||
func (b *Base) Delete(path string, cascade, force bool) error {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
|
||||
return b.Resource.Delete(ns, n, cascade, force)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func (r *ConfigMap) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *ConfigMap) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func (r *ClusterRole) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *ClusterRole) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func (r *ClusterRoleBinding) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *ClusterRoleBinding) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func (r *CustomResourceDefinition) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal a resource.
|
||||
func (r *CustomResourceDefinition) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func (r *CronJob) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *CronJob) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
@ -78,7 +78,7 @@ func (r *CronJob) Marshal(path string) (string, error) {
|
|||
|
||||
// Run a given cronjob.
|
||||
func (r *CronJob) Run(pa string) error {
|
||||
ns, n := namespaced(pa)
|
||||
ns, n := Namespaced(pa)
|
||||
if c, ok := r.Resource.(Runnable); ok {
|
||||
return c.Run(ns, n)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ func (r *Custom) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *Custom) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func (r *Deployment) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *Deployment) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func (r *DaemonSet) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *DaemonSet) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func (r *Endpoints) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *Endpoints) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func (r *Event) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *Event) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -118,7 +118,8 @@ func toPerc(v1, v2 float64) float64 {
|
|||
return (v1 / v2) * 100
|
||||
}
|
||||
|
||||
func namespaced(n string) (string, string) {
|
||||
// Namespaced return a namesapace and a name.
|
||||
func Namespaced(n string) (string, string) {
|
||||
ns, po := path.Split(n)
|
||||
|
||||
return strings.Trim(ns, "/"), po
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ func TestNamespaced(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, u := range uu {
|
||||
ns, n := namespaced(u.p)
|
||||
ns, n := Namespaced(u.p)
|
||||
assert.Equal(t, u.ns, ns)
|
||||
assert.Equal(t, u.n, n)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func (r *HorizontalPodAutoscalerV1) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *HorizontalPodAutoscalerV1) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func (r *HorizontalPodAutoscalerV2Beta1) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *HorizontalPodAutoscalerV2Beta1) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func (r *HorizontalPodAutoscaler) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *HorizontalPodAutoscaler) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func (r *Ingress) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *Ingress) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ func (r *Job) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *Job) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
@ -76,7 +76,7 @@ func (r *Job) Marshal(path string) (string, error) {
|
|||
|
||||
// Containers fetch all the containers on this job, may include init containers.
|
||||
func (r *Job) Containers(path string, includeInit bool) ([]string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
|
||||
return r.Resource.(k8s.Loggable).Containers(ns, n, includeInit)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ func (r *Node) List(ns string) (Columnars, error) {
|
|||
|
||||
// Marshal a resource to yaml.
|
||||
func (r *Node) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
log.Error().Err(err)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func (r *Namespace) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal a resource to yaml.
|
||||
func (r *Namespace) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
log.Error().Err(err)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ func (r *PodDisruptionBudget) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *PodDisruptionBudget) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ func (r *Pod) SetPodMetrics(m *mv1beta1.PodMetrics) {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *Pod) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
@ -113,7 +113,7 @@ func (r *Pod) Marshal(path string) (string, error) {
|
|||
|
||||
// Containers lists out all the docker containers name contained in a pod.
|
||||
func (r *Pod) Containers(path string, includeInit bool) ([]string, error) {
|
||||
ns, po := namespaced(path)
|
||||
ns, po := Namespaced(path)
|
||||
|
||||
return r.Resource.(k8s.Loggable).Containers(ns, po, includeInit)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func (r *PersistentVolume) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *PersistentVolume) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func (r *PersistentVolumeClaim) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *PersistentVolumeClaim) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func (r *ReplicationController) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal a deployment given a namespaced name.
|
||||
func (r *ReplicationController) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func (r *Role) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *Role) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func (r *RoleBinding) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *RoleBinding) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func (r *ReplicaSet) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal a deployment given a namespaced name.
|
||||
func (r *ReplicaSet) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func (r *ServiceAccount) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *ServiceAccount) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func (r *Secret) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *Secret) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func (r *StatefulSet) New(i interface{}) Columnar {
|
|||
|
||||
// Marshal resource to yaml.
|
||||
func (r *StatefulSet) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ func (r *Service) New(i interface{}) Columnar {
|
|||
// Marshal resource to yaml.
|
||||
// BOZO!! Why you need to fill type info??
|
||||
func (r *Service) Marshal(path string) (string, error) {
|
||||
ns, n := namespaced(path)
|
||||
ns, n := Namespaced(path)
|
||||
i, err := r.Resource.Get(ns, n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -3,15 +3,16 @@ package ui
|
|||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/resource"
|
||||
"github.com/derailed/tview"
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/ktr0731/go-fuzzyfinder/matching"
|
||||
|
||||
// "github.com/ktr0731/go-fuzzyfinder/matching"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/sahilm/fuzzy"
|
||||
"k8s.io/apimachinery/pkg/util/duration"
|
||||
)
|
||||
|
||||
|
|
@ -79,11 +80,6 @@ func (v *Table) AddSelectedRowListener(f SelectedRowFunc) {
|
|||
}
|
||||
|
||||
func (v *Table) selChanged(r, c int) {
|
||||
// Changed?
|
||||
if v.selectedRow == r {
|
||||
return
|
||||
}
|
||||
|
||||
v.selectedRow = r
|
||||
v.updateSelectedItem(r)
|
||||
if r == 0 {
|
||||
|
|
@ -104,7 +100,7 @@ func (v *Table) selChanged(r, c int) {
|
|||
|
||||
// UpdateSelection refresh selected row.
|
||||
func (v *Table) updateSelection(broadcast bool) {
|
||||
v.SelectRow(v.selectedRow, false)
|
||||
v.SelectRow(v.selectedRow, broadcast)
|
||||
}
|
||||
|
||||
// SelectRow select a given row by index.
|
||||
|
|
@ -221,13 +217,13 @@ func (v *Table) SetSortCol(index, count int, asc bool) {
|
|||
// Update table content.
|
||||
func (v *Table) Update(data resource.TableData) {
|
||||
v.data = data
|
||||
if !v.cmdBuff.Empty() {
|
||||
v.doUpdate(v.filtered())
|
||||
} else {
|
||||
if v.cmdBuff.Empty() {
|
||||
v.doUpdate(v.data)
|
||||
} else {
|
||||
v.doUpdate(v.filtered())
|
||||
}
|
||||
v.UpdateTitle()
|
||||
v.updateSelection(false)
|
||||
v.updateSelection(true)
|
||||
}
|
||||
|
||||
func (v *Table) doUpdate(data resource.TableData) {
|
||||
|
|
@ -368,33 +364,6 @@ func (v *Table) AddHeaderCell(numerical bool, col int, name string) {
|
|||
v.SetCell(0, col, c)
|
||||
}
|
||||
|
||||
// BOZO!! Nuke?
|
||||
// func (v *Table) depFiltered() resource.TableData {
|
||||
// if v.cmdBuff.Empty() || isLabelSelector(v.cmdBuff.String()) {
|
||||
// return v.data
|
||||
// }
|
||||
|
||||
// rx, err := regexp.Compile(`(?i)` + v.cmdBuff.String())
|
||||
// if err != nil {
|
||||
// v.cmdBuff.Clear()
|
||||
// return v.data
|
||||
// }
|
||||
|
||||
// filtered := resource.TableData{
|
||||
// Header: v.data.Header,
|
||||
// Rows: resource.RowEvents{},
|
||||
// Namespace: v.data.Namespace,
|
||||
// }
|
||||
// for k, row := range v.data.Rows {
|
||||
// f := strings.Join(row.Fields, " ")
|
||||
// if rx.MatchString(f) {
|
||||
// filtered.Rows[k] = row
|
||||
// }
|
||||
// }
|
||||
|
||||
// return filtered
|
||||
// }
|
||||
|
||||
func (v *Table) filtered() resource.TableData {
|
||||
if v.cmdBuff.Empty() || isLabelSelector(v.cmdBuff.String()) {
|
||||
return v.data
|
||||
|
|
@ -403,7 +372,7 @@ func (v *Table) filtered() resource.TableData {
|
|||
q := v.cmdBuff.String()
|
||||
var ss, kk []string
|
||||
for k, row := range v.data.Rows {
|
||||
ss = append(ss, strings.Join(row.Fields, " "))
|
||||
ss = append(ss, row.Fields[v.NameColIndex()])
|
||||
kk = append(kk, k)
|
||||
}
|
||||
|
||||
|
|
@ -412,9 +381,9 @@ func (v *Table) filtered() resource.TableData {
|
|||
Rows: resource.RowEvents{},
|
||||
Namespace: v.data.Namespace,
|
||||
}
|
||||
mm := matching.FindAll(q, ss)
|
||||
mm := fuzzy.Find(q, ss)
|
||||
for _, m := range mm {
|
||||
filtered.Rows[kk[m.Idx]] = v.data.Rows[kk[m.Idx]]
|
||||
filtered.Rows[kk[m.Index]] = v.data.Rows[kk[m.Index]]
|
||||
}
|
||||
|
||||
return filtered
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/perf"
|
||||
"github.com/derailed/k9s/internal/resource"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/derailed/tview"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
|
@ -35,38 +35,42 @@ var (
|
|||
)
|
||||
|
||||
type benchView struct {
|
||||
*tview.Pages
|
||||
*masterDetail
|
||||
|
||||
app *appView
|
||||
cancel context.CancelFunc
|
||||
selectedItem string
|
||||
selectedRow int
|
||||
actions ui.KeyActions
|
||||
app *appView
|
||||
}
|
||||
|
||||
func newBenchView(_ string, app *appView, _ resource.List) resourceViewer {
|
||||
v := benchView{
|
||||
Pages: tview.NewPages(),
|
||||
actions: make(ui.KeyActions),
|
||||
app: app,
|
||||
}
|
||||
func newBenchView(title string, app *appView, _ resource.List) resourceViewer {
|
||||
v := benchView{app: app}
|
||||
v.masterDetail = newMasterDetail(benchTitle, "", app, v.backCmd)
|
||||
v.keyBindings()
|
||||
|
||||
tv := newTableView(app, benchTitle)
|
||||
tv.SetSelectionChangedFunc(v.selChanged)
|
||||
return &v
|
||||
}
|
||||
|
||||
// Init the view.
|
||||
func (v *benchView) Init(ctx context.Context, ns string) {
|
||||
v.masterDetail.init(ctx, ns)
|
||||
|
||||
tv := v.masterPage()
|
||||
tv.SetBorderFocusColor(tcell.ColorSeaGreen)
|
||||
tv.SetSelectedStyle(tcell.ColorWhite, tcell.ColorSeaGreen, tcell.AttrNone)
|
||||
tv.SetColorerFn(benchColorer)
|
||||
tv.SetActiveNS("")
|
||||
v.AddPage("table", tv, true, true)
|
||||
|
||||
details := newDetailsView(app, v.backCmd)
|
||||
details.setCategory("Bench")
|
||||
details.SetTextColor(app.Styles.FgColor())
|
||||
v.AddPage("details", details, true, false)
|
||||
dv := v.detailsPage()
|
||||
dv.setCategory("Bench")
|
||||
dv.SetTextColor(tcell.ColorSeaGreen)
|
||||
|
||||
v.registerActions()
|
||||
if err := v.watchBenchDir(ctx); err != nil {
|
||||
v.app.Flash().Errf("Unable to watch benchmarks directory %s", err)
|
||||
}
|
||||
|
||||
return &v
|
||||
v.refresh()
|
||||
tv.SetSortCol(tv.NameColIndex()+7, 0, true)
|
||||
tv.Refresh()
|
||||
tv.Select(1, 0)
|
||||
v.app.SetFocus(tv)
|
||||
v.app.SetHints(tv.Hints())
|
||||
}
|
||||
|
||||
func (v *benchView) setEnterFn(enterFn) {}
|
||||
|
|
@ -74,54 +78,28 @@ func (v *benchView) setColorerFn(ui.ColorerFunc) {}
|
|||
func (v *benchView) setDecorateFn(decorateFn) {}
|
||||
func (v *benchView) setExtraActionsFn(ui.ActionsFunc) {}
|
||||
|
||||
// Init the view.
|
||||
func (v *benchView) Init(ctx context.Context, _ string) {
|
||||
if err := v.watchBenchDir(ctx); err != nil {
|
||||
v.app.Flash().Errf("Unable to watch benchmarks directory %s", err)
|
||||
}
|
||||
|
||||
v.refresh()
|
||||
tv := v.getTV()
|
||||
tv.SetSortCol(tv.NameColIndex()+7, 0, true)
|
||||
tv.Refresh()
|
||||
tv.Select(1, 0)
|
||||
v.app.SetFocus(tv)
|
||||
}
|
||||
|
||||
func (v *benchView) refresh() {
|
||||
tv := v.getTV()
|
||||
tv := v.masterPage()
|
||||
tv.Update(v.hydrate())
|
||||
tv.UpdateTitle()
|
||||
v.selChanged(v.selectedRow, 0)
|
||||
}
|
||||
|
||||
func (v *benchView) registerActions() {
|
||||
v.actions[ui.KeyP] = ui.NewKeyAction("Previous", v.app.prevCmd, false)
|
||||
v.actions[tcell.KeyEnter] = ui.NewKeyAction("Enter", v.enterCmd, false)
|
||||
v.actions[tcell.KeyCtrlD] = ui.NewKeyAction("Delete", v.deleteCmd, false)
|
||||
|
||||
vu := v.getTV()
|
||||
vu.SetActions(v.actions)
|
||||
v.app.SetHints(vu.Hints())
|
||||
func (v *benchView) keyBindings() {
|
||||
aa := ui.KeyActions{
|
||||
ui.KeyP: ui.NewKeyAction("Previous", v.app.prevCmd, false),
|
||||
tcell.KeyEnter: ui.NewKeyAction("Enter", v.enterCmd, false),
|
||||
tcell.KeyCtrlD: ui.NewKeyAction("Delete", v.deleteCmd, false),
|
||||
}
|
||||
v.masterPage().SetActions(aa)
|
||||
}
|
||||
|
||||
func (v *benchView) getTitle() string {
|
||||
return benchTitle
|
||||
}
|
||||
|
||||
func (v *benchView) selChanged(r, c int) {
|
||||
tv := v.getTV()
|
||||
if r == 0 || tv.GetCell(r, 0) == nil {
|
||||
v.selectedItem = ""
|
||||
return
|
||||
}
|
||||
v.selectedRow = r
|
||||
v.selectedItem = ui.TrimCell(tv.Table, r, 7)
|
||||
}
|
||||
|
||||
func (v *benchView) sortColCmd(col int, asc bool) func(evt *tcell.EventKey) *tcell.EventKey {
|
||||
return func(evt *tcell.EventKey) *tcell.EventKey {
|
||||
tv := v.getTV()
|
||||
tv := v.masterPage()
|
||||
tv.SetSortCol(tv.NameColIndex()+col, 0, asc)
|
||||
tv.Refresh()
|
||||
|
||||
|
|
@ -130,39 +108,39 @@ func (v *benchView) sortColCmd(col int, asc bool) func(evt *tcell.EventKey) *tce
|
|||
}
|
||||
|
||||
func (v *benchView) enterCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
if v.getTV().Cmd().IsActive() {
|
||||
return v.getTV().filterCmd(evt)
|
||||
if v.masterPage().Cmd().IsActive() {
|
||||
return v.masterPage().filterCmd(evt)
|
||||
}
|
||||
if v.selectedItem == "" {
|
||||
|
||||
if !v.masterPage().RowSelected() {
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err := readBenchFile(v.app.Config, v.selectedItem)
|
||||
data, err := readBenchFile(v.app.Config, v.benchFile())
|
||||
if err != nil {
|
||||
v.app.Flash().Errf("Unable to load bench file %s", err)
|
||||
return nil
|
||||
}
|
||||
vu := v.getDetails()
|
||||
vu := v.detailsPage()
|
||||
vu.SetText(data)
|
||||
vu.setTitle(v.selectedItem)
|
||||
v.SwitchToPage("details")
|
||||
vu.setTitle(v.masterPage().GetSelectedItem())
|
||||
v.showDetails()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *benchView) deleteCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
sel := v.selectedItem
|
||||
if sel == "" {
|
||||
if !v.masterPage().RowSelected() {
|
||||
return nil
|
||||
}
|
||||
|
||||
dir := filepath.Join(K9sBenchDir, v.app.Config.K9s.CurrentCluster)
|
||||
showModal(v.Pages, fmt.Sprintf("Delete benchmark `%s?", sel), "table", func() {
|
||||
if err := os.Remove(filepath.Join(dir, sel)); err != nil {
|
||||
sel, file := v.masterPage().GetSelectedItem(), v.benchFile()
|
||||
dir := filepath.Join(perf.K9sBenchDir, v.app.Config.K9s.CurrentCluster)
|
||||
showModal(v.Pages, fmt.Sprintf("Delete benchmark `%s?", file), "master", func() {
|
||||
if err := os.Remove(filepath.Join(dir, file)); err != nil {
|
||||
v.app.Flash().Errf("Unable to delete file %s", err)
|
||||
return
|
||||
}
|
||||
v.refresh()
|
||||
v.app.Flash().Infof("Benchmark %s deleted!", sel)
|
||||
})
|
||||
|
||||
|
|
@ -170,14 +148,15 @@ func (v *benchView) deleteCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
}
|
||||
|
||||
func (v *benchView) backCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
if v.cancel != nil {
|
||||
v.cancel()
|
||||
}
|
||||
v.SwitchToPage("table")
|
||||
|
||||
v.showMaster()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *benchView) benchFile() string {
|
||||
r := v.masterPage().GetSelectedRow()
|
||||
return ui.TrimCell(v.masterPage().Table, r, 7)
|
||||
}
|
||||
|
||||
func (v *benchView) hints() ui.Hints {
|
||||
return v.CurrentPage().Item.(ui.Hinter).Hints()
|
||||
}
|
||||
|
|
@ -196,7 +175,10 @@ func (v *benchView) hydrate() resource.TableData {
|
|||
continue
|
||||
}
|
||||
fields := make(resource.Row, len(benchHeader))
|
||||
initRow(fields, f)
|
||||
if err := initRow(fields, f); err != nil {
|
||||
log.Error().Err(err).Msg("Load bench file")
|
||||
continue
|
||||
}
|
||||
augmentRow(fields, bench)
|
||||
data.Rows[f.Name()] = &resource.RowEvent{
|
||||
Action: resource.New,
|
||||
|
|
@ -208,32 +190,19 @@ func (v *benchView) hydrate() resource.TableData {
|
|||
return data
|
||||
}
|
||||
|
||||
func initRow(row resource.Row, f os.FileInfo) {
|
||||
func initRow(row resource.Row, f os.FileInfo) error {
|
||||
tokens := strings.Split(f.Name(), "_")
|
||||
if len(tokens) < 2 {
|
||||
return fmt.Errorf("Invalid file name %s", f.Name())
|
||||
}
|
||||
row[0] = tokens[0]
|
||||
row[1] = tokens[1]
|
||||
row[7] = f.Name()
|
||||
row[8] = time.Since(f.ModTime()).String()
|
||||
}
|
||||
|
||||
func (v *benchView) getTV() *tableView {
|
||||
if vu, ok := v.GetPrimitive("table").(*tableView); ok {
|
||||
return vu
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *benchView) getDetails() *detailsView {
|
||||
if vu, ok := v.GetPrimitive("details").(*detailsView); ok {
|
||||
return vu
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *benchView) resetTitle1() {
|
||||
v.SetTitle(fmt.Sprintf(benchTitleFmt, benchTitle, v.getTV().GetRowCount()-1))
|
||||
}
|
||||
|
||||
func (v *benchView) watchBenchDir(ctx context.Context) error {
|
||||
w, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
|
|
@ -331,7 +300,7 @@ func augmentRow(fields resource.Row, data string) {
|
|||
}
|
||||
|
||||
func benchDir(cfg *config.Config) string {
|
||||
return filepath.Join(K9sBenchDir, cfg.K9s.CurrentCluster)
|
||||
return filepath.Join(perf.K9sBenchDir, cfg.K9s.CurrentCluster)
|
||||
}
|
||||
|
||||
func loadBenchDir(cfg *config.Config) ([]os.FileInfo, error) {
|
||||
|
|
|
|||
|
|
@ -26,14 +26,9 @@ func newDeployView(title string, app *appView, list resource.List) resourceViewe
|
|||
|
||||
func (v *deployView) extraActions(aa ui.KeyActions) {
|
||||
v.logResourceView.extraActions(aa)
|
||||
<<<<<<< HEAD
|
||||
v.scalableResourceView.extraActions(aa)
|
||||
aa[KeyShiftD] = newKeyAction("Sort Desired", v.sortColCmd(2, false), true)
|
||||
aa[KeyShiftC] = newKeyAction("Sort Current", v.sortColCmd(3, false), true)
|
||||
=======
|
||||
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(2, false), true)
|
||||
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(3, false), true)
|
||||
>>>>>>> checkpoint
|
||||
}
|
||||
|
||||
func (v *deployView) showPods(app *appView, _, res, sel string) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/perf"
|
||||
"github.com/derailed/k9s/internal/resource"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/derailed/tview"
|
||||
|
|
@ -27,7 +28,7 @@ type forwardView struct {
|
|||
|
||||
app *appView
|
||||
cancel context.CancelFunc
|
||||
bench *benchmark
|
||||
bench *perf.Benchmark
|
||||
}
|
||||
|
||||
var _ resourceViewer = &forwardView{}
|
||||
|
|
@ -131,7 +132,7 @@ func (v *forwardView) benchStopCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
if v.bench != nil {
|
||||
log.Debug().Msg(">>> Benchmark canceled!!")
|
||||
v.app.status(ui.FlashErr, "Benchmark Camceled!")
|
||||
v.bench.cancel()
|
||||
v.bench.Cancel()
|
||||
}
|
||||
v.app.StatusReset()
|
||||
|
||||
|
|
@ -159,7 +160,7 @@ func (v *forwardView) benchCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
|
||||
base := ui.TrimCell(tv.Table, r, 4)
|
||||
var err error
|
||||
if v.bench, err = newBenchmark(base, cfg); err != nil {
|
||||
if v.bench, err = perf.NewBenchmark(base, cfg); err != nil {
|
||||
v.app.Flash().Errf("Bench failed %v", err)
|
||||
v.app.StatusReset()
|
||||
return nil
|
||||
|
|
@ -173,14 +174,14 @@ func (v *forwardView) benchCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
}
|
||||
|
||||
func (v *forwardView) runBenchmark() {
|
||||
v.bench.run(v.app.Config.K9s.CurrentCluster, func() {
|
||||
v.bench.Run(v.app.Config.K9s.CurrentCluster, func() {
|
||||
log.Debug().Msg("Bench Completed!")
|
||||
v.app.QueueUpdate(func() {
|
||||
if v.bench.canceled {
|
||||
if v.bench.Canceled() {
|
||||
v.app.status(ui.FlashInfo, "Benchmark canceled")
|
||||
} else {
|
||||
v.app.status(ui.FlashInfo, "Benchmark Completed!")
|
||||
v.bench.cancel()
|
||||
v.bench.Cancel()
|
||||
}
|
||||
v.bench = nil
|
||||
go func() {
|
||||
|
|
@ -334,7 +335,7 @@ func showModal(pv *tview.Pages, msg, back string, ok func()) {
|
|||
}
|
||||
dismissModal(pv, back)
|
||||
})
|
||||
m.SetTitle("<Confirm>")
|
||||
m.SetTitle("<Delete Benchmark>")
|
||||
pv.AddPage(promptPage, m, false, false)
|
||||
pv.ShowPage(promptPage)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,10 +66,18 @@ func (v *masterDetail) setEnterFn(f enterFn) {
|
|||
v.enterFn = f
|
||||
}
|
||||
|
||||
func (v *masterDetail) showMaster() {
|
||||
v.SwitchToPage("master")
|
||||
}
|
||||
|
||||
func (v *masterDetail) masterPage() *tableView {
|
||||
return v.GetPrimitive("master").(*tableView)
|
||||
}
|
||||
|
||||
func (v *masterDetail) showDetails() {
|
||||
v.SwitchToPage("details")
|
||||
}
|
||||
|
||||
func (v *masterDetail) detailsPage() *detailsView {
|
||||
return v.GetPrimitive("details").(*detailsView)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,14 +25,9 @@ func newStatefulSetView(t string, app *appView, list resource.List) resourceView
|
|||
|
||||
func (v *statefulSetView) extraActions(aa ui.KeyActions) {
|
||||
v.logResourceView.extraActions(aa)
|
||||
<<<<<<< HEAD
|
||||
v.scalableResourceView.extraActions(aa)
|
||||
aa[KeyShiftD] = newKeyAction("Sort Desired", v.sortColCmd(1, false), true)
|
||||
aa[KeyShiftC] = newKeyAction("Sort Current", v.sortColCmd(2, false), true)
|
||||
=======
|
||||
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(1, false), true)
|
||||
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(2, false), true)
|
||||
>>>>>>> checkpoint
|
||||
}
|
||||
|
||||
func (v *statefulSetView) showPods(app *appView, ns, res, sel string) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/k8s"
|
||||
"github.com/derailed/k9s/internal/perf"
|
||||
"github.com/derailed/k9s/internal/resource"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/gdamore/tcell"
|
||||
|
|
@ -18,11 +19,13 @@ import (
|
|||
type svcView struct {
|
||||
*resourceView
|
||||
|
||||
bench *benchmark
|
||||
bench *perf.Benchmark
|
||||
}
|
||||
|
||||
func newSvcView(t string, app *appView, list resource.List) resourceViewer {
|
||||
v := svcView{resourceView: newResourceView(t, app, list).(*resourceView)}
|
||||
v := svcView{
|
||||
resourceView: newResourceView(t, app, list).(*resourceView),
|
||||
}
|
||||
v.extraActionsFn = v.extraActions
|
||||
v.enterFn = v.showPods
|
||||
v.AddPage("logs", newLogsView(list.GetName(), app, &v), true, false)
|
||||
|
|
@ -95,7 +98,7 @@ func (v *svcView) benchStopCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
if v.bench != nil {
|
||||
log.Debug().Msg(">>> Benchmark canceled!!")
|
||||
v.app.status(ui.FlashErr, "Benchmark Camceled!")
|
||||
v.bench.cancel()
|
||||
v.bench.Cancel()
|
||||
}
|
||||
v.app.StatusReset()
|
||||
|
||||
|
|
@ -150,6 +153,7 @@ func (v *svcView) benchCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
cfg.Name = sel
|
||||
log.Debug().Msgf("Benchmark config %#v", cfg)
|
||||
|
||||
row, _ := v.masterPage().GetSelection()
|
||||
if err := v.checkSvc(row); err != nil {
|
||||
|
|
@ -173,13 +177,13 @@ func (v *svcView) benchCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
func (v *svcView) runBenchmark(port string, cfg config.BenchConfig) error {
|
||||
var err error
|
||||
base := "http://" + cfg.HTTP.Host + ":" + port + cfg.HTTP.Path
|
||||
if v.bench, err = newBenchmark(base, cfg); err != nil {
|
||||
if v.bench, err = perf.NewBenchmark(base, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v.app.status(ui.FlashWarn, "Benchmark in progress...")
|
||||
log.Debug().Msg("Bench starting...")
|
||||
go v.bench.run(v.app.Config.K9s.CurrentCluster, v.benchDone)
|
||||
go v.bench.Run(v.app.Config.K9s.CurrentCluster, v.benchDone)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -187,11 +191,11 @@ func (v *svcView) runBenchmark(port string, cfg config.BenchConfig) error {
|
|||
func (v *svcView) benchDone() {
|
||||
log.Debug().Msg("Bench Completed!")
|
||||
v.app.QueueUpdate(func() {
|
||||
if v.bench.canceled {
|
||||
if v.bench.Canceled() {
|
||||
v.app.status(ui.FlashInfo, "Benchmark canceled")
|
||||
} else {
|
||||
v.app.status(ui.FlashInfo, "Benchmark Completed!")
|
||||
v.bench.cancel()
|
||||
v.bench.Cancel()
|
||||
}
|
||||
v.bench = nil
|
||||
go benchTimedOut(v.app)
|
||||
|
|
|
|||
Loading…
Reference in New Issue