Skip to content

Commit

Permalink
Fix issue with relative paths in Container.push_path (#949)
Browse files Browse the repository at this point in the history
  • Loading branch information
yanksyoon committed Jun 15, 2023
1 parent 3765013 commit cbaec52
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
4 changes: 2 additions & 2 deletions ops/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2093,7 +2093,7 @@ def push_path(self,

def local_list(source_path: Path) -> List[pebble.FileInfo]:
paths = source_path.iterdir() if source_path.is_dir() else [source_path]
files = [self._build_fileinfo(source_path / f) for f in paths]
files = [self._build_fileinfo(f) for f in paths]
return files

errors: List[Tuple[str, Exception]] = []
Expand Down Expand Up @@ -2256,7 +2256,7 @@ def _build_destpath(
# /src --> /dst/src
file_path, source_path, dest_dir = Path(file_path), Path(source_path), Path(dest_dir)
prefix = str(source_path.parent)
if os.path.commonprefix([prefix, str(file_path)]) != prefix:
if prefix != '.' and os.path.commonprefix([prefix, str(file_path)]) != prefix:
raise RuntimeError(
f'file "{file_path}" does not have specified prefix "{prefix}"')
path_suffix = os.path.relpath(str(file_path), prefix)
Expand Down
58 changes: 58 additions & 0 deletions test/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,64 @@ def test_recursive_push_and_pull(case):
assert c.exists(fpath), f'pull_path failed: file {fpath} missing at destination'


@pytest.mark.parametrize('case', [
PushPullCase(
name='push directory without trailing slash',
path='foo',
dst='/baz',
files=['foo/bar/baz.txt', 'foo/foobar.txt'],
want={'/baz/foo/foobar.txt', '/baz/foo/bar/baz.txt'},
),
PushPullCase(
name='push directory with trailing slash',
path='foo/',
dst='/baz',
files=['foo/bar/baz.txt', 'foo/foobar.txt'],
want={'/baz/foo/foobar.txt', '/baz/foo/bar/baz.txt'},
),
PushPullCase(
name='push directory relative pathing',
path='./foo',
dst='/baz',
files=['foo/bar/baz.txt', 'foo/foobar.txt'],
want={'/baz/foo/foobar.txt', '/baz/foo/bar/baz.txt'},
),
])
def test_push_path_relative(case):
harness = ops.testing.Harness(ops.CharmBase, meta='''
name: test-app
containers:
foo:
resource: foo-image
''')
harness.begin()
harness.set_can_connect('foo', True)
container = harness.model.unit.containers['foo']

with tempfile.TemporaryDirectory() as tmpdir:
cwd = os.getcwd()
# change working directory to enable relative pathing for testing
os.chdir(tmpdir)
try:
# create test files under temporary test directory
tmp = pathlib.Path(tmpdir)
for testfile in case.files:
testfile_path = pathlib.Path(tmp / testfile)
testfile_path.parent.mkdir(parents=True, exist_ok=True)
testfile_path.touch(exist_ok=True)
testfile_path.write_text("test", encoding="utf-8")

# push path under test to container
container.push_path(case.path, case.dst)

# test
for want_path in case.want:
content = container.pull(want_path).read()
assert content == 'test'
finally:
os.chdir(cwd)


class TestApplication(unittest.TestCase):

def setUp(self):
Expand Down

0 comments on commit cbaec52

Please sign in to comment.