Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow (or document) Container.push behavior on overwrite #752

Closed
paulomach opened this issue May 13, 2022 · 8 comments · Fixed by #1094
Closed

Allow (or document) Container.push behavior on overwrite #752

paulomach opened this issue May 13, 2022 · 8 comments · Fixed by #1094
Assignees
Labels
docs Improvements or additions to documentation small item

Comments

@paulomach
Copy link
Contributor

paulomach commented May 13, 2022

Issue

Container.push currently does not allow file overwriting, but the behavior is not documented in docs.

Suggestion

  1. Add a boolean overwrite flag that when True test if path exists and remove it before pushing.
  2. Update docs about overwrite behavior.
@benhoyt
Copy link
Collaborator

benhoyt commented May 15, 2022

@paulomach I can't reproduce this locally. I'm running the Pebble server/daemon in one terminal:

$ PEBBLE=~/pebble go run ./cmd/pebble run
...

And then using the test Pebble CLI to execute a push, like so:

$ PEBBLE=~/pebble python3 -m test.pebble_cli push ./setup.py /home/ben/w/pebble/setup.py
wrote ./setup.py to remote file /home/ben/w/pebble/setup.py
$ PEBBLE=~/pebble python3 -m test.pebble_cli push ./setup.py /home/ben/w/pebble/setup.py
wrote ./setup.py to remote file /home/ben/w/pebble/setup.py
# modify ./setup.py
$ PEBBLE=~/pebble python3 -m test.pebble_cli push ./setup.py /home/ben/w/pebble/setup.py
wrote ./setup.py to remote file /home/ben/w/pebble/setup.py
# changes appear in /home/ben/w/pebble/setup.py

I can do the push successfully many times, and when I make changes in the source, the destination updates fine.

Are you able to send a repro for the case you're seeing, and the error messages you get?

@paulomach
Copy link
Contributor Author

Hi @benhoyt , absolutely.

Since I've observed that on charm context, I've wrote a simple charm that implements replicates the error, available here.

The traceback observed is:

Traceback (most recent call last):
  File "./src/charm.py", line 44, in <module>
    main(TestPebblePushCharm)
  File "/var/lib/juju/agents/unit-test-pebble-push-0/charm/venv/ops/main.py", line 431, in main
    _emit_charm_event(charm, dispatcher.event_name)
  File "/var/lib/juju/agents/unit-test-pebble-push-0/charm/venv/ops/main.py", line 142, in _emit_charm_event
    event_to_emit.emit(*args, **kwargs)
  File "/var/lib/juju/agents/unit-test-pebble-push-0/charm/venv/ops/framework.py", line 283, in emit
    framework._emit(event)
  File "/var/lib/juju/agents/unit-test-pebble-push-0/charm/venv/ops/framework.py", line 743, in _emit
    self._reemit(event_path)
  File "/var/lib/juju/agents/unit-test-pebble-push-0/charm/venv/ops/framework.py", line 790, in _reemit
    custom_handler(event)
  File "./src/charm.py", line 38, in _on_pebble_ready
    container.push("/etc/resolv.conf", "\n".join(content))
  File "/var/lib/juju/agents/unit-test-pebble-push-0/charm/venv/ops/model.py", line 1282, in push
    self._pebble.push(path, source, encoding=encoding, make_dirs=make_dirs,
  File "/var/lib/juju/agents/unit-test-pebble-push-0/charm/venv/ops/pebble.py", line 1726, in push
    self._raise_on_path_error(resp, path)
  File "/var/lib/juju/agents/unit-test-pebble-push-0/charm/venv/ops/pebble.py", line 1683, in _raise_on_path_error
    raise PathError(error['kind'], error['message'])
ops.pebble.PathError: generic-file-error - rename /etc/resolv.conf.8xThkKlBDntr~ /etc/resolv.conf: device or resource busy

@rwcarlsen
Copy link
Contributor

This is because another process has resolv.conf opened - the file is currently in use and can't be removed/overwritten. You can lsof | grep 'resolv.conf' to check what processes are using it.

@paulomach
Copy link
Contributor Author

Hey @rwcarlsen , that's was my initial thought also, but there's no process owning the file.
Running lsof does not show any process with the file open (link to pastebin)
And this can be reproduced to others containers files, not only resolv.conf.

@rwcarlsen
Copy link
Contributor

@paulomach
Copy link
Contributor Author

That's the issue. There other files of interest that are bind mounts, like /etc/hosts.
Having the push implementation on pebble to copy over the original file can make it work (instead of mv/rename).
But I don't know if there's any drawbacks on doing that.
Should that limitation (overwrite bind mounts) be documented?

@rwcarlsen
Copy link
Contributor

It's probably worth mentioning in docs somewhere that bind mounts for files will interfere with workload-side file operations.

@benhoyt benhoyt added the docs Improvements or additions to documentation label May 1, 2023
@benhoyt
Copy link
Collaborator

benhoyt commented Oct 4, 2023

Yeah, let's update the push docs to mention this gotcha and perhaps suggest a workaround for locked file / bind mount cases ("use Container.exec for full control" or whatever).

@tonyandrewmeyer tonyandrewmeyer changed the title Allow (or document) Container.push behavior on overwrite. Allow (or document) Container.push behavior on overwrite Dec 15, 2023
@tonyandrewmeyer tonyandrewmeyer self-assigned this Dec 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Improvements or additions to documentation small item
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants