Signed-off-by: Srini Brahmaroutu <srbrahma@us.ibm.com>
| ... | ... |
@@ -28,7 +28,6 @@ func (daemon *Daemon) Containers(job *engine.Job) engine.Status {
|
| 28 | 28 |
size = job.GetenvBool("size")
|
| 29 | 29 |
psFilters filters.Args |
| 30 | 30 |
filt_exited []int |
| 31 |
- filt_status []string |
|
| 32 | 31 |
) |
| 33 | 32 |
outs := engine.NewTable("Created", 0)
|
| 34 | 33 |
|
| ... | ... |
@@ -46,8 +45,6 @@ func (daemon *Daemon) Containers(job *engine.Job) engine.Status {
|
| 46 | 46 |
} |
| 47 | 47 |
} |
| 48 | 48 |
|
| 49 |
- filt_status, _ = psFilters["status"] |
|
| 50 |
- |
|
| 51 | 49 |
names := map[string][]string{}
|
| 52 | 50 |
daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error {
|
| 53 | 51 |
names[e.ID()] = append(names[e.ID()], p) |
| ... | ... |
@@ -76,6 +73,15 @@ func (daemon *Daemon) Containers(job *engine.Job) engine.Status {
|
| 76 | 76 |
if !container.Running && !all && n <= 0 && since == "" && before == "" {
|
| 77 | 77 |
return nil |
| 78 | 78 |
} |
| 79 |
+ |
|
| 80 |
+ if !psFilters.Match("name", container.Name) {
|
|
| 81 |
+ return nil |
|
| 82 |
+ } |
|
| 83 |
+ |
|
| 84 |
+ if !psFilters.Match("id", container.ID) {
|
|
| 85 |
+ return nil |
|
| 86 |
+ } |
|
| 87 |
+ |
|
| 79 | 88 |
if before != "" && !foundBefore {
|
| 80 | 89 |
if container.ID == beforeCont.ID {
|
| 81 | 90 |
foundBefore = true |
| ... | ... |
@@ -102,10 +108,9 @@ func (daemon *Daemon) Containers(job *engine.Job) engine.Status {
|
| 102 | 102 |
return nil |
| 103 | 103 |
} |
| 104 | 104 |
} |
| 105 |
- for _, status := range filt_status {
|
|
| 106 |
- if container.State.StateString() != strings.ToLower(status) {
|
|
| 107 |
- return nil |
|
| 108 |
- } |
|
| 105 |
+ |
|
| 106 |
+ if !psFilters.Match("status", container.State.StateString()) {
|
|
| 107 |
+ return nil |
|
| 109 | 108 |
} |
| 110 | 109 |
displayed++ |
| 111 | 110 |
out := &engine.Env{}
|
| ... | ... |
@@ -336,3 +336,63 @@ func TestPsListContainersFilterStatus(t *testing.T) {
|
| 336 | 336 |
|
| 337 | 337 |
logDone("ps - test ps filter status")
|
| 338 | 338 |
} |
| 339 |
+ |
|
| 340 |
+func TestPsListContainersFilterID(t *testing.T) {
|
|
| 341 |
+ // start container |
|
| 342 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "busybox") |
|
| 343 |
+ out, _, err := runCommandWithOutput(runCmd) |
|
| 344 |
+ if err != nil {
|
|
| 345 |
+ t.Fatal(out, err) |
|
| 346 |
+ } |
|
| 347 |
+ firstID := stripTrailingCharacters(out) |
|
| 348 |
+ |
|
| 349 |
+ // start another container |
|
| 350 |
+ runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 360") |
|
| 351 |
+ if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
|
| 352 |
+ t.Fatal(out, err) |
|
| 353 |
+ } |
|
| 354 |
+ |
|
| 355 |
+ // filter containers by id |
|
| 356 |
+ runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=id="+firstID) |
|
| 357 |
+ if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
|
| 358 |
+ t.Fatal(out, err) |
|
| 359 |
+ } |
|
| 360 |
+ containerOut := strings.TrimSpace(out) |
|
| 361 |
+ if containerOut != firstID[:12] {
|
|
| 362 |
+ t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
|
|
| 363 |
+ } |
|
| 364 |
+ |
|
| 365 |
+ deleteAllContainers() |
|
| 366 |
+ |
|
| 367 |
+ logDone("ps - test ps filter id")
|
|
| 368 |
+} |
|
| 369 |
+ |
|
| 370 |
+func TestPsListContainersFilterName(t *testing.T) {
|
|
| 371 |
+ // start container |
|
| 372 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "--name=a_name_to_match", "busybox") |
|
| 373 |
+ out, _, err := runCommandWithOutput(runCmd) |
|
| 374 |
+ if err != nil {
|
|
| 375 |
+ t.Fatal(out, err) |
|
| 376 |
+ } |
|
| 377 |
+ firstID := stripTrailingCharacters(out) |
|
| 378 |
+ |
|
| 379 |
+ // start another container |
|
| 380 |
+ runCmd = exec.Command(dockerBinary, "run", "-d", "--name=b_name_to_match", "busybox", "sh", "-c", "sleep 360") |
|
| 381 |
+ if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
|
| 382 |
+ t.Fatal(out, err) |
|
| 383 |
+ } |
|
| 384 |
+ |
|
| 385 |
+ // filter containers by name |
|
| 386 |
+ runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=name=a_name_to_match") |
|
| 387 |
+ if out, _, err = runCommandWithOutput(runCmd); err != nil {
|
|
| 388 |
+ t.Fatal(out, err) |
|
| 389 |
+ } |
|
| 390 |
+ containerOut := strings.TrimSpace(out) |
|
| 391 |
+ if containerOut != firstID[:12] {
|
|
| 392 |
+ t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
|
|
| 393 |
+ } |
|
| 394 |
+ |
|
| 395 |
+ deleteAllContainers() |
|
| 396 |
+ |
|
| 397 |
+ logDone("ps - test ps filter name")
|
|
| 398 |
+} |
| ... | ... |
@@ -3,6 +3,7 @@ package filters |
| 3 | 3 |
import ( |
| 4 | 4 |
"encoding/json" |
| 5 | 5 |
"errors" |
| 6 |
+ "regexp" |
|
| 6 | 7 |
"strings" |
| 7 | 8 |
) |
| 8 | 9 |
|
| ... | ... |
@@ -61,3 +62,22 @@ func FromParam(p string) (Args, error) {
|
| 61 | 61 |
} |
| 62 | 62 |
return args, nil |
| 63 | 63 |
} |
| 64 |
+ |
|
| 65 |
+func (filters Args) Match(field, source string) bool {
|
|
| 66 |
+ fieldValues := filters[field] |
|
| 67 |
+ |
|
| 68 |
+ //do not filter if there is no filter set or cannot determine filter |
|
| 69 |
+ if len(fieldValues) == 0 {
|
|
| 70 |
+ return true |
|
| 71 |
+ } |
|
| 72 |
+ for _, name2match := range fieldValues {
|
|
| 73 |
+ match, err := regexp.MatchString(name2match, source) |
|
| 74 |
+ if err != nil {
|
|
| 75 |
+ continue |
|
| 76 |
+ } |
|
| 77 |
+ if match {
|
|
| 78 |
+ return true |
|
| 79 |
+ } |
|
| 80 |
+ } |
|
| 81 |
+ return false |
|
| 82 |
+} |