|
1 | 1 | //===----------------------------------------------------------------------===// |
2 | | -// Copyright © 2025 Apple Inc. and the Containerization project authors. |
| 2 | +// Copyright © 2025-2026 Apple Inc. and the Containerization project authors. |
3 | 3 | // |
4 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | // you may not use this file except in compliance with the License. |
@@ -830,6 +830,59 @@ extension LinuxContainer { |
830 | 830 | try await relayManager.start(port: port, socket: socket) |
831 | 831 | try await relayAgent.relaySocket(port: port, configuration: socket) |
832 | 832 | } |
| 833 | + |
| 834 | + /// Default chunk size for file transfers (1MiB). |
| 835 | + public static let defaultCopyChunkSize = 1024 * 1024 |
| 836 | + |
| 837 | + /// Copy a file from the host into the container. |
| 838 | + public func copyIn( |
| 839 | + from source: URL, |
| 840 | + to destination: URL, |
| 841 | + mode: UInt32 = 0o644, |
| 842 | + createParents: Bool = true, |
| 843 | + chunkSize: Int = defaultCopyChunkSize, |
| 844 | + progress: ProgressHandler? = nil |
| 845 | + ) async throws { |
| 846 | + try await self.state.withLock { |
| 847 | + let state = try $0.startedState("copyIn") |
| 848 | + |
| 849 | + let guestPath = URL(filePath: self.root).appending(path: destination.path) |
| 850 | + try await state.vm.withAgent { agent in |
| 851 | + try await agent.copyIn( |
| 852 | + from: source, |
| 853 | + to: guestPath, |
| 854 | + mode: mode, |
| 855 | + createParents: createParents, |
| 856 | + chunkSize: chunkSize, |
| 857 | + progress: progress |
| 858 | + ) |
| 859 | + } |
| 860 | + } |
| 861 | + } |
| 862 | + |
| 863 | + /// Copy a file from the container to the host. |
| 864 | + public func copyOut( |
| 865 | + from source: URL, |
| 866 | + to destination: URL, |
| 867 | + createParents: Bool = true, |
| 868 | + chunkSize: Int = defaultCopyChunkSize, |
| 869 | + progress: ProgressHandler? = nil |
| 870 | + ) async throws { |
| 871 | + try await self.state.withLock { |
| 872 | + let state = try $0.startedState("copyOut") |
| 873 | + |
| 874 | + let guestPath = URL(filePath: self.root).appending(path: source.path) |
| 875 | + try await state.vm.withAgent { agent in |
| 876 | + try await agent.copyOut( |
| 877 | + from: guestPath, |
| 878 | + to: destination, |
| 879 | + createParents: createParents, |
| 880 | + chunkSize: chunkSize, |
| 881 | + progress: progress |
| 882 | + ) |
| 883 | + } |
| 884 | + } |
| 885 | + } |
833 | 886 | } |
834 | 887 |
|
835 | 888 | extension VirtualMachineInstance { |
|
0 commit comments