Skip to content

Copy event status emitted by podman machine cp is missing from StringToStatus #29478

Description

@HindzStark

Issue Description

The events.Copy status (value: "copy") is defined in libpod/events/config.go and is actively emitted during podman machine cp operations via newMachineEvent(events.Copy, ...) in cmd/podman/machine/cp.go.

However, the authoritative mapping function StringToStatus in libpod/events/events.go completely lacks a case for "copy".

Because StringToStatus enforces the contract that every emitted event status must be deserializable, its omission breaks event processing paths that rely on it. Specifically, in the remote API path (pkg/domain/entities/events.go:25), when ConvertToLibpodEvent attempts to parse an incoming event with Action = "copy", StringToStatus("copy") returns the error unknown event status "copy". This causes machine cp events to be silently dropped or generate errors when interacting with Podman over the remote API or via tunneling.

Steps to reproduce the issue

  1. Initiate a podman machine cp command (which internally emits an events.Copy machine event).
  2. Concurrently monitor the event stream via the remote REST API (or any path that triggers ConvertToLibpodEvent in pkg/domain/entities/events.go).
  3. Note that the event conversion fails internally because StringToStatus("copy") returns an error, rather than mapping to events.Copy.

(Alternatively, simply inspect StringToStatus in libpod/events/events.go and observe that Copy is missing from the switch statement).

Describe the results you received

When the Action field of an event is "copy", StringToStatus returns an error:
unknown event status "copy"

This causes the event to fail conversion and be dropped in the remote client/API path.

Describe the results you expected

StringToStatus("copy") should return the events.Copy constant without error, just as it does for all other emitted event statuses (like Start, Stop, Init, Remove, etc.), ensuring events can be successfully serialized and deserialized across all API boundaries.

podman info output

time="2026-08-12T16:08:40Z" level=warning msg="\"/\" is not a shared mount, this could cause issues or missing mounts with rootless containers"
host:
  arch: amd64
  buildahVersion: 1.33.7
  cgroupControllers:
  - cpu
  - memory
  - pids
  cgroupManager: cgroupfs
  cgroupVersion: v2
  conmon:
    package: conmon_2.1.10+ds1-1build2_amd64
    path: /usr/bin/conmon
    version: 'conmon version 2.1.10, commit: unknown'
  cpuUtilization:
    idlePercent: 99.75
    systemPercent: 0.18
    userPercent: 0.07
  cpus: 32
  databaseBackend: sqlite
  distribution:
    codename: noble
    distribution: ubuntu
    version: "24.04"
  eventLogger: journald
  freeLocks: 2048
  hostname: LAPTOP-14T392O1
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
  kernel: 6.18.33.2-microsoft-standard-WSL2
  linkmode: dynamic
  logDriver: journald
  memFree: 6463332352
  memTotal: 7903866880
  networkBackend: netavark
  networkBackendInfo:
    backend: netavark
    dns:
      package: aardvark-dns_1.4.0-5_amd64
      path: /usr/lib/podman/aardvark-dns
      version: aardvark-dns 1.4.0
    package: netavark_1.4.0-4_amd64
    path: /usr/lib/podman/netavark
    version: netavark 1.4.0
  ociRuntime:
    name: crun
    package: Unknown
    path: /usr/local/bin/crun
    version: |-
      crun version 1.29.0.0.0.1-86e7
      commit: 86e7e3eaf8e8d15e6e9983faddeffd0ea0771a94
      rundir: /run/user/1000/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +JSON_C
  os: linux
  pasta:
    executable: /usr/local/bin/pasta
    package: Unknown
    version: |
      pasta 2026_07_28.f8df3f1
      Copyright Red Hat
      GNU General Public License, version 2 or later
        <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
      This is free software: you are free to change and redistribute it.
      There is NO WARRANTY, to the extent permitted by law.
  remoteSocket:
    exists: false
    path: /run/user/1000/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: true
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: false
  serviceIsRemote: false
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns_1.2.1-1build2_amd64
    version: |-
      slirp4netns version 1.2.1
      commit: 09e31e92fa3d2a1d3ca261adaeb012c8d75a8194
      libslirp: 4.7.0
      SLIRP_CONFIG_VERSION_MAX: 4
      libseccomp: 2.5.5
  swapFree: 2147483648
  swapTotal: 2147483648
  uptime: 0h 1m 20.00s
  variant: ""
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries: {}
store:
  configFile: /home/dhruv/.config/containers/storage.conf
  containerStore:
    number: 0
    paused: 0
    running: 0
    stopped: 0
  graphDriverName: overlay
  graphOptions: {}
  graphRoot: /tmp/podman_temp_root
  graphRootAllocated: 1081101176832
  graphRootUsed: 4823900160
  graphStatus:
    Backing Filesystem: extfs
    Native Overlay Diff: "true"
    Supports d_type: "true"
    Supports shifting: "false"
    Supports volatile: "true"
    Using metacopy: "false"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 0
  runRoot: /run/user/1000/containers
  transientStore: false
  volumePath: /tmp/podman_temp_root/volumes
version:
  APIVersion: 4.9.3
  Built: 0
  BuiltTime: Thu Jan  1 00:00:00 1970
  GitCommit: ""
  GoVersion: go1.22.2
  Os: linux
  OsArch: linux/amd64
  Version: 4.9.3

Podman in a container

No

Privileged Or Rootless

Rootless

Upstream Latest Release

Yes

Additional environment details

I am planning to submit a PR to fix this issue as part of an LFX Mentorship application contribution. The PR will simply add the missing Copy.String() case to StringToStatus in libpod/events/events.go and include a unit test in events_test.go to prevent future regressions.

Additional information

Additional information like issue happens only occasionally or issue happens with a particular architecture or on a particular setting

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions