github.com/containers/podman/v5@v5.1.0-rc1/test/system/090-events.bats (about)

     1  #!/usr/bin/env bats   -*- bats -*-
     2  #
     3  # tests for podman events functionality
     4  #
     5  
     6  load helpers
     7  load helpers.network
     8  
     9  # bats test_tags=distro-integration
    10  @test "events with a filter by label" {
    11      cname=test-$(random_string 30 | tr A-Z a-z)
    12      labelname=$(random_string 10)
    13      labelvalue=$(random_string 15)
    14  
    15      run_podman run --label $labelname=$labelvalue --name $cname --rm $IMAGE ls
    16  
    17      expect=".* container start [0-9a-f]\+ (image=$IMAGE, name=$cname,.* ${labelname}=${labelvalue}"
    18      run_podman events --filter type=container -f container=$cname --filter label=${labelname}=${labelvalue} --filter event=start --stream=false
    19      is "$output" "$expect" "filtering by container name and label"
    20  
    21      # Same thing, but without the container-name filter
    22      run_podman system events -f type=container --filter label=${labelname}=${labelvalue} --filter event=start --stream=false
    23      is "$output" "$expect" "filtering just by label"
    24  
    25      # Now filter just by container name, no label
    26      run_podman events --filter type=container --filter container=$cname --filter event=start --stream=false
    27      is "$output" "$expect" "filtering just by container"
    28  }
    29  
    30  @test "truncate events" {
    31      cname=test-$(random_string 30 | tr A-Z a-z)
    32  
    33      run_podman run -d --name=$cname --rm $IMAGE echo hi
    34      id="$output"
    35  
    36      run_podman events --filter container=$cname --filter event=start --stream=false
    37      is "$output" ".* $id " "filtering by container name full id"
    38  
    39      truncID=${id:0:12}
    40      run_podman events --filter container=$cname --filter event=start --stream=false --no-trunc=false
    41      is "$output" ".* $truncID " "filtering by container name trunc id"
    42  
    43      # --no-trunc does not affect --format; we always get the full ID
    44      run_podman events --filter container=$cname --filter event=died --stream=false --format='{{.ID}}--{{.Image}}' --no-trunc=false
    45      assert "$output" = "${id}--${IMAGE}"
    46  }
    47  
    48  @test "image events" {
    49      skip_if_remote "remote does not support --events-backend"
    50      pushedDir=$PODMAN_TMPDIR/dir
    51      mkdir -p $pushedDir
    52  
    53      tarball=$PODMAN_TMPDIR/ball.tar
    54  
    55      run_podman image inspect --format "{{.ID}}" $IMAGE
    56      imageID="$output"
    57  
    58      t0=$(date --iso-8601=seconds)
    59      tag=registry.com/$(random_string 10 | tr A-Z a-z)
    60  
    61      bogus_image="localhost:$(random_free_port)/bogus"
    62  
    63      # Force using the file backend since the journal backend is eating events
    64      # (see containers/podman/pull/10219#issuecomment-842325032).
    65      run_podman --events-backend=file push $IMAGE dir:$pushedDir
    66      run_podman --events-backend=file save $IMAGE -o $tarball
    67      run_podman --events-backend=file load -i $tarball
    68      run_podman --events-backend=file pull docker-archive:$tarball
    69      run_podman 125 --events-backend=file pull --retry 0 $bogus_image
    70      run_podman --events-backend=file tag $IMAGE $tag
    71      run_podman --events-backend=file untag $IMAGE $tag
    72      run_podman --events-backend=file tag $IMAGE $tag
    73      run_podman --events-backend=file rmi -f $imageID
    74      run_podman --events-backend=file load -i $tarball
    75  
    76      run_podman --events-backend=file events --stream=false --filter type=image --since $t0
    77      is "$output" ".*image push $imageID dir:$pushedDir
    78  .*image save $imageID $tarball
    79  .*image loadfromarchive $imageID $tarball
    80  .*image pull $imageID docker-archive:$tarball
    81  .*image pull-error  $bogus_image .*pinging container registry localhost.*connection refused
    82  .*image tag $imageID $tag
    83  .*image untag $imageID $tag:latest
    84  .*image tag $imageID $tag
    85  .*image untag $imageID $tag:latest
    86  .*image untag $imageID $IMAGE
    87  .*image remove $imageID $imageID" \
    88         "podman events"
    89  
    90      # With --format we can check the _exact_ output, not just substrings
    91      local -a expect=("push--dir:$pushedDir"
    92                       "save--$tarball"
    93                       "loadfromarchive--$tarball"
    94                       "pull--docker-archive:$tarball"
    95                       "pull-error--$bogus_image"
    96                       "tag--$tag"
    97                       "untag--$tag:latest"
    98                       "tag--$tag"
    99                       "untag--$tag:latest"
   100                       "untag--$IMAGE"
   101                       "remove--$imageID"
   102                       "loadfromarchive--$tarball"
   103                      )
   104      run_podman --events-backend=file events --stream=false --filter type=image --since $t0 --format '{{.Status}}--{{.Name}}'
   105      for i in $(seq 0 ${#expect[@]}); do
   106          assert "${lines[$i]}" = "${expect[$i]}" "events, line $i"
   107      done
   108      assert "${#lines[@]}" = "${#expect[@]}" "Total lines of output"
   109  }
   110  
   111  function _events_disjunctive_filters() {
   112      local backend=$1
   113  
   114      # Regression test for #10507: make sure that filters with the same key are
   115      # applied in disjunction.
   116      t0=$(date --iso-8601=seconds)
   117      run_podman $backend run --name foo --rm $IMAGE ls
   118      run_podman $backend run --name bar --rm $IMAGE ls
   119      run_podman $backend events --stream=false --since=$t0 --filter container=foo --filter container=bar --filter event=start
   120      is "$output" ".* container start .* name=foo.*
   121  .* container start .* name=bar.*"
   122  }
   123  
   124  @test "events with disjunctive filters - file" {
   125      skip_if_remote "remote does not support --events-backend"
   126      _events_disjunctive_filters --events-backend=file
   127  }
   128  
   129  @test "events with disjunctive filters - journald" {
   130      skip_if_remote "remote does not support --events-backend"
   131      skip_if_journald_unavailable "system does not support journald events"
   132      _events_disjunctive_filters --events-backend=journald
   133  }
   134  
   135  @test "events with file backend and journald logdriver with --follow failure" {
   136      skip_if_remote "remote does not support --events-backend"
   137      skip_if_journald_unavailable "system does not support journald events"
   138      run_podman --events-backend=file run --log-driver=journald --name=test $IMAGE echo hi
   139      is "$output" "hi" "Should support events-backend=file"
   140  
   141      run_podman 125 --events-backend=file logs --follow test
   142      is "$output" "Error: using --follow with the journald --log-driver but without the journald --events-backend (file) is not supported" \
   143         "Should fail with reasonable error message when events-backend and events-logger do not match"
   144  
   145  }
   146  
   147  @test "events with disjunctive filters - default" {
   148      _events_disjunctive_filters ""
   149  }
   150  
   151  # bats test_tags=distro-integration
   152  @test "events with events_logfile_path in containers.conf" {
   153      skip_if_remote "remote does not support --events-backend"
   154      events_file=$PODMAN_TMPDIR/events.log
   155      containersconf=$PODMAN_TMPDIR/containers.conf
   156      cat >$containersconf <<EOF
   157  [engine]
   158  events_logfile_path="$events_file"
   159  EOF
   160      CONTAINERS_CONF_OVERRIDE="$containersconf" run_podman --events-backend=file pull $IMAGE
   161      assert "$(< $events_file)" =~ "\"Name\":\"$IMAGE\"" "Image found in events"
   162  }
   163  
   164  function _populate_events_file() {
   165      # Create 100 duplicate entries to populate the events log file.
   166      local events_file=$1
   167      truncate --size=0 $events_file
   168      for i in {0..99}; do
   169          printf '{"Name":"busybox","Status":"pull","Time":"2022-04-06T11:26:42.7236679%02d+02:00","Type":"image","Attributes":null}\n' $i >> $events_file
   170      done
   171  }
   172  
   173  # bats test_tags=distro-integration
   174  @test "events log-file rotation" {
   175      skip_if_remote "setting CONTAINERS_CONF_OVERRIDE logger options does not affect remote client"
   176  
   177      # Make sure that the events log file is (not) rotated depending on the
   178      # settings in containers.conf.
   179  
   180      # Config without a limit
   181      eventsFile=$PODMAN_TMPDIR/events.txt
   182      containersConf=$PODMAN_TMPDIR/containers.conf
   183      cat >$containersConf <<EOF
   184  [engine]
   185  events_logger="file"
   186  events_logfile_path="$eventsFile"
   187  EOF
   188  
   189      # Check that a non existing event file does not cause a hang (#15688)
   190      CONTAINERS_CONF_OVERRIDE=$containersConf run_podman events --stream=false
   191  
   192      _populate_events_file $eventsFile
   193  
   194      # Create events *without* a limit and make sure that it has not been
   195      # rotated/truncated.
   196      contentBefore=$(head -n100 $eventsFile)
   197      CONTAINERS_CONF_OVERRIDE=$containersConf run_podman run --rm $IMAGE true
   198      contentAfter=$(head -n100 $eventsFile)
   199      is "$contentBefore" "$contentAfter" "events file has not been rotated"
   200  
   201      # Repopulate events file
   202      rm $eventsFile
   203      _populate_events_file $eventsFile
   204  
   205      # Config with a limit
   206      rm $containersConf
   207      cat >$containersConf <<EOF
   208  [engine]
   209  events_logger="file"
   210  events_logfile_path="$eventsFile"
   211  # The limit of 4750 is the *exact* half of the initial events file.
   212  events_logfile_max_size=4750
   213  EOF
   214  
   215      # Create events *with* a limit and make sure that it has been
   216      # rotated/truncated.  Once rotated, the events file should only contain the
   217      # second half of its previous events plus the new ones.
   218      expectedContentAfterTruncation=$PODMAN_TMPDIR/truncated.txt
   219  
   220      run_podman create $IMAGE
   221      ctrID=$output
   222      CONTAINERS_CONF_OVERRIDE=$containersConf run_podman rm $ctrID
   223      tail -n52 $eventsFile >> $expectedContentAfterTruncation
   224  
   225      # Make sure the events file looks as expected.
   226      is "$(cat $eventsFile)" "$(cat $expectedContentAfterTruncation)" "events file has been rotated"
   227  
   228      # Make sure that `podman events` can read the file, and that it returns the
   229      # same amount of events.  We checked the contents before.
   230      CONTAINERS_CONF_OVERRIDE=$containersConf run_podman events --stream=false --since="2022-03-06T11:26:42.723667984+02:00" --format=json
   231      assert "${#lines[@]}" = 52 "Number of events returned"
   232      is "${lines[0]}" "{\"Name\":\"$eventsFile\",\"Status\":\"log-rotation\",\"time\":[0-9]\+,\"timeNano\":[0-9]\+,\"Type\":\"system\",\"Attributes\":{\"io.podman.event.rotate\":\"begin\"}}"
   233      is "${lines[-2]}" "{\"Name\":\"$eventsFile\",\"Status\":\"log-rotation\",\"time\":[0-9]\+,\"timeNano\":[0-9]\+,\"Type\":\"system\",\"Attributes\":{\"io.podman.event.rotate\":\"end\"}}"
   234      is "${lines[-1]}" "{\"ID\":\"$ctrID\",\"Image\":\"$IMAGE\",\"Name\":\".*\",\"Status\":\"remove\",\"time\":[0-9]\+,\"timeNano\":[0-9]\+,\"Type\":\"container\",\"Attributes\":{.*}}"
   235  }
   236  
   237  @test "events log-file no duplicates" {
   238      skip_if_remote "setting CONTAINERS_CONF_OVERRIDE logger options does not affect remote client"
   239  
   240      # This test makes sure that events are not returned more than once when
   241      # streaming during a log-file rotation.
   242      eventsFile=$PODMAN_TMPDIR/events.txt
   243      eventsJSON=$PODMAN_TMPDIR/events.json
   244      containersConf=$PODMAN_TMPDIR/containers.conf
   245      cat >$containersConf <<EOF
   246  [engine]
   247  events_logger="file"
   248  events_logfile_path="$eventsFile"
   249  # The populated file has a size of 11300, so let's create a couple of events to
   250  # force a log rotation.
   251  events_logfile_max_size=11300
   252  EOF
   253  
   254      _populate_events_file $eventsFile
   255      CONTAINERS_CONF_OVERRIDE=$containersConf timeout --kill=10 20 \
   256          $PODMAN events --stream=true --since="2022-03-06T11:26:42.723667984+02:00" --format=json > $eventsJSON &
   257  
   258      # Now wait for the above podman-events process to write to the eventsJSON
   259      # file, so we know it's reading.
   260      retries=20
   261      while [[ $retries -gt 0 ]]; do
   262          if [ -s $eventsJSON ]; then
   263              break
   264          fi
   265          retries=$((retries - 1))
   266          sleep 0.5
   267      done
   268      assert $retries -gt 0 \
   269             "Timed out waiting for podman-events to start reading pre-existing events"
   270  
   271      CONTAINERS_CONF_OVERRIDE=$containersConf run_podman create $IMAGE
   272      ctrID=$output
   273      CONTAINERS_CONF_OVERRIDE=$containersConf run_podman rm -f $ctrID
   274  
   275      # Now wait for the last event above to be read by the `podman-events`
   276      # process above.
   277      retries=20
   278      while [[ $retries -gt 0 ]]; do
   279          run grep "\"Status\"\:\"remove\"," $eventsJSON
   280          if [[ $status -eq 0 ]]; then
   281              break
   282          fi
   283          retries=$((retries - 1))
   284          sleep 0.5
   285      done
   286      test "$status" = 0 || die "Did not find expected 'Status:remove' line in log"
   287  
   288      # Make sure that the log file has been rotated as expected.
   289      run cat $eventsFile
   290      assert "${#lines[@]}" = 54 "Number of events in $eventsFile" # 49 previous + 2 rotation + pull/create/rm
   291      is "${lines[0]}" "{\"Name\":\"$eventsFile\",\"Status\":\"log-rotation\",\"Time\":\".*\",\"Type\":\"system\",\"Attributes\":{\"io.podman.event.rotate\":\"begin\"}}"
   292      is "${lines[1]}" "{\"Name\":\"busybox\",\"Status\":\"pull\",\"Time\":\"2022-04-06T11:26:42.723667951+02:00\",\"Type\":\"image\",\"Attributes\":null}"
   293      is "${lines[49]}" "{\"Name\":\"busybox\",\"Status\":\"pull\",\"Time\":\"2022-04-06T11:26:42.723667999+02:00\",\"Type\":\"image\",\"Attributes\":null}"
   294      is "${lines[50]}" "{\"Name\":\"$eventsFile\",\"Status\":\"log-rotation\",\"Time\":\".*\",\"Type\":\"system\",\"Attributes\":{\"io.podman.event.rotate\":\"end\"}}"
   295      is "${lines[53]}" "{\"ID\":\"$ctrID\",\"Image\":\"$IMAGE\",\"Name\":\".*\",\"Status\":\"remove\",\"Time\":\".*\",\"Type\":\"container\",\"Attributes\":{.*}}"
   296  
   297  
   298      # Make sure that the JSON stream looks as expected. That means it has all
   299      # events and no duplicates.
   300      run cat $eventsJSON
   301      is "${lines[0]}" "{\"Name\":\"busybox\",\"Status\":\"pull\",\"time\":1649237202,\"timeNano\":1649237202723[0-9]\+,\"Type\":\"image\",\"Attributes\":null}"
   302      is "${lines[99]}" "{\"Name\":\"busybox\",\"Status\":\"pull\",\"time\":1649237202,\"timeNano\":1649237202723[0-9]\+,\"Type\":\"image\",\"Attributes\":null}"
   303      is "${lines[100]}" "{\"Name\":\"$eventsFile\",\"Status\":\"log-rotation\",\"time\":[0-9]\+,\"timeNano\":[0-9]\+,\"Type\":\"system\",\"Attributes\":{\"io.podman.event.rotate\":\"end\"}}"
   304      is "${lines[103]}" "{\"ID\":\"$ctrID\",\"Image\":\"$IMAGE\",\"Name\":\".*\",\"Status\":\"remove\",\"time\":[0-9]\+,\"timeNano\":[0-9]\+,\"Type\":\"container\",\"Attributes\":{.*}}"
   305  }
   306  
   307  # Prior to #15633, container labels would not appear in 'die' log events
   308  @test "events - labels included in container die" {
   309      skip_if_remote "remote does not support --events-backend"
   310      local cname=c$(random_string 15)
   311      local lname=l$(random_string 10)
   312      local lvalue="v$(random_string 10) $(random_string 5)"
   313  
   314      run_podman 17 --events-backend=file run --rm \
   315                 --name=$cname \
   316                 --label=$lname="$lvalue" \
   317                 $IMAGE sh -c 'exit 17'
   318      run_podman --events-backend=file events \
   319                 --filter=container=$cname \
   320                 --filter=status=died \
   321                 --stream=false \
   322                 --format="{{.Attributes.$lname}}"
   323      assert "$output" = "$lvalue" "podman-events output includes container label"
   324  }
   325  
   326  @test "events - backend none should error" {
   327      skip_if_remote "remote does not support --events-backend"
   328  
   329      run_podman 125 --events-backend none events
   330      is "$output" "Error: cannot read events with the \"none\" backend" "correct error message"
   331      run_podman 125 --events-backend none events --stream=false
   332      is "$output" "Error: cannot read events with the \"none\" backend" "correct error message"
   333  }
   334  
   335  function _events_container_create_inspect_data {
   336      containersConf=$PODMAN_TMPDIR/containers.conf
   337      cat >$containersConf <<EOF
   338  [engine]
   339  events_logger="$1"
   340  events_container_create_inspect_data=true
   341  EOF
   342  
   343      local cname=c$(random_string 15)
   344      t0=$(date --iso-8601=seconds)
   345  
   346      CONTAINERS_CONF_OVERRIDE=$containersConf run_podman create --name=$cname $IMAGE
   347      CONTAINERS_CONF_OVERRIDE=$containersConf run_podman container inspect --size=true $cname
   348      inspect_json=$(jq -r --tab . <<< "$output")
   349  
   350      CONTAINERS_CONF_OVERRIDE=$containersConf run_podman --events-backend=$1 events \
   351          --since="$t0"           \
   352          --filter=status=$cname  \
   353          --filter=status=create  \
   354          --stream=false          \
   355          --format="{{.ContainerInspectData}}"
   356      events_json=$(jq -r --tab . <<< "[$output]")
   357      assert "$events_json" = "$inspect_json" "JSON payload in event attributes is the same as the inspect one"
   358  
   359      # Make sure that the inspect data doesn't show by default in
   360      # podman-events.
   361      CONTAINERS_CONF_OVERRIDE=$containersConf run_podman --events-backend=$1 events \
   362          --since="$t0"           \
   363          --filter=status=$cname  \
   364          --filter=status=create  \
   365          --stream=false
   366      assert "$output" != ".*ConmonPidFile.*"
   367      assert "$output" != ".*EffectiveCaps.*"
   368  }
   369  
   370  @test "events - container inspect data - journald" {
   371      skip_if_remote "remote does not support --events-backend"
   372      skip_if_journald_unavailable
   373  
   374      _events_container_create_inspect_data journald
   375  }
   376  
   377  @test "events - container inspect data - file" {
   378      skip_if_remote "remote does not support --events-backend"
   379  
   380      _events_container_create_inspect_data file
   381  }
   382  
   383  @test "events - docker compat" {
   384      local cname=c$(random_string 15)
   385      t0=$(date --iso-8601=seconds)
   386      run_podman run --name=$cname --rm $IMAGE true
   387      run_podman events \
   388          --since="$t0"           \
   389          --filter=status=$cname  \
   390          --filter=status=die     \
   391          --stream=false
   392      is "${lines[0]}" ".* container died .* (image=$IMAGE, name=$cname, .*)"
   393  }
   394  
   395  @test "events - volume events" {
   396      local vname=v$(random_string 10)
   397      run_podman volume create $vname
   398      run_podman volume rm $vname
   399  
   400      run_podman events --since=1m --stream=false --filter volume=$vname
   401      notrunc_results="$output"
   402      assert "${lines[0]}" =~ ".* volume create $vname"
   403      assert "${lines[1]}" =~ ".* volume remove $vname"
   404  
   405      # Prefix test
   406      run_podman events --since=1m --stream=false --filter volume=${vname:0:5}
   407      assert "$output" = "$notrunc_results"
   408  }
   409  
   410  @test "events - invalid filter" {
   411      run_podman 125 events --since="the dawn of time...ish"
   412      assert "$output" =~ "failed to parse event filters"
   413  }