fbpx

CL LAB

HOME > CL LAB > softlayer > softlayer-api-ruby-client で Portable Storage (SAN) を追加する #softlayer

softlayer-api-ruby-client で Portable Storage (SAN) を追加する #softlayer

 ★ 0

Portable Storage (SAN) とは

SoftLayer のストレージにはさまざまな種類がありますが、本記事では Portable Storage を取り扱います。
以前の記事 で軽く触れましたが、Portable Storage は複数のサーバで使い回し可能なストレージです。現状では Portable Storage として SAN が利用可能です。

softlayer-api-ruby-client で Portable Storage (SAN) を注文するには

もちろん Portable Storage (SAN) も softlayer-api-ruby-client を用いて注文が可能です。注文には 先の記事 のように SoftLayer_Product_Order::placeOrder を用います。
さて、Virtual Server の注文にはマジックナンバーとして 46 が必要でした。Portable Storage を表すマジックナンバーは何でしょうか。まずはそれを調べなくてはいけません。

注文のための Package ID を調べる

Virtual Server や Portable Storage は Package という分類になっています。そしてこのマジックナンバーは Package ID と呼称されています。
Package ID を取得するには SoftLayer_Product_Package サービスの SoftLayer_Product_Package::getAllObjects を用います。
次のプログラムを見てください。

#!/usr/bin/ruby

require 'softlayer_api'
require 'pp'

#
# fill your SoftLayer API username and API key
#
api_username = ENV['SOFTLAYER_API_USERNAME'] || 'YOUR_SOFTLAYER_API_USERNAME'
api_key      = ENV['SOFTLAYER_API_KEY']      || 'YOUR_SOFTLAYER_API_KEY'

#
# http://sldn.softlayer.com/reference/services/SoftLayer_Product_Package
#
product_package_service = SoftLayer::Service.new( 'SoftLayer_Product_Package',
  :username => api_username,
  :api_key  => api_key,
)

#
# result
#
pp product_package_service.getAllObjects

__END__

これを実行すると次の結果が得られます。

    :
    (中略)
    :
 {"description"=>
   "<div class="PageTopicSubHead">Cloud Compute Instances</div>",
  "firstOrderStepId"=>1,
  "id"=>46,
  "isActive"=>1,
  "name"=>"Cloud Server",
  "unitSize"=>1},
    :
    (中略)
    :
 {"firstOrderStepId"=>1,
  "id"=>198,
  "isActive"=>1,
  "name"=>"Portable Storage",
  "unitSize"=>1},
    :
    (中略)
    :

このように、Portable Storage の Package ID は 198 であることがわかりました。また、Virtual Server (旧名:Cloud Compute Instances) の Package ID が 46 であることもこれからわかります。

注文のための Price ID を調べる

Portable Storage の Package ID がわかったら、次は実際に注文するための Price ID が必要になります。Portable Storage の場合、どれだけの容量を持った SAN を注文するか、ということになります。
先の記事と同じように、Virtual Guest Ordering にあるプログラムを Portable Storage に合わせて変更して取得します。

#!/usr/bin/ruby

require 'softlayer_api'
require 'pp'

#
# fill your SoftLayer API username and API key
#
api_username = ENV['SOFTLAYER_API_USERNAME'] || 'YOUR_SOFTLAYER_API_USERNAME'
api_key      = ENV['SOFTLAYER_API_KEY']      || 'YOUR_SOFTLAYER_API_KEY'

softlayer_product_package = SoftLayer::Service.new("SoftLayer_Product_Package",
  :username => api_username,
  :api_key  => api_key,
)

portable_storage_package = softlayer_product_package.object_with_id( 198 )

portable_storage_configuration = portable_storage_package.object_mask("isRequired","itemCategory").getConfiguration()

#
# http://sldn.softlayer.com/reference/datatypes/SoftLayer_Product_Package_Order_Configuration
#
item_prices = portable_storage_package.object_mask("id", "item.description", "categories.id").getItemPrices()

portable_storage_configuration.each do |configuration_entry|
  if configuration_entry['isRequired'] == 1
    print 'Required '
  else
    print 'Optional '
  end

  puts "Category "#{configuration_entry['itemCategory']['name']}" -- #{configuration_entry['itemCategory']['id']}:"
  category_prices = item_prices.map do |item|
    item["categories"].map do |category|
      item if category["id"] == configuration_entry["itemCategory"]["id"]
    end if item.include?("categories")
  end.flatten.compact
  category_prices.each do |category_price|
    puts "\t #{category_price['id']} -- #{category_price['item']['description']}"
  end
end

__END__

これを実行すると次の結果が得られます。

Required Category "Second Disk" -- 82:
     2264 -- 200 GB (SAN)
     2259 -- 50 GB (SAN)
     2272 -- 250 GB (SAN)
     2279 -- 1,000 GB (SAN)
     2266 -- 350 GB (SAN)
     2278 -- 750 GB (SAN)
     2257 -- 30 GB (SAN)
     2265 -- 300 GB (SAN)
     2281 -- 2,000 GB (SAN)
     2258 -- 40 GB (SAN)
     2260 -- 75 GB (SAN)
     2270 -- 500 GB (SAN)
     21861 -- 25 GB (SAN)
     2256 -- 20 GB (SAN)
     2261 -- 125 GB (SAN)
     2280 -- 1,500 GB (SAN)
     2262 -- 150 GB (SAN)
     2255 -- 10 GB (SAN)
     2263 -- 175 GB (SAN)
     2267 -- 400 GB (SAN)
     2277 -- 100 GB (SAN)

これで Portable Storage (SAN) を注文するために必要なマジックナンバーは揃いました。

softlayer-api-ruby-client で Portable Storage (SAN) の注文内容を検証する

Portable Storage の注文内容は SoftLayer_Container_Product_Order_Virtual_Disk_Image データタイプで構成されています。
次のような形になるでしょう。diskDescription には何か適当な説明文を入力しておきます。

product_order = {
  'complexType' => 'SoftLayer_Container_Product_Order_Virtual_Disk_Image',
  'quantity' => 1,
  'location' => 168642, # NOTE: 168642 is 'sjc01' location ID
  'packageId' => 198,   # NOTE: 198 is 'Portable Storage' package ID
  'useHourlyPricing' => false,
  'diskDescription' => 'Portable Storage 10GB SAN', # Required
  'prices' => [
    { 'id' => 2255 }, # 10 GB (SAN)
  ]
}

先の記事と同様に、SoftLayer_Product_Order::verifyOrder で注文内容を検証しましょう。

#!/usr/bin/ruby

require 'softlayer_api'
require 'pp'

#
# fill your SoftLayer API username and API key
#
api_username = ENV['SOFTLAYER_API_USERNAME'] || 'YOUR_SOFTLAYER_API_USERNAME'
api_key      = ENV['SOFTLAYER_API_KEY']      || 'YOUR_SOFTLAYER_API_KEY'

#
# https://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Virtual_Disk_Image
#
product_order = {
  'complexType' => 'SoftLayer_Container_Product_Order_Virtual_Disk_Image',
  'quantity' => 1,
  'location' => 168642, # NOTE: 168642 is 'sjc01' location ID
  'packageId' => 198,   # NOTE: 198 is 'Portable Storage' package ID
  'useHourlyPricing' => false,
  'diskDescription' => 'Portable Storage 10GB SAN', # Required
  'prices' => [
    { 'id' => 2255 }, # 10 GB (SAN)
  ]
}

#
# http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order
#
product_order_service = SoftLayer::Service.new( 'SoftLayer_Product_Order',
  :username => api_username,
  :api_key  => api_key,
)

#
# http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order/verifyOrder
#
begin
  result = product_order_service.verifyOrder( product_order )
  pp result
  puts "The order was verified successfully"
rescue => error_reason
  puts "The order could not be verified by the server: #{error_reason}"
  exit
end

exit

__END__

これを実行すると次の結果が得られます。
注文内容が問題ないことがわかります。

{"bigDataOrderFlag"=>false,
 "billingOrderItemId"=>nil,
 "containerSplHash"=>"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
 "currencyShortName"=>"USD",
 "extendedHardwareTesting"=>nil,
 "imageTemplateId"=>nil,
 "isManagedOrder"=>0,
 "location"=>"168642",
 "locationObject"=>
  {"id"=>168642,
   "longName"=>"San Jose 1",
   "name"=>"sjc01",
   "activePresaleEvents"=>[]},
 "packageId"=>198,
 "postTaxRecurring"=>"4.57",
 "postTaxRecurringHourly"=>"0",
 "postTaxRecurringMonthly"=>"4.57",
 "postTaxSetup"=>"0",
 "preTaxRecurring"=>"4.57",
 "preTaxRecurringHourly"=>"0",
 "preTaxRecurringMonthly"=>"4.57",
 "preTaxSetup"=>"0",
 "presetId"=>nil,
 "prices"=>
  [{"currentPriceFlag"=>nil,
    "hourlyRecurringFee"=>".007",
    "id"=>2255,
    "itemId"=>1213,
    "laborFee"=>"0",
    "onSaleFlag"=>nil,
    "oneTimeFee"=>"0",
    "oneTimeFeeTax"=>"0",
    "proratedRecurringFee"=>"3.8083333333333",
    "proratedRecurringFeeTax"=>"0",
    "quantity"=>nil,
    "recurringFee"=>"4.57",
    "recurringFeeTax"=>"0",
    "setupFee"=>"0",
    "sort"=>0,
    "categories"=>
     [{"categoryCode"=>"guest_disk1",
       "id"=>82,
       "name"=>"Second Disk",
       "quantityLimit"=>0},
      {"categoryCode"=>"guest_disk2",
       "id"=>92,
       "name"=>"Third Disk",
       "quantityLimit"=>0},
      {"categoryCode"=>"guest_disk3",
       "id"=>93,
       "name"=>"Fourth Disk",
       "quantityLimit"=>0},
      {"categoryCode"=>"guest_disk4",
       "id"=>116,
       "name"=>"Fifth Disk",
       "quantityLimit"=>0}],
    "item"=>
     {"capacity"=>"10",
      "description"=>"10 GB (SAN)",
      "id"=>1213,
      "softwareDescriptionId"=>nil,
      "units"=>"GB",
      "upgradeItemId"=>nil,
      "bundle"=>[]}}],
 "primaryDiskPartitionId"=>nil,
 "privateCloudOrderFlag"=>false,
 "proratedInitialCharge"=>"3.81",
 "proratedOrderTotal"=>"3.81",
 "quantity"=>1,
 "resourceGroupId"=>nil,
 "resourceGroupTemplateId"=>nil,
 "sendQuoteEmailFlag"=>nil,
 "serverCoreCount"=>nil,
 "sourceVirtualGuestId"=>nil,
 "sshKeys"=>[],
 "stepId"=>nil,
 "storageGroups"=>[],
 "totalRecurringTax"=>"0",
 "totalSetupTax"=>"0",
 "useHourlyPricing"=>false,
 "diskDescription"=>"Portable Storage 10GB SAN"}
The order was verified successfully

softlayer-api-ruby-client で Portable Storage (SAN) を注文する

では、検証した注文内容を実際に注文してみましょう。
次のプログラムになります。

#!/usr/bin/ruby

require 'softlayer_api'
require 'pp'

#
# fill your SoftLayer API username and API key
#
api_username = ENV['SOFTLAYER_API_USERNAME'] || 'YOUR_SOFTLAYER_API_USERNAME'
api_key      = ENV['SOFTLAYER_API_KEY']      || 'YOUR_SOFTLAYER_API_KEY'

#
# https://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Virtual_Disk_Image
#
product_order = {
  'complexType' => 'SoftLayer_Container_Product_Order_Virtual_Disk_Image',
  'quantity' => 1,
  'location' => 168642, # NOTE: 168642 is 'sjc01' location ID
  'packageId' => 198,   # NOTE: 198 is 'Portable Storage' package ID
  'useHourlyPricing' => false,
  'diskDescription' => 'Portable Storage 10GB SAN', # Required
  'prices' => [
    { 'id' => 2255 }, # 10 GB (SAN)
  ]
}

#
# http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order
#
product_order_service = SoftLayer::Service.new( 'SoftLayer_Product_Order',
  :username => api_username,
  :api_key  => api_key,
)

#
# http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order/verifyOrder
#
begin
  result = product_order_service.verifyOrder( product_order )
  puts "The order was verified successfully"
rescue => error_reason
  puts "The order could not be verified by the server: #{error_reason}"
  exit
end

#
# http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order/placeOrder
#
begin
  result = product_order_service.placeOrder( product_order )
  puts "The order was placed successfully"
  pp result
rescue => error_reason
  puts "The order could not be placed by the server: #{error_reason}"
  exit
end

__END__

これを実行すると次の結果が得られます。

The order was verified successfully
The order was placed successfully
{"orderDate"=>"2014-06-03T16:11:41+09:00",
 "orderDetails"=>
  {"bigDataOrderFlag"=>false,
    :
    (中略)
    :
   "billingOrderItemId"=>nil,
   "containerSplHash"=>"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
   "currencyShortName"=>"USD",
   "extendedHardwareTesting"=>nil,
   "imageTemplateId"=>nil,
   "isManagedOrder"=>0,
   "itemCategoryQuestionAnswers"=>[],
   "location"=>"168642",
   "locationObject"=>
    {"id"=>168642,
     "longName"=>"San Jose 1",
     "name"=>"sjc01",
     "activePresaleEvents"=>[]},
   "packageId"=>198,
   "paymentType"=>"CARD_ON_FILE",
   "postTaxRecurring"=>"4.57",
   "postTaxRecurringHourly"=>"0",
   "postTaxRecurringMonthly"=>"4.57",
   "postTaxSetup"=>"0",
   "preTaxRecurring"=>"4.57",
   "preTaxRecurringHourly"=>"0",
   "preTaxRecurringMonthly"=>"4.57",
   "preTaxSetup"=>"0",
   "presetId"=>nil,
   "prices"=>
    [{"currentPriceFlag"=>nil,
      "hourlyRecurringFee"=>".007",
      "id"=>2255,
      "itemId"=>1213,
      "laborFee"=>"0",
      "onSaleFlag"=>nil,
      "oneTimeFee"=>"0",
      "oneTimeFeeTax"=>"0",
      "proratedRecurringFee"=>"3.656",
      "proratedRecurringFeeTax"=>"0",
      "quantity"=>nil,
      "recurringFee"=>"4.57",
      "recurringFeeTax"=>"0",
      "setupFee"=>"0",
      "sort"=>0,
      "categories"=>
       [{"categoryCode"=>"guest_disk1",
         "id"=>82,
         "name"=>"Second Disk",
         "quantityLimit"=>0},
        {"categoryCode"=>"guest_disk2",
         "id"=>92,
         "name"=>"Third Disk",
         "quantityLimit"=>0},
        {"categoryCode"=>"guest_disk3",
         "id"=>93,
         "name"=>"Fourth Disk",
         "quantityLimit"=>0},
        {"categoryCode"=>"guest_disk4",
         "id"=>116,
         "name"=>"Fifth Disk",
         "quantityLimit"=>0}],
      "item"=>
       {"capacity"=>"10",
        "description"=>"10 GB (SAN)",
        "id"=>1213,
        "softwareDescriptionId"=>nil,
        "units"=>"GB",
        "upgradeItemId"=>nil,
        "bundle"=>[]}}],
   "primaryDiskPartitionId"=>nil,
   "privateCloudOrderFlag"=>false,
   "properties"=>[],
   "proratedInitialCharge"=>"3.66",
   "proratedOrderTotal"=>"3.66",
   "quantity"=>1,
   "resourceGroupId"=>nil,
   "resourceGroupTemplateId"=>nil,
   "sendQuoteEmailFlag"=>nil,
   "serverCoreCount"=>nil,
   "sourceVirtualGuestId"=>nil,
   "sshKeys"=>[],
   "stepId"=>nil,
   "storageGroups"=>[],
   "totalRecurringTax"=>"0",
   "totalSetupTax"=>"0",
   "useHourlyPricing"=>false,
   "diskDescription"=>"Portable Storage 10GB SAN"},
 "orderId"=>XXXXX46,
 "placedOrder"=>
  {"accountId"=>XXXX78,
   "createDate"=>"2014-06-03T16:11:40+09:00",
   "id"=>XXXXX46,
   "impersonatingUserRecordId"=>nil,
   "modifyDate"=>nil,
   "orderQuoteId"=>nil,
   "orderTypeId"=>4,
   "presaleEventId"=>nil,
   "privateCloudOrderFlag"=>false,
   "status"=>"PENDING_AUTO_APPROVAL",
   "userRecordId"=>XXXX42,
   "account"=>
    :
    (中略)
    :
   "items"=>
    [{"categoryCode"=>"guest_disk1",
      "description"=>"10 GB (SAN)",
      "id"=>XXXXXX38,
      "itemId"=>1213,
      "itemPriceId"=>"2255",
      "laborFee"=>"0",
      "laborFeeTaxRate"=>"0",
      "oneTimeFee"=>"0",
      "oneTimeFeeTaxRate"=>"0",
      "parentId"=>nil,
      "promoCodeId"=>nil,
      "quantity"=>nil,
      "recurringFee"=>"4.57",
      "setupFee"=>"0",
      "setupFeeDeferralMonths"=>12,
      "setupFeeTaxRate"=>"0",
      "bundledItems"=>[],
      "category"=>
       {"categoryCode"=>"guest_disk1",
        "id"=>82,
        "name"=>"Second Disk",
        "quantityLimit"=>0},
      "children"=>[],
      "location"=>{"id"=>168642, "longName"=>"San Jose 1", "name"=>"sjc01"},
      "order"=>nil,
      "storageGroups"=>[]}],
   "orderTopLevelItems"=>
    [{"categoryCode"=>"guest_disk1",
      "description"=>"10 GB (SAN)",
      "id"=>XXXXXX38,
      "itemId"=>1213,
      "itemPriceId"=>"2255",
      "laborFee"=>"0",
      "laborFeeTaxRate"=>"0",
      "oneTimeFee"=>"0",
      "oneTimeFeeTaxRate"=>"0",
      "parentId"=>nil,
      "promoCodeId"=>nil,
      "quantity"=>nil,
      "recurringFee"=>"4.57",
      "setupFee"=>"0",
      "setupFeeDeferralMonths"=>12,
      "setupFeeTaxRate"=>"0",
      "bundledItems"=>[],
      "category"=>
       {"categoryCode"=>"guest_disk1",
        "id"=>82,
        "name"=>"Second Disk",
        "quantityLimit"=>0},
      "children"=>[],
      "location"=>{"id"=>168642, "longName"=>"San Jose 1", "name"=>"sjc01"},
      "order"=>nil,
      "storageGroups"=>[]}],
    :
    (中略)
    :

このように Portable Storage 10GB SAN が注文できました。

softlayer-api-ruby-client で Portable Storage (SAN) を確認する

ポータルの Portable Storage から確認することもできますが、softlayer-api-ruby-client からも確認してみましょう。
SoftLayer_Account サービスの SoftLayer_Account::getPortableStorageVolumes で Portable Storage の一覧が確認できます。

#!/usr/bin/ruby

require 'softlayer_api'
require 'pp'

#
# fill your SoftLayer API username and API key
#
api_username = ENV['SOFTLAYER_API_USERNAME'] || 'YOUR_SOFTLAYER_API_USERNAME'
api_key      = ENV['SOFTLAYER_API_KEY']      || 'YOUR_SOFTLAYER_API_KEY'

#
# http://sldn.softlayer.com/reference/services/SoftLayer_Account
#
account_service = SoftLayer::Service.new( 'SoftLayer_Account',
  :username => api_username,
  :api_key  => api_key,
)

#
# result
#
pp account_service.getPortableStorageVolumes

__END__

このプログラムを実行すると、次のように先に注文した Portable Storage の内容が取得できます。

[{"capacity"=>10,
  "createDate"=>"2014-06-03T16:11:48+09:00",
  "description"=>"Portable Storage 10GB SAN",
  "id"=>XXXXX50,
  "modifyDate"=>"2014-06-03T16:11:52+09:00",
  "name"=>"Portable Storage 10GB SAN",
  "parentId"=>nil,
  "storageRepositoryId"=>XXXXXX60,
  "typeId"=>241,
  "units"=>"GB",
  "uuid"=>"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"}]

softlayer-api-ruby-client で Portable Storage (SAN) を Virtual Server にアタッチする

では、この Portable Storage を Virtual Server にアタッチしてみましょう。SoftLayer_Virtual_Guest::attachDiskImage を使います。
次のプログラムの VIRTUAL_GUEST_ID はアタッチ先の Virtual Server の ID、PORTABLE_STORAGE_ID は今確認した Portable Storage の id に置き換えてください。
なお、このプログラムを実行する際は Virtual Server を停止してから行ってください。さもないと、実行した直後に Virtual Server は自動的に再起動します。

#!/usr/bin/ruby

require 'softlayer_api'
require 'pp'

#
# fill your SoftLayer API username and API key
#
api_username = ENV['SOFTLAYER_API_USERNAME'] || 'YOUR_SOFTLAYER_API_USERNAME'
api_key      = ENV['SOFTLAYER_API_KEY']      || 'YOUR_SOFTLAYER_API_KEY'

#
# fill your SoftLayer Virtual Guest ID and Portable Storage ID
#
VIRTUAL_GUEST_ID=0
PORTABLE_STORAGE_ID=0

#
# http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest
#
virtual_guest_service = SoftLayer::Service.new( 'SoftLayer_Virtual_Guest',
  :username => api_username,
  :api_key  => api_key,
)

#
# result
#
pp virtual_guest_service.object_with_id( VIRTUAL_GUEST_ID ).attachDiskImage( PORTABLE_STORAGE_ID )

__END__

これを実行すると次の結果が得られます。

{"createDate"=>"2014-06-03T17:19:02+09:00",
 "elapsedSeconds"=>0,
 "guestId"=>XXXXX64,
 "hardwareId"=>nil,
 "id"=>XXXXX40,
 "modifyDate"=>"2014-06-03T17:19:02+09:00",
 "statusChangeDate"=>"2014-06-03T17:19:02+09:00",
 "transactionGroup"=>
  {"averageTimeToComplete"=>"1.38", "name"=>"Cloud Disk Image Attach"},
 "transactionStatus"=>
  {"friendlyName"=>"Cloud Disk Image Attach",
   "name"=>"CLOUD_DISK_IMAGE_ATTACH"}}

softlayer-api-ruby-client で Virtual Server を作成・閲覧・破棄する」で用いた Virtual Server の閲覧プログラムを実行してみましょう。

    :
    (中略)
    :
 "blockDevices"=>
  [{"bootableFlag"=>1,
    "createDate"=>"2014-05-16T14:43:42+09:00",
    "device"=>"0",
    "diskImageId"=>XXXXX26,
    "guestId"=>XXXXX64,
    "hotPlugFlag"=>0,
    "id"=>XXXXX54,
    "modifyDate"=>nil,
    "mountMode"=>"RW",
    "mountType"=>"Disk",
    "statusId"=>1,
    "uuid"=>"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"},
   {"bootableFlag"=>0,
    "createDate"=>"2014-05-16T14:42:58+09:00",
    "device"=>"1",
    "diskImageId"=>XXXXX28,
    "guestId"=>XXXXX64,
    "hotPlugFlag"=>0,
    "id"=>XXXXX52,
    "modifyDate"=>nil,
    "mountMode"=>"RW",
    "mountType"=>"Disk",
    "statusId"=>1,
    "uuid"=>"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"},
   {"bootableFlag"=>0,
    "createDate"=>"2014-06-03T17:19:37+09:00",
    "device"=>"2",
    "diskImageId"=>XXXXX50,
    "guestId"=>XXXXX64,
    "hotPlugFlag"=>0,
    "id"=>XXXXX42,
    "modifyDate"=>nil,
    "mountMode"=>"RW",
    "mountType"=>"Disk",
    "statusId"=>1,
    "uuid"=>"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"}],
    :
    (中略)
    :

Portable Storage ID を持ったブロックデバイスが1つ増えていることがわかります。
次に、Virtual Server を起動して /var/log/dmesg.0 と /var/log/dmesg の差分を取ってみましょう。

@@ -171,14 +172,14 @@
   tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
   PPP generic driver version 2.4.2
   Initialising Xen virtual ethernet driver.
-  blkfront: xvda: barrier: enabled
+  blkfront: xvdc: barrier: enabled
+  xvdc: unknown partition table
   ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
   ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
   uhci_hcd: USB Universal Host Controller Interface driver
   usbcore: registered new interface driver libusual
   i8042: PNP: No PS/2 controller found. Probing ports directly.
   i8042: No controller found
-  xvda: xvda1 xvda2
   mousedev: PS/2 mouse device common for all mice
   rtc_cmos rtc_cmos: rtc core: registered rtc_cmos as rtc0
   rtc_cmos: probe of rtc_cmos failed with error -38

xvdc が増えていることがわかります。fdisk で確認してみましょう。

root@test-20140516144201:~# fdisk -l /dev/xvdc

Disk /dev/xvdc: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/xvdc doesn't contain a valid partition table
root@test-20140516144201:~#

アタッチした Portable Storage の 10GB SAN のようです。
パーティショニングとファイルシステム構築を行ってみましょう。

root@test-20140516144201:~# fdisk /dev/xvdc

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-20971519, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-20971519, default 20971519):
Using default value 20971519

Command (m for help): p

Disk /dev/xvdc: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x8a3165e5

    Device Boot      Start         End      Blocks   Id  System
/dev/xvdc1            2048    20971519    10484736   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
root@test-20140516144201:~#
root@test-20140516144201:~# mkfs.ext4 /dev/xvdc1
mke2fs 1.42 (29-Nov-2011)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
655360 inodes, 2621184 blocks
131059 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2684354560
80 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

root@test-20140516144201:~#

マウントしてみましょう。

root@test-20140516144201:~# mount /dev/xvdc1 /mnt
root@test-20140516144201:~# ls -l /mnt/
total 16
drwx------ 2 root root 16384 Jun  3 03:44 lost+found
root@test-20140516144201:~# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvdc1      9.9G  151M  9.2G   2% /mnt
root@test-20140516144201:~#

これで Virtual Server から Portable Storage が利用できます。
なお、永続マウントする際は /etc/fstab の編集などを忘れないでください。

softlayer-api-ruby-client で Portable Storage (SAN) を Virtual Server からデタッチする

Portable Storage を別の Virtual Server で使い回すには、デタッチする必要があります。また、Virtual Server をキャンセルする際にアタッチしたままだと Portable Storage も一緒に消えてしまうので、デタッチを忘れないようにしましょう。デタッチは SoftLayer_Virtual_Guest::detachDiskImage で行います。
次のプログラムの VIRTUAL_GUEST_ID はアタッチ先の Virtual Server の ID、PORTABLE_STORAGE_ID は今確認した Portable Storage の id に置き換えてください。
なお、このプログラムを実行する際は Virtual Server を停止してから行ってください。さもないと、実行した直後に Virtual Server は自動的に再起動します。

#!/usr/bin/ruby

require 'softlayer_api'
require 'pp'

#
# fill your SoftLayer API username and API key
#
api_username = ENV['SOFTLAYER_API_USERNAME'] || 'YOUR_SOFTLAYER_API_USERNAME'
api_key      = ENV['SOFTLAYER_API_KEY']      || 'YOUR_SOFTLAYER_API_KEY'

#
# fill your SoftLayer Virtual Guest ID and Portable Storage ID
#
VIRTUAL_GUEST_ID=0
PORTABLE_STORAGE_ID=0

#
# http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest
#
virtual_guest_service = SoftLayer::Service.new( 'SoftLayer_Virtual_Guest',
  :username => api_username,
  :api_key  => api_key,
)

#
# result
#
pp virtual_guest_service.object_with_id( VIRTUAL_GUEST_ID ).detachDiskImage( PORTABLE_STORAGE_ID )

__END__
{"createDate"=>"2014-06-03T17:53:20+09:00",
 "elapsedSeconds"=>0,
 "guestId"=>XXXXX64,
 "hardwareId"=>nil,
 "id"=>XXXXX80,
 "modifyDate"=>"2014-06-03T17:53:20+09:00",
 "statusChangeDate"=>"2014-06-03T17:53:20+09:00",
 "transactionGroup"=>
  {"averageTimeToComplete"=>".85", "name"=>"Cloud Disk Image Detach"},
 "transactionStatus"=>
  {"friendlyName"=>"Cloud Disk Image Detach",
   "name"=>"CLOUD_DISK_IMAGE_DETACH"}}

softlayer-api-ruby-client で Virtual Server を作成・閲覧・破棄する」で用いた Virtual Server の閲覧プログラムを実行してみましょう。

    :
    (中略)
    :
 "blockDevices"=>
  [{"bootableFlag"=>1,
    "createDate"=>"2014-05-16T14:43:42+09:00",
    "device"=>"0",
    "diskImageId"=>XXXXX26,
    "guestId"=>XXXXX64,
    "hotPlugFlag"=>0,
    "id"=>XXXXX54,
    "modifyDate"=>nil,
    "mountMode"=>"RW",
    "mountType"=>"Disk",
    "statusId"=>1,
    "uuid"=>"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"},
   {"bootableFlag"=>0,
    "createDate"=>"2014-05-16T14:42:58+09:00",
    "device"=>"1",
    "diskImageId"=>XXXXX28,
    "guestId"=>XXXXX64,
    "hotPlugFlag"=>0,
    "id"=>XXXXX52,
    "modifyDate"=>nil,
    "mountMode"=>"RW",
    "mountType"=>"Disk",
    "statusId"=>1,
    "uuid"=>"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"}],
    :
    (中略)
    :

Portable Storage ID を持ったブロックデバイスが消えています。
次に、Virtual Server を起動して fdisk で確認したところ、もう /dev/xvdc は存在していません。

root@test-20140516144201:~# fdisk -l /dev/xvdc
root@test-20140516144201:~#

まとめ

Portable Storage は、Virtual Server に後からストレージを付け足したり、Virtual Server 間で使い回しのできるストレージとして利用できます。活用してみてください。

CL LAB Mail Magazine

CL LABの情報を逃さずチェックしよう!

メールアドレスを登録すると記事が投稿されるとメールで通知します。

メールアドレス: 登録

※登録後メールに記載しているリンクをクリックして認証してください。

Related post