概要
前回 GuestProcessManager を使って VM 内のプロセス制御をしてみました
同じようにファイルやディレクトリを制御できる GuestFileManager という機能があるので今回はこれを使ってみました
ProcessManager に比べて操作できる機能が多いです
環境
- Ubuntu 16.04.3
- Ruby 2.3.1p112
- gem 2.5.1
- rbvmomi 1.11.3
ファイルの一覧を表示する
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
path = "/tmp/"
files = vim.serviceContent.guestOperationsManager.fileManager.ListFilesInGuest(
vm: vm,
auth: auth,
filePath: path,
matchPattern: "^hoge$"
)
files.props[:files].each { |file|
puts file.props[:path]
puts file.props[:type]
puts file.props[:size]
puts file.props[:attributes].props[:modificationTime]
puts file.props[:attributes].props[:accessTime]
puts file.props[:attributes].props[:ownerId]
puts file.props[:attributes].props[:groupId]
puts file.props[:attributes].props[:permissions].to_s(8)
}
ListFilesInGuest を使います
パラメータに path, index, maxResults, matchPattern を指定できます
path はファイルでもいいですしディレクトリでも OK です
ファイルの場合は 1 つだけ取得しディレクトリの場合は指定したディレクトリ配下のファイル群を取得します
index はページネート用のインデックスです
デフォルトは 0 ページ目からの取得になります
maxResults は 1 ページで取得する最大の件数になります
デフォルトは 50 です
例えば取得件数が 100 ファイルある場合に 51 件目以降を取得する場合は index を 1 にしてそこから 50 件取得するか index を 0 のままで maxResults を 100 にするかになります
matchPattern は正規表現に合致したファイル群を取得するパラメータです
上記のサンプルのように指定した場合は hoge にマッチするファイルだけを取得します
これを ^hoge
というふうにすると先頭が hoge というファイルにマッチするので hoge2 や hogefuga というファイルも検索結果に含まれます
使用できる正規表現は Perl の正規表現になります
検索結果は GuestListFileInfo というクラスのオブジェクトが返ってきます
この中のプロパティ :files にというものがあり、その中に各ファイルの情報を管理する GuestFileInfo という配列があります
あとは each とハッシュを使って必要な情報を取得するだけですがその中にファイルの権限を取得できる permissions があります
これがデフォルトだと 10 進数表記になっているのでわかりやすいように 8 進数表記に変換してあげると良いと思います
ファイルの属性情報を変更する
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
path = "/tmp/hoge"
attr = RbVmomi::VIM::GuestPosixFileAttributes(
permissions: 33279
)
vim.serviceContent.guestOperationsManager.fileManager.ChangeFileAttributesInGuest(
vm: vm,
auth: auth,
guestFilePath: path,
fileAttributes: attr
)
ChangeFileAttributesInGuest を使います
guestFilePath で指定したファイルの属性情報を変更します
今回 Ubuntu VM 内のファイルの属性情報を変更するので GuestPosixFileAttributes を使用します
パラメータにはファイルの管理者情報とパーミッションを指定できます
上記のサンプルでは権限を変更しています
権限の指定方法は 10 進数で指定する必要があるので注意してください
返り値が void なので結果を確認したい場合は ListFilesInGuest を実行してファイルの内容を確認してください
テンポラリのディレクトリを作成する
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
path = "/tmp"
ret = vim.serviceContent.guestOperationsManager.fileManager.CreateTemporaryDirectoryInGuest(
vm: vm,
auth: auth,
prefix: "prefix-",
suffix: "-suffix",
directoryPath: path
)
puts ret
CreateTemporaryDirectoryInGuest を使います
パラメータにはディレクトリを作成するパス (directoryPath) と作成するディレクトリの prefix と suffix をオプションで指定することができます
作成されるディレクトリ名は vmware000 という形式で作成されます
000 の部分はランダムの数字が入ります
その前後に prefix と suffix で指定した文字列が付与されます
返り値は作成されたディレクトリのフルパス情報が String で返却されます
テンポラリのファイルを作成する
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
path = "/tmp"
ret = vim.serviceContent.guestOperationsManager.fileManager.CreateTemporaryFileInGuest(
vm: vm,
auth: auth,
prefix: "prefix-",
suffix: "-suffix",
directoryPath: path
)
puts ret
CreateTemporaryFileInGuest を使います
挙動やパラメータは前述の CreateTemporaryDirectoryInGuest とほぼ同じです
ディレクトリを作成するかファイルを作成するかの違いになります
ンポラリファイルの権限は 600 で作成されるようです
ディレクトリの削除をする
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
path = "/tmp/prefix-vmware130-suffix"
vim.serviceContent.guestOperationsManager.fileManager.DeleteDirectoryInGuest(
vm: vm,
auth: auth,
directoryPath: path,
recursive: true
)
DeleteDirectoryInGuest を使います
パラメータは削除対象のディレクトリと再帰的に削除するかのフラグを渡します
recursive が false の場合に削除対象のディレクトリ配下に更にディレクトリがあるとエラーとなります
返り値は void になります
ファイルの削除をする
require 'rbvmomi'
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
path = "/tmp/prefix-vmware136-suffix"
vim.serviceContent.guestOperationsManager.fileManager.DeleteFileInGuest(
vm: vm,
auth: auth,
filePath: path
)
DeleteFileInGuest を使います
先程はディレクトリを削除しましたがこれはファイルを削除します
ディレクトリを指定した場合やファイルが存在しない場合にはエラーとなります
返り値は void です
ディレクトリを作成する
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
path = "/tmp/fuga/hoge"
vim.serviceContent.guestOperationsManager.fileManager.MakeDirectoryInGuest(
vm: vm,
auth: auth,
directoryPath: path,
createParentDirectories: true
)
MakeDirectoryInGuest を使います
CreateTemporaryDirectoryInGuest とほぼ同じですがこちらの場合は作成するディレクトリ名に規則はありません
createParentDirectories は mkdir でいうところの -p
オプションで上位のディレクトリがなかった場合に作成してくれます
ただ CreateTemporaryDirectoryInGuest とは違いなぜか返り値は void になっています
そして MakeFileInGuest はありません
ディレクトリを移動する
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
src = "/tmp/fuga/hoge2"
dst = "/tmp/fuga/hoge"
vim.serviceContent.guestOperationsManager.fileManager.MoveDirectoryInGuest(
vm: vm,
auth: auth,
srcDirectoryPath: src,
dstDirectoryPath: dst
)
MoveDirectoryInGuest を使います
src にあるディレクトリを dst に移動します
dst 側にすでにディレクトリがある場合はエラーになります
返り値は void になります
ファイルを移動する
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
src = "/tmp/fuga/file1"
dst = "/tmp/fuga/file2"
vim.serviceContent.guestOperationsManager.fileManager.MoveFileInGuest(
vm: vm,
auth: auth,
srcFilePath: src,
dstFilePath: dst,
overwrite: false
)
MoveFileInGuest を使います
移動前と移動後のファイルパスを指定します
移動前のファイルが存在しない場合はエラーになります
また移動後のファイル名がすでに存在する場合に上書きするオプションがあります
true で上書きします、false を指定した場合に移動後のファイル名がすでにある場合はエラーとなります
ホストから ESXi にファイルを転送する
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
path = "/tmp/fuga/file1"
ret = vim.serviceContent.guestOperationsManager.fileManager.InitiateFileTransferFromGuest(
vm: vm,
auth: auth,
guestFilePath: path
)
puts ret.props[:url]
InitiateFileTransferFromGuest を使います
これは VM 上のファイルをから ESXi 上にアップロードすることができる機能になります
返り値は RbVmomi::VIM::FileTransferInformation
になります
この中に url というフィールドが含まれておりこの URL にアクセスすると ESXi 上にアップロードされたファイルを確認することができます
URL は一度しかアクセスすることができません
ESXi からホストにファイルを転送する
require 'rbvmomi'
vim = RbVmomi::VIM.connect(
host: '192.168.100.1',
user: 'vcenter-user',
password: 'vcenter-pass',
insecure: 'true'
)
dc = vim.serviceInstance.find_datacenter('datacenter') || fail('datacenter not found')
vm = dc.find_vm('directory/path/to/vm') || fail('VM not found')
auth = RbVmomi::VIM::NamePasswordAuthentication(
interactiveSession: false,
username: "root",
password: "password"
)
path = "/tmp/fuga/file1"
attr = RbVmomi::VIM::GuestPosixFileAttributes(
permissions: 33188
)
ret = vim.serviceContent.guestOperationsManager.fileManager.InitiateFileTransferToGuest(
vm: vm,
auth: auth,
guestFilePath: path,
fileAttributes: attr,
fileSize: 26,
overwrite: true
)
puts ret
InitiateFileTransferToGuest を使います
ローカルにあるファイルにアクセスするために ESXi 経由で取得できるURL を取得することができます
URL には一度しかアクセスできません
最後に
GuestFileManager を使って VM 内のファイルやディレクトリの操作をしてみました
GuesetProcessManager に比べいろいろな処理ができる印象です
ただ、相変わらず返り値は void が多いので確認には工夫が必要です
今回も認証はユーザ名/パスワードにしました
SSPI or Ticketed でも頑張れば認証する方法があるかもしれません