| 337 | _build(service, use_cache=use_cache and use_leaf_cache) |
| 338 | |
| 339 | def run(self, service_name, command=None, *, env=None, volumes=None, |
| 340 | user=None, resource_limit=None): |
| 341 | service = self.config.get(service_name) |
| 342 | |
| 343 | args = [] |
| 344 | |
| 345 | use_docker = self.config.using_docker or service['need_gpu'] or resource_limit |
| 346 | if use_docker: |
| 347 | # use gpus, requires docker>=19.03 |
| 348 | if service['need_gpu']: |
| 349 | args.extend(['--gpus', 'all']) |
| 350 | |
| 351 | if service.get('shm_size'): |
| 352 | args.extend(['--shm-size', service['shm_size']]) |
| 353 | |
| 354 | # append env variables from the compose conf |
| 355 | for k, v in service.get('environment', {}).items(): |
| 356 | if v is not None: |
| 357 | args.extend(['-e', f'{k}={v}']) |
| 358 | |
| 359 | # append volumes from the compose conf |
| 360 | for v in service.get('volumes', []): |
| 361 | if not isinstance(v, str): |
| 362 | # if not the compact string volume definition |
| 363 | v = f'{v["source"]}:{v["target"]}' |
| 364 | args.extend(['-v', v]) |
| 365 | |
| 366 | # append capabilities from the compose conf |
| 367 | for c in service.get('cap_add', []): |
| 368 | args.extend([f'--cap-add={c}']) |
| 369 | |
| 370 | # infer whether an interactive shell is desired or not |
| 371 | if command in ['cmd.exe', 'bash', 'sh', 'powershell']: |
| 372 | args.append('-it') |
| 373 | |
| 374 | if resource_limit: |
| 375 | limits = self.config.limit_presets.get(resource_limit) |
| 376 | if not limits: |
| 377 | raise ValueError( |
| 378 | f"Unknown resource limit preset '{resource_limit}'") |
| 379 | cpuset = limits.get('cpuset_cpus', []) |
| 380 | if cpuset: |
| 381 | args.append(f'--cpuset-cpus={",".join(map(str, cpuset))}') |
| 382 | memory = limits.get('memory') |
| 383 | if memory: |
| 384 | args.append(f'--memory={memory}') |
| 385 | args.append(f'--memory-swap={memory}') |
| 386 | |
| 387 | if user is not None: |
| 388 | args.extend(['-u', user]) |
| 389 | |
| 390 | if env is not None: |
| 391 | for k, v in env.items(): |
| 392 | args.extend(['-e', f'{k}={v}']) |
| 393 | |
| 394 | if volumes is not None: |
| 395 | for volume in volumes: |
| 396 | args.extend(['--volume', volume]) |