-
Notifications
You must be signed in to change notification settings - Fork 949
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: add pouch kill functionality
Signed-off-by: xiechengsheng <XIE1995@whut.edu.cn>
- Loading branch information
1 parent
3f0c62f
commit b50b084
Showing
14 changed files
with
559 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
// killDescription is used to describe kill command in detail and auto generate command doc. | ||
var killDescription = "Kill one or more running containers, the container will receive SIGKILL by default, " + | ||
"or the signal which is specified with the --signal option." | ||
|
||
// KillCommand use to implement 'kill' command | ||
type KillCommand struct { | ||
baseCommand | ||
signal string | ||
} | ||
|
||
// Init initialize kill command. | ||
func (kill *KillCommand) Init(c *Cli) { | ||
kill.cli = c | ||
kill.cmd = &cobra.Command{ | ||
Use: "kill [OPTIONS] CONTAINER [CONTAINER...]", | ||
Short: "Kill one or more running containers", | ||
Long: killDescription, | ||
Args: cobra.MinimumNArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return kill.runKill(args) | ||
}, | ||
Example: killExample(), | ||
} | ||
kill.addFlags() | ||
} | ||
|
||
// addFlags adds flags for specific command. | ||
func (kill *KillCommand) addFlags() { | ||
flagSet := kill.cmd.Flags() | ||
flagSet.StringVarP(&kill.signal, "signal", "s", "SIGKILL", "Signal to send to the container") | ||
} | ||
|
||
// runKill is the entry of kill command. | ||
func (kill *KillCommand) runKill(args []string) error { | ||
ctx := context.Background() | ||
apiClient := kill.cli.Client() | ||
|
||
var errs []string | ||
for _, name := range args { | ||
if err := apiClient.ContainerKill(ctx, name, kill.signal); err != nil { | ||
errs = append(errs, err.Error()) | ||
continue | ||
} | ||
fmt.Printf("%s\n", name) | ||
} | ||
|
||
if len(errs) > 0 { | ||
return errors.New(strings.Join(errs, "\n")) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// killExample shows examples in kill command, and is used in auto-generated cli docs. | ||
func killExample() string { | ||
return `$ pouch ps | ||
Name ID Status Created Image Runtime | ||
foo c926cf Up 5 seconds 6 seconds ago registry.hub.docker.com/library/busybox:latest runc | ||
$ pouch kill foo | ||
foo | ||
$ pouch ps -a | ||
Name ID Status Created Image Runtime | ||
foo c926cf Exited (137) 9 seconds 25 seconds ago registry.hub.docker.com/library/busybox:latest runc` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"net/url" | ||
) | ||
|
||
// ContainerKill sends signal to a container. | ||
func (client *APIClient) ContainerKill(ctx context.Context, name, signal string) error { | ||
q := url.Values{} | ||
q.Set("signal", signal) | ||
|
||
resp, err := client.post(ctx, "/containers/"+name+"/kill", q, nil, nil) | ||
if err != nil { | ||
return err | ||
} | ||
ensureCloseReader(resp) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package client | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestContainerKillError(t *testing.T) { | ||
client := &APIClient{ | ||
HTTPCli: newMockClient(errorMockResponse(http.StatusInternalServerError, "Server error")), | ||
} | ||
err := client.ContainerKill(context.Background(), "nothing", "SIGKILL") | ||
if err == nil || !strings.Contains(err.Error(), "Server error") { | ||
t.Fatalf("expected a Server Error, got %v", err) | ||
} | ||
} | ||
|
||
func TestContainerKillNotFoundError(t *testing.T) { | ||
client := &APIClient{ | ||
HTTPCli: newMockClient(errorMockResponse(http.StatusNotFound, "Not Found")), | ||
} | ||
err := client.ContainerKill(context.Background(), "no container", "SIGKILL") | ||
if err == nil || !strings.Contains(err.Error(), "Not Found") { | ||
t.Fatalf("expected a Not Found Error, got %v", err) | ||
} | ||
} | ||
|
||
func TestContainerKill(t *testing.T) { | ||
expectedURL := "/containers/container_id/kill" | ||
|
||
httpClient := newMockClient(func(req *http.Request) (*http.Response, error) { | ||
if !strings.HasPrefix(req.URL.Path, expectedURL) { | ||
return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL) | ||
} | ||
signal := req.URL.Query().Get("signal") | ||
if signal != "SIGKILL" { | ||
return nil, fmt.Errorf("signal not set in URL query properly. Expected 'SIGKILL', got %s", signal) | ||
} | ||
return &http.Response{ | ||
StatusCode: http.StatusOK, | ||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), | ||
}, nil | ||
}) | ||
|
||
client := &APIClient{ | ||
HTTPCli: httpClient, | ||
} | ||
|
||
err := client.ContainerKill(context.Background(), "container_id", "SIGKILL") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.