-
仮想化アプリの機能の拡張
macOS 27のパワフルな新機能で仮想化アプリの機能を拡張しましょう。初回起動時のユーザーアカウント設定を通じて、macOSゲストのセットアップを自動化する方法を紹介します。仮想マシンへのUSBアクセサリのパススルー、カスタムネットワークトポロジー、ポートフォワーディングなどの高度なワークフローについて解説するほか、アプリにおける仮想マシンの利用体験を向上させる最新の機能強化についても確認します。
関連する章
- 0:01 - Introduction
- 1:04 - macOS guest provisioning
- 4:34 - Accessory Access
- 8:26 - Advanced network topologies
- 11:35 - DiskImageKit
- 15:57 - Custom Virtio
リソース
関連ビデオ
WWDC26
-
このビデオを検索
こんにちは!
VirtualizationチームのRonnie Misraです。 このセッションでは、高度な機能を 追加する方法を探ります。 Virtualizationアプリへの追加です。 Virtualizationフレームワークを使用すると、 完全なデスクトップ体験を提供する アプリを作成できます。 また、洗練されたデベロッパワークフローも 実現できます。 Mac同士のコラボレーションアプリのテストや デバイス間のネットワーキングなどです。 コマンドラインツールや オートメーションも構築できます。 制御された環境での一貫したテストを 実現するためです。 本日は、新しいAPIと既存のAPIを ご紹介します。 Virtualizationアプリをさらに 強力にするためのものです。 取り上げる内容は、Virtual Macの セットアップの自動化と、 仮想マシンへのUSBデバイスの 接続です。 Accessory Accessフレームワークを 使用します。 高度なネットワークトポロジの設定の 探索と、 ハイパフォーマンスで 効率的なディスクイメージの作成を DiskImageKitフレームワークで行います。 最後に、カスタムで ハイパフォーマンスな仮想デバイスを Virtioで作成する方法を取り上げます。
まず、Virtualizationを使用して macOSゲストプロビジョニングを 自動化する方法をご紹介します。 仮想MacにmacOSをインストールした後、 物理Macのセットアップと同様の方法で 設定できます。 既に使い慣れている設定アシスタントを 使用します。 これにより、ユーザーアカウントを 簡単に作成できます。 一般的な設定も行えます。 ただし、自動化のユースケースでは、 仮想Macをプログラムで セットアップできると便利です。 Virtualizationフレームワークでは プロビジョニング設定の指定が可能です。 仮想Macの起動時に指定します。 フルネーム、ユーザー名、パスワードを 指定します。 自動ログインやSSHリモートログインを オプションで有効にできます。 ゲストが初めて起動するとき、 これらのパラメータは自動的に 設定アシスタントに渡されます。 指定した認証情報でユーザーが作成されます。 要求された場合、自動ログインと リモートログインが有効になります。 macOSゲストプロビジョニングAPIを 使用するには、 まずVZMacGuestProvisioningOptionsオブジェクトを 作成します。 希望の設定で作成します。 ここでは、ユーザーアカウントを作成する provisioningOptionsを作成しました。 自動ログインとSSHも有効にします。 次に、VZMacOSVirtualMachineStartOptionsオブジェクトを 作成します。 ゲストプロビジョニングを設定し、 先ほど作成したprovisioningOptionsに 設定します。 最後に、startOptionsを使用して 仮想Macを起動します。 ゲストが起動すると、 これらのプロビジョニングオプションで 仮想Macのプロビジョニングを自動化します。 これを実際にお見せします。 macOS仮想マシンのサンプルアプリを 変更しました。 macOSゲストプロビジョニングAPIを 利用するためです。 新しい仮想MacにmacOSをインストール済みです。 まだ起動していません。 アプリをダブルクリックして 仮想Macを初回起動します。
アプリがプロビジョニングオプションを 求めてきます。 以前にこのアプリを実行したことがあるため、 優先するプロビジョニングオプションを 記憶しています。 Jane Appleseedのユーザーを 作成するためのものです。 自動ログインとリモートログインを 有効にします。 をクリックして 設定を承認します。
プロビジョニングオプションで 仮想Macを起動しました。 Virtualizationフレームワークがゲストに オプションを渡します。 設定アシスタントを手動で操作する 必要はありません。 設定アシスタントが自動的に 新しいユーザーを作成します。 設定アシスタントが新しいアカウントを 作成しました。 プロビジョニングオプションで 自動ログイン有効化を指定していたため、 ゲストはアカウントにログインしています。 仮想MacでFinderウィンドウを 開きます。
サイドバーのユーザー名はjappleseedで、 指定と一致します。 システム設定を開きます。 リモートログインの共有設定を確認します。
システム設定でリモートログインが 有効であることを確認できます。 仮想Macの準備ができました! 起動するだけでよかったのです。 これらの設定は、ゲストがまだ セットアップされていない場合のみ有効です。 ゲストにすでにユーザーが作成されている場合、 後続の起動時に渡されるプロビジョニングオプションは 無視されます。 これらのAPIを使用する際は、 パスワードの扱いに注意してください。 アプリのセキュリティへの影響を 考慮してください。 例えば、コードにパスワードを ハードコードする代わりに、 キーチェーンから読み取ることを 検討してください。
または設定ファイルや環境変数から 読み取ります。 次は、USBアクセサリの接続についてです。 Accessory Accessを使用します。
一部の仮想マシンのユースケースでは、 ホストに接続されたUSBアクセサリへの ゲストアクセスを許可する機能が必要です。 例えば、仮想マシン内から USBドライブを使用したい場合があります。 仮想マシンの内部からです。 同時に、ユーザーはデバイスを コントロールし続けられる必要があります。 Accessory Accessは新しいフレームワークです。 macOSおよびLinux仮想マシンへの USBデバイスの利用を可能にします。 Accessory Accessの主要な原則は、 ユーザーが明示的に制御できることです。 どのデバイスがどのアプリに 接続されているかを制御します。 どのアプリがデバイスを 使用しているか確認できます。 デバイスをいつでも 接続・切断できます。 Accessory Accessは デバイスのホットプラグをサポートします。 アプリにデバイスへのアクセスが 許可されると、 実行時に仮想マシンに接続できます。 VMの静的設定を変更せずに 接続できます。 詳細に入る前に、Accessory Accessの 動作をご覧ください。 先ほどお見せしたmacOS仮想マシンの サンプルアプリを実行しています。 MacにUSBドライブを接続します。
ドライブのアイコンがデスクトップに 表示されました。 また、仮想マシンアプリが実行されているため、 ストレージデバイスへの 関心を示しています。 アクセサリアイコンがメニューバーに 表示されました。 アクセサリメニューでディスクを選択します。 アプリに接続します。
このドライブを仮想Macに接続したので、 ホストのドライブはアンマウントされ、 ゲストでマウントされました。 仮想Macの内部から 安全にドライブをイジェクトします。
次に、アクセサリメニューを使用して ドライブをホストに戻します。
ドライブをホストに返したので、 ホストがドライブを再マウントしました。 Accessory AccessでUSBアクセサリを 簡単に使用できることを示しました。 仮想マシンからです。 Accessory Accessを使用するには、 アプリが一致条件でリスナーを登録します。 関心を持つデバイスの種類を記述します。 デバイスクラスとサブクラスで フィルタリングできます。 ベンダーIDと製品IDでも。 またはその他の条件でも可能です。 一致するデバイスがMacに接続されると、 Accessory Accessメニューエクストラが 表示されます。 ここから、ユーザーがデバイスをアプリに 接続するか選択できます。 デバイスがアプリに接続されると、 アプリのリスナーオブジェクトに 新しく接続されたデバイスが通知されます。 Accessory Accessを使用するには、 AAUSBAccessoryMatchingCriteriaオブジェクトの 配列を作成することから始めます。 関心を持つデバイスの種類を記述します。 空の配列を使用して すべてのUSBデバイスへの関心を表現できます。 次に、AAUSBAccessoryManagerを使用して リスナーを登録します。 このリスナーはAAUSBAccessoryListenerプロトコルを 実装する必要があります。 registerListenerは 既存のアクセサリを返します。 以前にアプリに接続されていたものです。 ユーザーがデバイスをアプリに接続すると、 リスナーのusbAccessoryDidConnect関数が 呼び出されます。 この関数でデバイスを 仮想マシンに接続できます。 VZVirtualMachineでは変更を 専用のキューで行う必要があります。 そのキューで VZUSBPassthroughDeviceConfigurationクラスを使用します。 VZUSBPassthroughDeviceを作成し、 virtualMachineのUSBコントローラの 1つにデバイスを接続します。
アプリでAccessory Accessを使用するには、 XcodeターゲットのCapabilitiesに 「Claim USB Accessory」を追加します。 ユーザーはいつでも選択できることを 覚えておいてください。 デバイスをアプリに接続または 切断できます。 アプリはこれらのイベントを 適切に処理する必要があります。 サポートされるデバイスタイプの詳細は Accessory Accessドキュメントを参照してください。
macOS 26以降では、アプリで vmnetフレームワークを使用できます。 仮想ネットワークインターフェイスを 設定するためです。 Virtualizationフレームワークでは 分離された仮想マシンを簡単に設定できます。 基本的なNATまたはブリッジ ネットワーキングで設定できます。 ただし、より高度なユースケースでは より多くの制御が必要な場合があります。 VMどうしの通信や 外部ネットワークとの接続についてです。 例えば、サーバー仮想マシンへの 接続をテストしたい場合があります。 同じネットワークまたは異なる ネットワーク上のクライアントからです。 vmnetフレームワークを使用すると カスタムネットワークトポロジーを作成できます。 これらの高度なユースケースを サポートするためです。 vmnetフレームワークを使用すると カスタムネットワークトポロジーを作成できます。 macOSおよびLinux VMのためです。 vmnetではVM間の通信方法を 制御できます。 vmnetではカスタムネットワークの さまざまなパラメータも設定できます。 例えば、ネットワークのDHCP設定を 行うことができます。 またはTCPやUDPのホストポートを フォワードするルールを追加できます。 特定の仮想マシンに転送します。 vmnetをVirtualizationフレームワークで 使用するには、 まずvmnetネットワーク設定オブジェクトを 作成します。 その設定を使用して vmnetネットワークオブジェクトを構築します。 そのネットワークオブジェクトを使用して ネットワークデバイスアタッチメントを構築できます。 このネットワークデバイスアタッチメントは ネットワークデバイス設定に接続されます。 そしてそれが仮想マシン設定に 追加されます。 最後に、その仮想マシン設定を 使用して 仮想マシンを構築します。 2台目の仮想マシンが同じvmnetネットワークを 使用する場合は、 同じ手順に従って 2台目の仮想マシンを設定します。 同じvmnetネットワークオブジェクトを 使用するようにしてください。 これらの手順をコードでお見せします。 まず、vmnet設定オブジェクトを作成します。 vmnet_network_configuration_createを使用します。 vmnetにはネットワークをカスタマイズする 関数がいくつか用意されています。 例えば、ネットワークのDHCP設定を 行えます。 ポートフォワーディングの有効化なども できます。 ネットワーク設定オブジェクトができたら、 vmnet_network_createを使用して vmnetネットワークオブジェクトを構築できます。 次に、VZVmnetNetworkDeviceAttachmentを構築します。 作成したvmnetネットワークを Virtualizationで使用できるようにします。
次に、VZVirtioNetworkDeviceConfigurationオブジェクトに アタッチメントを設定します。 このnetworkDeviceConfigurationは networkDevicesの配列に追加されます。 VZVirtualMachineConfigurationオブジェクトの 配列です。 最後に、この設定を使用して VZVirtualMachineを構築します。 vmnetネットワークオブジェクトは 参照カウント式のObjective-Cオブジェクトです。 最後の参照が解放されると ネットワークが削除されます。 アプリが終了すると vmnetネットワークは保持されません。 一貫したネットワーク設定を作成したい場合は、 アプリ自身でvmnetの設定を 保持する必要があります。 vmnetには vmnet_network_copy_serialization とvmnet_network_create_with_serialization APIがあり vmnetネットワークを転送できます。 XPC接続を通じてプロセス間で 転送できます。 複数のVMを別々のプロセスで実行して 同じネットワークに接続する場合に便利です。 同じネットワークに接続するためです。
次に、DiskImageKitを使用して ディスクイメージを効率的に扱う方法をご紹介します。 Virtualizationフレームワークは 標準のrawディスクイメージファイルの使用をサポートしています。 仮想マシンのディスクとして使用します。 このシンプルな形式はディスクブロックを ファイルブロックに1対1でマッピングします。 このシンプルさから、既存のソフトウェアで 広くサポートされています。 ただし、このシンプルさには コストが伴います。 rawディスクイメージは 本来スパース性を表現できません。 例えば、100ギガバイトのディスクは 100ギガバイトのファイルとして表現されます。 これによりスナップショットも高コストになります。 VMのディスクをスナップショットするには ディスク全体のコピーが必要です。
DiskImageKitはmacOS 27の 新しいフレームワークです。 ディスクイメージ管理を より効率的にするために設計されています。 macOS 26で導入されたApple Sparse Image Format(ASIF)を サポートしています。 DiskImageKitを使用すると イメージのスタックを構築できます。 書き込みはオーバーレイレイヤに行われ、 ベースレイヤはそのまま保持されます。 DiskImageKitはrawディスクイメージも サポートしています。 スタックイメージを構築する際、 DiskImageKitはいくつかの 異なるレイヤタイプをサポートしています。 スタックイメージの最下層は ベースレイヤと呼ばれます。 このレイヤはDiskImageKitが サポートする任意の形式を使用できます。 上位レイヤは常にASIFイメージです。 これらのレイヤはキャッシュまたは オーバーレイレイヤになります。 キャッシュレイヤは パフォーマンス向上に使用できます。 下位レイヤが低速なストレージに 存在する場合です。 リモートネットワークファイルシステムなどです。 読み取りリクエスト処理時に、キャッシュレイヤが 読み取りを満たせない場合、 DiskImageKitは下位レイヤから 読み取りを満たします。 そしてデータのコピーを キャッシュレイヤに保存します。 以降、同じデータの読み取りは キャッシュから行われます。
オーバーレイレイヤはスナップショットの コピーオンライトセマンティクスの実装に使用できます。 レイヤード イメージへの書き込み時に、 DiskImageKitがスタック走査中に 書き込み可能なオーバーレイを検出すると、 そのレイヤに書き込みを保存します。
DiskImageKitでは読み取り専用レイヤを 複数の並行スタックで共有できます。 これにより共有コンテンツを 効率的に再利用できます。 複数の仮想マシン間で それぞれの独立した書き込みを 分離したまま共有できます。
ASIFイメージはスパースです。 ASIFイメージは論理的には 実際に保存されているより多くのブロックを 表現できます。 ASIFファイルの読み取り時に イメージに保存されていないブロックは ゼロで満たされているとして扱われます。
DiskImageKitが読み書きリクエストを 処理する方法を 例を用いて説明します。 この例では、ベースレイヤに ブロック0、1、4のコンテンツがあります。 キャッシュレイヤには どのブロックのコンテンツもありません。 オーバーレイレイヤには ブロック4の更新コンテンツがあります。 またブロック5のコンテンツもあります。 レイヤは上下のレイヤと 異なる論理サイズを持てる点に注意してください。 上下のレイヤとです。 ブロック0の読み取りを満たすために、 DiskImageKitはスタックイメージの レイヤを走査します。 このブロックのコンテンツを含む レイヤが見つかるまで続けます。 この読み取りはベースレイヤによって 満たされます。 キャッシュレイヤがあるため、 DiskImageKitはこのブロックの コンテンツをキャッシュします。 そして呼び出し元に コンテンツを返します。 同じブロックの以降の読み取りは キャッシュレイヤから満たされます。
ブロック2を書き込む場合、 DiskImageKitは最上位レイヤが オーバーレイであることを検出し、 そこにコンテンツを保存します。
DiskImageKitイメージを Virtualizationで使用するには、 まずDiskImageオブジェクトを 作成することから始めます。
レイヤードイメージを使用する場合は、 複数のDiskImageオブジェクトを作成して 順番に追加します。 次にstackedImageから VZDiskImageStorageDeviceAttachmentを構築できます。 stackedImageからです。 これをstorageDeviceConfigurationに 接続できます。 例えば VZVirtioBlockDeviceConfigurationです。 このstorageDeviceConfigurationを 仮想マシン設定の storageDevicesに追加します。 最後に、この設定を使用して VZVirtualMachineを作成します。
スタックイメージを使用する際は、 スタックが浅いほどパフォーマンスが 優れていることを覚えておいてください。 パフォーマンスコストがあります。 ディスクイメージスタックの深さを 増やすことによるものです。 仮想マシンはディスクイメージだけで 構成されていないことを覚えておいてください。 例えば、仮想Macには 補助ストレージファイルがあります。 またEFIブートローダーを使用するVMには EFI変数ストアファイルがあります。 VMをクローンして共有ベースレイヤを 使用する場合は、 それらの他のファイルも複製する 必要があることを覚えておいてください。
最後に、カスタムVirtio APIが カスタム通信チャネルを 構築できる方法をご紹介します。 ホストアプリとLinux仮想マシン間の 通信チャネルです。
Virtualizationフレームワークはすでに 幅広い 標準デバイスクラスをサポートしていますが、 一部のユースケースでは より特化したものが必要な場合があります。 カスタムプロトコルを 実装したい場合があります。 ホストとゲスト間の パフォーマンスクリティカルな通信のためです。 Virtioクリプトデバイスなどの コプロセッサを実装したい場合もあります。 機械学習アクセラレーターへの 効率的なゲストアクセスを 提供したい場合もあります。 そこでカスタムVirtioデバイスAPIの 出番です。 Virtioは準仮想化デバイスの 業界標準です。 組み込みのVirtualizationデバイスの多くを 実装するために使用されているプロトコルです。 macOS 27では、Virtualizationフレームワークで 独自のVirtioデバイスを 実装できます。 ホストアプリとLinux仮想マシン間の カスタム通信が可能になります。 これはパフォーマンスクリティカルな シナリオで特に有用です。 ローレイテンシ・ハイスループットの 通信が必要な場合です。
Virtioプロトコルはゲストとホスト間で 共有されるメモリバッファを使用します。 ゲストとホスト間で共有されます。 これらのバッファはVirtioキューに 整理されています。 Virtioはゲストとホスト間の コンテキストスイッチ回数を 最小化するように設計されています。 ゲスト内のデバイスドライバは ホスト上で動作するデバイスに通知します。 データがエンキューされたときです。 同様に、ホストは割り込みを使用して エンキューされたデータについて ゲストドライバに通知できます。
macOS 27では、 VZCustomVirtioDeviceクラスを使用して カスタムデバイスを実装できます。 アプリはデバイスにデリゲートを設定します。 このデリゲートはゲストがキューにデータを エンキューすると通知されます。 デバイスの割り込みをトリガーすることで ゲストでアクティビティを開始することもできます。 カスタムVirtioデバイスAPIを 使用するには、 まずVZCustomVirtioDeviceConfigurationオブジェクトを 作成することから始めます。 このオブジェクトにデバイスのVirtioデバイス IDを設定します。 PCIクラスとサブクラスを設定します。 そしてデバイスが使用するVirtioキューの 数を設定します。
また、設定にプロバイダも 設定します。 VZCustomVirtioDeviceDelegateProviderは デリゲートの設定に使用されます。 VZCustomVirtioDevice- ConfigurationDelegateプロトコルを実装します。 次に、このdeviceConfigurationを virtualMachineConfigurationの customVirtioDevices配列に追加します。 そしてその設定を使用して VZVirtualMachineを作成します。
仮想マシンが起動されると、 VZCustomVirtioDeviceオブジェクトが 作成されます。 そして設定デリゲートの didCreateDevice関数が呼び出されます。 この関数で、デバイスの デリゲートを設定してください。 このデリゲートはVZCustomVirtioDeviceDelegateプロトコルを 実装する必要があります。 デバイス自体を保持することもできます。 デバイスがゲスト割り込みを トリガーできるようにするためです。
VZCustomVirtioDeviceDelegateプロトコルには いくつかの関数があります。 デバイスのライフサイクルを モニタリングするためのものです。 そしてデバイスとやり取りします。 didReceiveNotificationFor関数に ロジックを実装します。 デバイスのキューから要素を デキューするためです。 要素を処理し、 キューに戻します。
カスタムデバイスにはカスタムドライバが 必要であることを覚えておいてください。 ゲストがデバイスを使用できるようにするためです。 Virtioキューはゲストとホスト間の 効率的な通信を提供するよう設計されています。 ゲストとホスト間のです。 ゲストドライバを設計する際は ベストプラクティスに従ってください。 Virtioキューを最適に活用するためです。 まとめる前に、 Virtualizationのその他の進化について 簡単にご紹介します。 アプリをさらに輝かせるものです。
iCloudサポートはデスクトップ体験に 特に価値があります。 VM内でiCloudのデータと サービスにアクセスできます。 EFI Secure BootによりLinux VMが 最新のセキュリティ機能で強化されます。 macOSゲストでは引数バッファなど Metalの機能を活用できます。 間接コマンドバッファなどもです。
Virtualizationアプリに さらなる機能を追加する準備ができました。 Virtualizationアプリへのです。 プロビジョニングオプションを設定して macOSユーザーアカウントのセットアップを自動化します。 プロビジョニングオプションで 設定します。 Accessory AccessフレームワークでUSBデバイスを VMに接続します。 独自のネットワークトポロジーを構築して VMのネットワークをカスタマイズします。 ポートフォワーディングも設定できます。 DiskImageKitフレームワークで 効率的なスパースディスクイメージを作成します。 Linuxゲストでカスタムかつ ハイパフォーマンスなデバイスが必要な場合は、 Virtioでカスタムデバイスを 作成することを検討してください。
ご視聴ありがとうございました。 よいWWDCをお過ごしください。
-
-
1:57 - Provision a macOS guest
import Virtualization let provisioningOptions = VZMacGuestProvisioningOptions() provisioningOptions.fullName = fullName provisioningOptions.username = username provisioningOptions.password = password provisioningOptions.logsInAutomatically = true provisioningOptions.enablesRemoteLogin = true let startOptions = VZMacOSVirtualMachineStartOptions() try startOptions.setGuestProvisioning(provisioningOptions) try await virtualMachine.start(options: startOptions) -
7:12 - Register an Accessory Access listener
import AccessoryAccess let criteria: [AAUSBAccessoryMatchingCriteria] = [] let accessories = try await AAUSBAccessoryManager.shared.registerListener(self, matchingCriteria: criteria) for accessory in accessories { // Handle previously attached accessories. } -
7:39 - Respond to USB accessory connection
import AccessoryAccess import Virtualization class AccessoryListener: NSObject, AAUSBAccessoryListener { func usbAccessoryDidConnect(_ usbAccessory: AAUSBAccessory) { virtualMachine.queue.async { do { let configuration = VZUSBPassthroughDeviceConfiguration(device: usbAccessory) let device = try VZUSBPassthroughDevice(configuration: configuration) self.virtualMachine.usbControllers.first?.attach(device: device) { error in // Handle error if necessary... } } catch { // Handle error... } } } } -
10:04 - Create a custom vmnet network
import Virtualization import vmnet var status: vmnet_return_t = .VMNET_FAILURE guard let networkConfiguration = vmnet_network_configuration_create(.VMNET_SHARED_MODE, &status) else { ... } guard let network = vmnet_network_create(networkConfiguration, &status) else { ... } let attachment = VZVmnetNetworkDeviceAttachment(network: network) let networkDeviceConfiguration = VZVirtioNetworkDeviceConfiguration() networkDeviceConfiguration.attachment = attachment virtualMachineConfiguration.networkDevices = [networkDeviceConfiguration] let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration) -
14:54 - Use DiskImageKit with Virtualization
import DiskImageKit import Virtualization let baseImage = try DiskImage(opening: .open(url: baseLayerURL, mode: .readOnly)) let cacheImage = try baseImage.appending(.asifLayer(url: cacheLayerURL, type: .cache)) let overlayImage = try DiskImage(opening: .open(url: overlayLayerURL)) let stackedImage = try cacheImage.appending(overlayImage) let storageDeviceAttachment = try VZDiskImageStorageDeviceAttachment(diskImage: stackedImage) let storageDeviceConfiguration = VZVirtioBlockDeviceConfiguration(attachment: storageDeviceAttachment) virtualMachineConfiguration.storageDevices = [storageDeviceConfiguration] let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration) -
17:41 - Configure a custom Virtio device
import Virtualization let deviceConfiguration = VZCustomVirtioDeviceConfiguration() // Virtio entropy device. deviceConfiguration.deviceID = 4 // PCI class for crypto devices. deviceConfiguration.pciClassID = 0x10 // PCI subclass for network and computing encryption controllers. deviceConfiguration.pciSubclassID = 0x00 // An entropy device uses a single Virtio queue. deviceConfiguration.virtioQueueCount = 1 deviceConfiguration.provider = VZCustomVirtioDeviceDelegateProvider(deviceQueue: deviceQueue, delegate: provider) virtualMachineConfiguration.customVirtioDevices = [deviceConfiguration] let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration) -
18:20 - Attach a delegate to a VZCustomVirtioDevice
import Virtualization class DeviceConfigurationDelegate: NSObject, VZCustomVirtioDeviceConfigurationDelegate { func customVirtioConfiguration(_ deviceConfiguration: VZCustomVirtioDeviceConfiguration, didCreateDevice device: VZCustomVirtioDevice) { device.delegate = deviceDelegate self.device = device } } -
18:42 - Process Virtio queue elements
import Virtualization class DeviceDelegate: NSObject, VZCustomVirtioDeviceDelegate { func customVirtioDevice(_ device: VZCustomVirtioDevice, didReceiveNotificationFor queue: VZVirtioQueue) { while let element = queue.nextElement() { // Process element... element.returnToQueue() } } }
-
-
- 0:01 - Introduction
The advanced Virtualization capabilities ahead — automating Virtual Mac setup, attaching USB devices with the Accessory Access framework, configuring advanced networking, creating disk images with DiskImageKit, and building custom Virtio devices.
- 1:04 - macOS guest provisioning
Automate the provisioning of user accounts in Setup Assistant for virtual Macs. Use the VZMacGuestProvisioningOptions API to set credentials and enable features like auto-login and SSH on first boot.
- 4:34 - Accessory Access
Pass through USB accessories directly into virtual machines using the Accessory Access framework. This approach gives people explicit control over which physical devices, such as external drives, are passed through to the virtual machine.
- 8:26 - Advanced network topologies
Configure complex network topologies by integrating the vmnet framework with Virtualization. You can create custom network architectures that define exactly how multiple virtual machines interact with each other and the host.
- 11:35 - DiskImageKit
DiskImageKit is a new framework in macOS 27 designed for managing high-performance, space-efficient disk images. You can use layered disk images, including base layers, cache layers, and overlay layers, to share data efficiently across multiple virtual machines.
- 15:57 - Custom Virtio
Define and implement custom paravirtualized devices using the industry-standard Virtio protocol. By using the VZCustomVirtioDevice API, you can enable specialized, high-performance communication between the host and custom drivers running in the virtual machine.