Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions xmanager/xm_local/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,12 @@ async def _launch_loaded_container_image(
env_vars = {**executable.env_vars, **job.env_vars}
options = executor.docker_options or executors.DockerOptions()

volumes = options.volumes or {}
# Add GCP credentials to Local Executor.
local_gcloud_config_path = os.path.expanduser('~/.config/gcloud')
image_gcloud_config_path = '/root/.config/gcloud'
volumes[local_gcloud_config_path] = image_gcloud_config_path
volumes = dict(options.volumes or {})
if options.mount_gcloud_config:
# Add GCP credentials to Local Executor.
local_gcloud_config_path = os.path.expanduser('~/.config/gcloud')
image_gcloud_config_path = '/root/.config/gcloud'
volumes[local_gcloud_config_path] = image_gcloud_config_path

if options.mount_gcs_path and os.path.isdir(os.path.expanduser('~/gcs')):
local_gcs_path = os.path.expanduser('~/gcs')
Expand Down
60 changes: 60 additions & 0 deletions xmanager/xm_local/execution_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,66 @@ async def test_container_launch_dispatcher(
interactive=interactive,
)

async def _launched_volumes(
self, docker_options: local_executors.DockerOptions
) -> dict[str, str]:
executable = local_executables.LoadedContainerImage(
name='test',
image_id='test-image',
args=xm.SequentialArgs.from_collection({}),
env_vars={},
)
job = xm.Job(
name='test-job',
executable=executable,
executor=local_executors.Local(docker_options=docker_options),
)
adapter = mock.MagicMock()
adapter.has_network.return_value = True
adapter.run_container.return_value = mock.sentinel.container

with mock.patch.object(docker_adapter, 'instance', return_value=adapter):
await execution._launch_loaded_container_image( # pylint: disable=protected-access
lambda name: name,
job,
executable,
)

return adapter.run_container.call_args.kwargs['volumes']

async def test_can_disable_gcloud_config_mount(self):
configured_volumes = {'a': 'b'}

launched_volumes = await self._launched_volumes(
local_executors.DockerOptions(
volumes=configured_volumes,
mount_gcs_path=False,
mount_gcloud_config=False,
)
)

self.assertEqual(launched_volumes, {'a': 'b'})
self.assertEqual(configured_volumes, {'a': 'b'})

async def test_gcloud_config_mount_remains_enabled_by_default(self):
configured_volumes = {'a': 'b'}

launched_volumes = await self._launched_volumes(
local_executors.DockerOptions(
volumes=configured_volumes,
mount_gcs_path=False,
)
)

self.assertEqual(
launched_volumes,
{
'a': 'b',
os.path.expanduser('~/.config/gcloud'): '/root/.config/gcloud',
},
)
self.assertEqual(configured_volumes, {'a': 'b'})

@parameterized.product(
mount_gcs_path=[True, False],
gcs_dir_exists=[True, False],
Expand Down
4 changes: 4 additions & 0 deletions xmanager/xm_local/executors.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,16 @@ class DockerOptions:
mount_gcs_path: If True, checks for the `~/gcs` directory on the host and
mounts it (if found) at `/gcs` in the container. Defaults to True.
interactive: If True, requests a run with interactive shell.
mount_gcloud_config: If True, mounts the host's `~/.config/gcloud`
directory at `/root/.config/gcloud` in the container. Defaults to True
for compatibility.
"""

ports: Optional[docker_adapter.Ports] = None
volumes: Optional[Dict[str, str]] = None
mount_gcs_path: bool = True
interactive: bool = False
mount_gcloud_config: bool = True


@attr.s(auto_attribs=True)
Expand Down