Skip to content

Commit

Permalink
Merge pull request #84 from yangsoon/fix/fix-cmd
Browse files Browse the repository at this point in the history
Fix: fix apply and exec command
  • Loading branch information
yangsoon authored Feb 10, 2023
2 parents 063ac43 + e64767d commit 094c604
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 114 deletions.
85 changes: 21 additions & 64 deletions saectl/internal/cmd/apply/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ var (
# Apply the configuration from all files that end with '.json' - i.e. expand wildcard characters in file names
saectl apply -f '*.json'`))

warningNoLastAppliedConfigAnnotation = "Warning: resource %[1]s is missing the %[2]s annotation which is required by %[3]s apply. %[3]s apply should only be used on resources created declaratively by either %[3]s create --save-config or %[3]s apply. The missing annotation will be patched automatically.\n"
warningChangesOnDeletingResource = "Warning: Detected changes to resource %[1]s which is currently being deleted.\n"
//warningNoLastAppliedConfigAnnotation = "Warning: resource %[1]s is missing the %[2]s annotation which is required by %[3]s apply. %[3]s apply should only be used on resources created declaratively by either %[3]s create --save-config or %[3]s apply. The missing annotation will be patched automatically.\n"
warningChangesOnDeletingResource = "Warning: Detected changes to resource %[1]s which is currently being deleted.\n"
)

// NewApplyFlags returns a default ApplyFlags
Expand Down Expand Up @@ -175,31 +175,20 @@ func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions

flags.AddFlags(cmd)

// apply subcommands
//cmd.AddCommand(NewCmdApplyViewLastApplied(flags.Factory, flags.IOStreams))
//cmd.AddCommand(NewCmdApplySetLastApplied(flags.Factory, flags.IOStreams))
//cmd.AddCommand(NewCmdApplyEditLastApplied(flags.Factory, flags.IOStreams))

return cmd
}

// AddFlags registers flags for a cli
func (flags *ApplyFlags) AddFlags(cmd *cobra.Command) {
// bind flag structs
flags.DeleteFlags.AddFlags(cmd)
//flags.RecordFlags.AddFlags(cmd)
flags.PrintFlags.AddFlags(cmd)

//cmdutil.AddValidateFlags(cmd)
//cmdutil.AddDryRunFlag(cmd)
//cmdutil.AddServerSideApplyFlags(cmd)
//cmdutil.AddFieldManagerFlagVar(cmd, &flags.FieldManager, FieldManagerClientSideApply)
cmdutil.AddDryRunFlag(cmd)
cmdutil.AddLabelSelectorFlagVar(cmd, &flags.Selector)

cmd.Flags().BoolVar(&flags.Overwrite, "overwrite", flags.Overwrite, "Automatically resolve conflicts between the modified and live configuration by using values from the modified configuration")
//cmd.Flags().BoolVar(&flags.Prune, "prune", flags.Prune, "Automatically delete resource objects, that do not appear in the configs and are created by either apply or create --save-config. Should be used with either -l or --all.")
cmd.Flags().BoolVar(&flags.All, "all", flags.All, "Select all resources in the namespace of the specified resource types.")
//cmd.Flags().StringArrayVar(&flags.PruneWhitelist, "prune-whitelist", flags.PruneWhitelist, "Overwrite the default whitelist with <group/version/kind> for --prune")
cmd.Flags().BoolVar(&flags.OpenAPIPatch, "openapi-patch", flags.OpenAPIPatch, "If true, use openapi to calculate diff when the openapi presents and the resource can be found in the openapi spec. Otherwise, fall back to use baked-in types.")
}

Expand All @@ -209,8 +198,6 @@ func (flags *ApplyFlags) ToOptions(cmd *cobra.Command, baseName string, args []s
return nil, cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args)
}

serverSideApply := cmdutil.GetServerSideApplyFlag(cmd)
forceConflicts := cmdutil.GetForceConflictsFlag(cmd)
dryRunStrategy, err := cmdutil.GetDryRunStrategy(cmd)
if err != nil {
return nil, err
Expand All @@ -222,8 +209,6 @@ func (flags *ApplyFlags) ToOptions(cmd *cobra.Command, baseName string, args []s
}

dryRunVerifier := resource.NewQueryParamVerifier(dynamicClient, flags.Factory.OpenAPIGetter(), resource.QueryParamDryRun)
fieldValidationVerifier := resource.NewQueryParamVerifier(dynamicClient, flags.Factory.OpenAPIGetter(), resource.QueryParamFieldValidation)
fieldManager := GetApplyFieldManagerFlag(cmd, serverSideApply)

// allow for a success message operation to be specified at print time
toPrinter := func(operation string) (printers.ResourcePrinter, error) {
Expand All @@ -250,14 +235,6 @@ func (flags *ApplyFlags) ToOptions(cmd *cobra.Command, baseName string, args []s

openAPISchema, _ := flags.Factory.OpenAPISchema()

validationDirective, err := cmdutil.GetValidationDirective(cmd)
if err != nil {
return nil, err
}
validator, err := flags.Factory.Validator(validationDirective, fieldValidationVerifier)
if err != nil {
return nil, err
}
builder := flags.Factory.NewBuilder()
mapper, err := flags.Factory.ToRESTMapper()
if err != nil {
Expand All @@ -269,44 +246,31 @@ func (flags *ApplyFlags) ToOptions(cmd *cobra.Command, baseName string, args []s
return nil, err
}

if flags.Prune {
flags.PruneResources, err = prune.ParseResources(mapper, flags.PruneWhitelist)
if err != nil {
return nil, err
}
}

o := &ApplyOptions{
// Store baseName for use in printing warnings / messages involving the base command name.
// This is useful for downstream command that wrap this one.
cmdBaseName: baseName,

PrintFlags: flags.PrintFlags,

DeleteOptions: deleteOptions,
ToPrinter: toPrinter,
ServerSideApply: serverSideApply,
ForceConflicts: forceConflicts,
FieldManager: fieldManager,
Selector: flags.Selector,
DryRunStrategy: dryRunStrategy,
DryRunVerifier: dryRunVerifier,
Prune: flags.Prune,
PruneResources: flags.PruneResources,
All: flags.All,
Overwrite: flags.Overwrite,
OpenAPIPatch: flags.OpenAPIPatch,
PruneWhitelist: flags.PruneWhitelist,

Recorder: recorder,
Namespace: namespace,
EnforceNamespace: enforceNamespace,
Validator: validator,
ValidationDirective: validationDirective,
Builder: builder,
Mapper: mapper,
DynamicClient: dynamicClient,
OpenAPISchema: openAPISchema,
DeleteOptions: deleteOptions,
ToPrinter: toPrinter,
Selector: flags.Selector,
DryRunStrategy: dryRunStrategy,
DryRunVerifier: dryRunVerifier,

All: flags.All,
Overwrite: flags.Overwrite,
OpenAPIPatch: flags.OpenAPIPatch,

Recorder: recorder,
Namespace: namespace,
EnforceNamespace: enforceNamespace,

Builder: builder,
Mapper: mapper,
DynamicClient: dynamicClient,
OpenAPISchema: openAPISchema,

IOStreams: flags.IOStreams,

Expand Down Expand Up @@ -589,12 +553,6 @@ See https://kubernetes.io/docs/reference/using-api/server-side-apply/#conflicts`
}

if o.DryRunStrategy != cmdutil.DryRunClient {
metadata, _ := meta.Accessor(info.Object)
annotationMap := metadata.GetAnnotations()
if _, ok := annotationMap[corev1.LastAppliedConfigAnnotation]; !ok {
fmt.Fprintf(o.ErrOut, warningNoLastAppliedConfigAnnotation, info.ObjectName(), corev1.LastAppliedConfigAnnotation, o.cmdBaseName)
}

patcher, err := newPatcher(o, info, helper)
if err != nil {
return err
Expand All @@ -603,7 +561,6 @@ See https://kubernetes.io/docs/reference/using-api/server-side-apply/#conflicts`
if err != nil {
return cmdutil.AddSourceToErr(fmt.Sprintf("applying patch:\n%s\nto:\n%v\nfor:", patchBytes, info), info.Source, err)
}

info.Refresh(patchedObject, true)

WarnIfDeleting(info.Object, o.ErrOut)
Expand Down
2 changes: 0 additions & 2 deletions saectl/internal/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,7 @@ func NewCommand(o CtlOption) *cobra.Command {

templates.ActsAsRootCommand(cmds, filters, groups...)

// TODO: add completion for get cmd
cmds.AddCommand(apiresources.NewCmdAPIResources(f, o.IOStreams))
//cmds.AddCommand(apiresources.NewCmdAPIVersions(f, o.IOStreams))
cmds.SetGlobalNormalizationFunc(cliflag.WordSepNormalizeFunc)
return cmds
}
Expand Down
17 changes: 5 additions & 12 deletions saectl/internal/cmd/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ var (
# Create a deployment(represents an application in sae) using the data in .json
saectl create -f ./deployment.json
# Create a pod based on the JSON passed into stdin
cat pod.json | saectl create -f -
# Create a deployment based on the JSON passed into stdin
cat deployment.json | saectl create -f -
# Edit the data in registry.yaml in JSON then create the resource using the edited data
saectl create -f registry.yaml --edit -o json`))
Expand All @@ -75,7 +75,6 @@ var (
func NewCreateOptions(ioStreams genericclioptions.IOStreams) *CreateOptions {
return &CreateOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
// RecordFlags: genericclioptions.NewRecordFlags(),

Recorder: genericclioptions.NoopRecorder{},

Expand Down Expand Up @@ -108,20 +107,14 @@ func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cob

usage := "to use to create the resource"
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
//cmdutil.AddValidateFlags(cmd)
cmdutil.AddValidateFlags(cmd)
cmd.Flags().BoolVar(&o.EditBeforeCreate, "edit", o.EditBeforeCreate, "Edit the API resource before creating")
cmd.Flags().Bool("windows-line-endings", runtime.GOOS == "windows",
"Only relevant if --edit=true. Defaults to the line ending native to your platform.")
//cmdutil.AddDryRunFlag(cmd)
cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddDryRunFlag(cmd)
o.PrintFlags.AddFlags(cmd)

// TODO: 1. Storing objects to annotations is currently not supported
//cmdutil.AddApplyAnnotationFlags(cmd)
// TODO: 2. Label selector is not supported for now
//cmdutil.AddLabelSelectorFlagVar(cmd, &o.Selector)
// TODO: 3. Server-Side Apply is not support for now
//cmdutil.AddFieldManagerFlagVar(cmd, &o.fieldManager, "saectl-create")

// create subcommands
cmd.AddCommand(create.NewCmdCreateNamespace(f, ioStreams))
cmd.AddCommand(create.NewCmdCreateConfigMap(f, ioStreams))
Expand Down
20 changes: 14 additions & 6 deletions saectl/internal/cmd/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ type Options struct {
podName string
namespace string
podClient coreclient.PodsGetter

cmd []string
}

func (o *Options) Complete(f util.AliCloudFactory, argsIn []string, ioStreams genericclioptions.IOStreams) error {
Expand Down Expand Up @@ -122,12 +124,19 @@ func (o *Options) Run() error {
return err
}
fn := func() error {
return o.Stream(tokenId)
e, err := o.NewExecutor(tokenId)
if err != nil {
return err
}
//_, _ = e.Exec("curl 127.0.0.1:5555")
_, _ = e.Exec("c")
return nil
//return e.Stream()
}
return o.tty.Safe(fn)
}

func (o *Options) Stream(tokenId string) error {
func (o *Options) NewExecutor(tokenId string) (*stream.Executor, error) {
wsUrl := &url.URL{
Scheme: "wss",
Host: "sae-webshell.console.aliyun.com",
Expand All @@ -139,15 +148,14 @@ func (o *Options) Stream(tokenId string) error {
}
c, err := websocket.Dial(wsUrl.String(), "", "https://sae.console.aliyun.com")
if err != nil {
return err
return nil, err
}
e := stream.NewExecutor(c, stream.Option{
return stream.NewExecutor(c, stream.Option{
Stdin: o.In,
Stdout: o.Out,
StdErr: nil,
TTY: o.tty.Raw,
})
return e.Stream()
}), nil
}

func (o *Options) GetWebShellToken(appId string, podName string) (string, error) {
Expand Down
80 changes: 60 additions & 20 deletions saectl/internal/cmd/exec/stream/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package stream

import (
"context"
"fmt"
"io"
"strings"
"sync"
Expand Down Expand Up @@ -31,12 +32,36 @@ func NewExecutor(conn *websocket.Conn, op Option) *Executor {
}
}

func (e *Executor) Exec(cmd string) (string, error) {
stop := make(chan struct{})
ctx, cancel := context.WithCancel(context.Background())

go func(ctx context.Context) {
websocket.Message.Send(e.Conn, cmd+"\n")
for i := 1; i <= 2; i++ {
websocket.Message.Send(e.Conn, "exit\n")
}
}(ctx)

stdOutBuffer := NewStdOutBuffer()
e.copyStdout(stop, stdOutBuffer)

select {
case <-stop:
cancel()
}

r := stdOutBuffer.String()
fmt.Println(r)
return r, nil
}

func (e *Executor) Stream() error {
stop := make(chan struct{})
ctx, cancel := context.WithCancel(context.Background())

e.copyStdin(ctx)
e.copyStdout(stop)
e.copyStdin(ctx, e.Stdin)
e.copyStdout(stop, e.Stdout)

select {
case <-stop:
Expand All @@ -45,28 +70,22 @@ func (e *Executor) Stream() error {
}
}

func (e *Executor) copyStdin(ctx context.Context) {
if e.Stdin != nil {
var once sync.Once
// copy from client's stdin to container's stdin
go func() {
defer runtime.HandleCrash()
defer once.Do(func() { e.Conn.Close() })
if _, err := io.Copy(e.Conn, NewGuardStdIn(ctx, e.Stdin)); err != nil {
runtime.HandleError(err)
}
}()
}
func (e *Executor) copyStdin(ctx context.Context, r io.Reader) {
var once sync.Once
go func() {
defer runtime.HandleCrash()
defer once.Do(func() { e.Conn.Close() })
if _, err := io.Copy(e.Conn, NewGuardStdIn(ctx, r)); err != nil {
runtime.HandleError(err)
}
}()
}

func (e *Executor) copyStdout(stop chan struct{}) {
if e.Stdout == nil {
return
}
func (e *Executor) copyStdout(stop chan struct{}, w io.Writer) {
go func() {
defer runtime.HandleCrash()
defer io.Copy(io.Discard, e.Conn)
if _, err := io.Copy(e.Stdout, NewGuardStdOut(e.Conn, stop)); err != nil {
if _, err := io.Copy(w, NewGuardStdOut(e.Conn, stop)); err != nil {
runtime.HandleError(err)
}
}()
Expand All @@ -86,7 +105,8 @@ func NewGuardStdOut(r io.Reader, stop chan struct{}) io.Reader {

func (g *guardStdOut) Read(p []byte) (n int, err error) {
n, err = g.Reader.Read(p)
if strings.Contains(string(p), "{\"metadata\":{},\"status\":\"Success\"}") {
if strings.Contains(string(p), "{\"metadata\":{},\"status\":\"Failure\"") ||
strings.Contains(string(p), "{\"metadata\":{},\"status\":\"Success\"") {
g.stop <- struct{}{}
return 0, io.EOF
}
Expand All @@ -113,3 +133,23 @@ func (g *guardStdIn) Read(p []byte) (n int, err error) {
return g.Reader.Read(p)
}
}

type StdOutBuffer struct {
builder strings.Builder
}

func NewStdOutBuffer() *StdOutBuffer {
return &StdOutBuffer{
builder: strings.Builder{},
}
}

func (s *StdOutBuffer) Write(p []byte) (n int, err error) {
s.builder.WriteString(string(p))
//fmt.Printf("\n<--%s-->\n", s.builder.String())
return len(p), nil
}

func (s *StdOutBuffer) String() string {
return s.builder.String()
}
1 change: 0 additions & 1 deletion saectl/internal/cmd/patch/patch.go

This file was deleted.

Loading

0 comments on commit 094c604

Please sign in to comment.