ご飯

すっきりしたコードを書きたい

Powershell を使って、ネットワークを設定する (2)

前回の続きです。パラメータファイル def.ps1 を引用して、サーバのネットワークを設定するスクリプトを作成します。

その前に、設定に必要なコマンドレットを整理しておきます。

 

ホスト名とワークグループ名の変更

 

ホスト名の変更は、Win32_ComputerSystemクラスの WMIオブジェクトを取得し、rename メソッドを実行します。

$s = gwmi win32_computersystem
$s.rename($param.host_name)

 

ワークグループは、Add-Computer コマンドレットを使用します。

Add-Computer -WorkgroupName $param.domain

 

設定後に再起動が必要なので、変更されたかどうかを記憶しておきます。変更ありなら restart-computer コマンドレットを実行します。

$ch = $false
$s = gwmi win32_computersystem

if($s.name -ne $param.host_name) {
  $s.rename($param.host_name)
  $ch = $true
}

if($s.domain -ne $param.domain) {
  Add-Computer -WorkgroupName $param.domain
  $ch = $true
}

if($ch -eq $true) {
  restart-computer
}

NICのポート名を変更する

 

Rename-NetAdapter コマンドレットを使用します。

foreach($r in $param.nw.rename_ifs) {
  rename-netadapter @r
}

@r という記述は、ハッシュテーブルの要素をコマンドレットのパラメータとして展開してくれるのです。foreach で $r に代入される値は、たとえば次のようなものです。

@{Name = "Ethernet0"   ; NewName = "Eth1"}

rename-netadapter @r は、次のような文に展開してくれるのです。

rename-netadapter -Name "Ethernet0" -NewName "Eth1"

素敵だと思います。ご飯は率直に Powershell を好きになりました。

 

チーミングを設定する

 

チーミングは、New-NetLbfoTeam コマンドレット、スタンバイポートの設定は、Set-NetLbfoTeamMember コマンドレットを使用します。

$lbfo1 = $param.nw.lbfo1
$lbfo2 = $param.nw.lbfo2
New-NetLbfoTeam @lbfo1
Set-NetLbfoTeamMember @lbfo2

 

ここでも @lbfo1 という記述が見られます。こういうところは楽をしたいですね。チーミングのパラメータは、このようなぐじゃぐじゃしたものです。

lbfo1 = @{
  Name = $team_name
  TeamMembers  = ("Eth1","Eth5")
  TeamingMode  = "SwitchIndependent"
  LoadBalancingAlgorithm = "Dynamic"
  Confirm = $false
}

lbfo2 = @{
  Name = "Eth5"
  AdministrativeMode = "Standby"
}

ぐじゃぐじゃしたコマンドラインのパラメータを書くなど言語道断、ぜったいにお断りです。ご飯はわがままなのです。

なお、@param.nw.lbfo1 とすることができなかったので、いったんスカラー変数に代入してから @演算子が有効となります。

 

バインディングを設定する

バインディングとは、 ネットワークのプロパティの赤枠のチェックボックスをつけるところです。

f:id:uhoo:20181109032211p:plain

 

これを Powershell でコントロールするには、Set-NetAdapterBinding コマンドレットを使用します。

foreach($r in $param.nw.ifs) {
  foreach($x in $r.bindings) {
    set-netadapterbinding -Name $r.name @x
  }
}

 

IPv4プロパティを設定する

IPv4アドレスの追加

New-NetIPAddress コマンドレットを使います。

New-NetIPAddress -IfAlias $r.name @ip

 

DNSサーバの追加

Set-DnsClientServerAddress コマンドレットを使います。

$dns = $r.dns
Set-DnsClientServerAddress $r.name @dns

 

「この接続のアドレスをDNSに登録する」 のチェックを外す

次の画面がそれにあたります。

 f:id:uhoo:20181109060226p:plain

 

$cmd = "netsh int ip set dnsservers name=`"" + $r.name + "`" source=dhcp register=none"
invoke-expression $cmd

これだけコマンドレットがありませんでした。仕方ないので冗長な netsh を使います。💢💢💢

 

「LMHOSTSの参照を有効にする」 のチェックを外す 

次の画面がそれにあたります。

f:id:uhoo:20181109060104p:plain

 

$nicClass = Get-WmiObject -list Win32_NetworkAdapterConfiguration
$nicClass.enablewins($false,$false)

 

まとめると次のようになります。

foreach($r in $param.nw.ifs) {
  if($r.ip -ne $null) {

    $ip = $r.ip
    New-NetIPAddress -IfAlias $r.name @ip

    if($r.register -eq $false) {
      $cmd = "netsh int ip set dnsservers name=`"" + $r.name + "`" source=dhcp register=none"
      invoke-expression $cmd
    }

    if($r.dns -ne $null) {
      $dns = $r.dns
      Set-DnsClientServerAddress $r.name @dns
    }
  }
}

if($param.nw.enablewins -eq $false) {
  $nicClass = Get-WmiObject -list Win32_NetworkAdapterConfiguration
  $nicClass.enablewins($false,$false)
}

次回は、メニュー画面を作成し、メニュー項目の Enterキーが押されたら、設定を実行するように書き換えてみます。

VMware に Windows Server 2012 R2 をインストールする

今回は UbuntuVMwareWindows Server 2012 R2 をインストールしてみます。まず、以下のサイトからWindows Server 2012 R2 の 180日評価版をダウンロードします。

Microsoft Evaluation Center

 

4.3GB 残り 5時間と表示されたので、ご飯は朝までやっているお店でカラオケでも歌ってきます。

 

家に帰ってきました。いつもの面々に会えてうれしかったので、つい飲みすぎてしまいました。やはり、孤独に生きていると、無性にだれかと一緒にいたくなってしまいます。ご飯の内面はたぶん優しいと思います。反面、さびしがりやで、自尊心も低く、ちょっとしたことに傷つき、いつもくじけて泣いています。この世から消えてしまいたいとさえ思うことがあります。ご飯のまわりの人たちも、人知れず悲しみを抱えているのだろうと思います。大切にしなければいけない人たちです。

 

さて、ダウンロードができたところで、VMware を起動し、Create a New Virtual Machine をクリックします。

f:id:uhoo:20181109012444p:plain

 

Use ISO image: を選択し、さきほどダウンロードした ISOファイルを指定し、Next をクリックします。

f:id:uhoo:20181109013046p:plain

 

Microsoft Windows が選択されています。そのまま Next をクリックします。

f:id:uhoo:20181109013240p:plain

 

なにも変更せずに Next をクリックします。

f:id:uhoo:20181109013658p:plain

 

60GBもあれば十分でしょう。Next をクリックします。

f:id:uhoo:20181109013845p:plain

 

Finish をクリックします。

f:id:uhoo:20181109013925p:plain

 

Close をクリックします。

f:id:uhoo:20181109014030p:plain

 

よくわからない画面が出てきましたが、OKをクリック。

f:id:uhoo:20181109014209p:plain

 

次へをクリックします。

f:id:uhoo:20181109014426p:plain

 

今すぐインストールをクリック

f:id:uhoo:20181109014604p:plain

 

Windows Server 2012 R2 Standard 評価版 (GUI 使用サーバ) を選択し次へをクリックします。

f:id:uhoo:20181109014837p:plain

 

同意しますにチェックを入れて、次へをクリックします。

f:id:uhoo:20181109014947p:plain

 

カスタムをクリック。

f:id:uhoo:20181109015036p:plain

 

パーティションは作成せずに、次へをクリック。

f:id:uhoo:20181109015229p:plain

 

インストールが始まります。

f:id:uhoo:20181109015310p:plain

 

数回再起動します。

f:id:uhoo:20181109015651p:plain

適宜パスワードを入力し、完了をクリックします。

f:id:uhoo:20181109020101p:plain

 

もうこんな時間か。寝なくては。Ctrl + Alt + Del でログオンします。

f:id:uhoo:20181109020359p:plain

パスワードを入力します。

f:id:uhoo:20181109020604p:plain

 

サインインできました。

f:id:uhoo:20181109020758p:plain

 

今日はこのへんで寝ることにします。

 

Powershell を使って、ネットワークを設定する (1)

今回の試みは、Windows Server の設定を、Powershellスクリプトで実行するというものです。サーバは複数台存在し、それぞれ異なるIPアドレスやホスト名を設定することがスクリプトのゴールです。設定する項目は、次の通りです。

 


 

 

パラメータのみを定義した def.ps1 というファイルを作成する

あらかじめ、サーバのシリアルナンバーを取得しておき、ホスト名、IPアドレスを対応付けたハッシュテーブルを作成します。def.ps1を開きつぎのように編集します。

$params = @{
  "XYZ123S2C5" = @{host_name = "hostname4" ; ipaddr1 = "192.168.1.64"; gw1 = "192.168.1.1"}
  "XYZ123S2C9" = @{host_name = "hostname3" ; ipaddr1 = "192.168.1.94"; gw1 = "192.168.1.1"}
  "XYZ123S2C6" = @{host_name = "hostname2" ; ipaddr1 = "192.168.1.84"; gw1 = "192.168.1.1"}
  "XYZ123VDED" = @{host_name = "hostname1" ; ipaddr1 = "192.168.1.74"; gw1 = "192.168.1.1"}
}

左辺がシリアルナンバー、右辺が、ホスト名とIPアドレスです。Powershell から次のように入力すると $params の内容が表示されます。

PS /home/uhoo> . ".\def.ps1"
PS /home/uhoo> $params

Name                           Value
----                           -----
XYZ123S2C9                     {host_name, gw1, ipaddr1}
XYZ123VDED                     {host_name, gw1, ipaddr1}
XYZ123S2C6                     {host_name, gw1, ipaddr1}
XYZ123S2C5                     {host_name, gw1, ipaddr1}

 

シリアルナンバーが、XYZ123S2C9 であると仮定すると、次のようにして $params の要素を取り出すことができます。

PS /home/uhoo> $params["XYZ123S2C9"]

Name                           Value
----                           -----
ipaddr1                        192.168.1.94
gw1                            192.168.1.1
host_name                      hostname3

 

自身のシリアルナンバーを取得するには、 (gwmi win32_bios).SerialNumber とします。$params[$serial].メンバ名 とすると、ぐじゃぐじゃして使いにくいので、メンバをスカラー変数に代入しておきます。

$serial    = (gwmi win32_bios).SerialNumber  # このコンピュータのシリアル№
$host_name = $params[$serial].host_name      # ホスト名
$team_name = "team_" + $host_name            # チーム名
$ipaddr1   = $params[$serial].ipaddr1        # IPv4アドレス -1
$gw1       = $params[$serial].gw1            # デフォゲ -1

 

ところで、ご飯の使用している Windows Server は、VMware なので、(gwmi win32_bios).SerialNumber とするとシリアルナンバーが VMwareの値で返されてしまいます。したがって、便宜上、一番目のパラメータを指していることにしておきます。

#$serial    = (gwmi win32_bios).SerialNumber  # コメントアウト
$serial    = "XYZ123S2C9" # 便宜上の値に変更  

 

つぎに $param というハッシュを定義して、使いやすい構成に整えます。def.ps1 に次のコードを追加します。

$param = @{

  # ホスト名
  host_name = $host_name
  domain    = "WORKGROUP"

  # ネットワークのプロパティ
  nw = @{

    # ポート名の変更
    rename_ifs = @(
       @{Name = "Ethernet0" ; NewName = "Eth1"}
       @{Name = "Ethernet1" ; NewName = "Eth5"}
     )

    # チーミングの設定
    lbfo1 = @{
      Name = $team_name
      TeamMembers  = ("Eth1","Eth5")
      TeamingMode  = "SwitchIndependent"
      LoadBalancingAlgorithm = "Dynamic"
      Confirm = $false
    }

    lbfo2 = @{
      Name = "Eth5"
      AdministrativeMode = "Standby"
    }

    # 接続の設定
    ifs = @(
      # インタフェイス-1 
      @{
        name = $team_name
     
        # バインディング (既定値を変更する ComponentID だけ追加し、enabled 属性を与えてください)
        bindings  = @(
          @{ComponentID = "ms_tcpip6"; Enabled = $false}
        )
     
        # IPv4アドレス (個別パラメータの $ipaddr1 を参照しています)
        ip = @{IPAddress = $ipaddr1; PrefixLength = 24; DefaultGateway = $gw1}
     
        # DNSサーバ
        dns = @{ServerAddress = @('192.168.0.2','192.168.0.1')}
     
        # $false を指定すると「この接続のアドレスをDNSに登録する」のチェックを外します
        register = $false
      }
    )

    # false を指定すると「LMHOSTS の参照を有効にするチェック」のを外します
    enablewins = $true

    # コンポーネントIDとその説明
    binding_dscr = @{
      ms_rspndr    = "Link-Layer Topology Discovery Responder"
      ms_lltdio    = "Link-Layer Topology Discovery Mapper I/O Driver"
      ms_implat    = "Microsoft Network Adapter Multiplexor Protocol"
      ms_msclient  = "Microsoft ネットワーク用クライアント"
      ms_netftflt  = "Microsoft Failover Cluster Virtual Adapter Performance Filter"
      ms_bridge    = "Microsoft MAC Bridge"
      ms_lbfo      = "Microsoft Load Balancing/Failover Provider"
      ms_pacer     = "QoS パケット スケジューラ"
      ms_server    = "Microsoft ネットワーク用ファイルとプリンター共有"
      ms_tcpip6    = "インターネット プロトコル バージョン 6 (TCP/IPv6)"
      ms_tcpip     = "インターネット プロトコル バージョン 4 (TCP/IPv4)"
    }
  }
}

 

ネストしたハッシュにアクセスするには、次のようにします。

PS /home/uhoo> $param.nw.ifs.ip

Name                           Value
----                           -----
DefaultGateway                 192.168.1.1
PrefixLength                   24
IPAddress                      192.168.1.84

PS /home/uhoo> 

 

余談ですが、ruby もハッシュをネストすることができますが、使うときが若干冗長ですね。ほかに書き方がないのか、調べている最中です。

param = {
  host: 'uhoo',
  workgroup: 'uhog',
  nw: { ipaddr: '192.168.1.1', gw: '192.168.1.254'}
}

p param[:host]
p param[:nw][:ipaddr]

 

次回は、パラメータファイルを使って設定を実行するスクリプトを作成します。 

uhoo.hatenablog.com

 

Ubuntu に VMware Player をインストールする

UbuntuVMWare をインストします。

  1. VMWare をダウンロード。

    VMware-Player-15.0.0-10134415.x86_64.bundle というファイルがダウンロードされます

  2. ダウンロードしたファイルを実行します。次のように入力
    uhoo@miyu:~$ sudo sh ./VMware-Player-15.0.0-10134415.x86_64.bundle 
    [sudo] uhoo のパスワード: 
    Extracting VMware Installer...done.
    [AppLoader] Use shipped Linux kernel AIO access library.
    An up-to-date "libaio" or "libaio1" package from your system is preferred.
    Gtk-Message: 21:46:48.840: Failed to load module "canberra-gtk-module"
    
    (vmware-installer.py:31940): IBUS-WARNING **: 21:46:51.327: The owner of /home/uhoo/.config/ibus/bus is not root!
  3. I accept にチェックを入れて Next をクリック

    f:id:uhoo:20181108220445p:plain

  4. I accept にチェックを入れて Next をクリック

    f:id:uhoo:20181108220547p:plain

  5. スタートアップ時にアップデートをチェックする場合 Yes にチェックを入れて Next をクリック

    f:id:uhoo:20181108220639p:plain

  6. カスタマーエクスペリエンスは No にチェックを入れて Next をクリック

    f:id:uhoo:20181108220803p:plain

  7. ライセンスキーはなにも入れないで Next をクリック

    f:id:uhoo:20181108220915p:plain

  8. 準備ができたので Install をクリック

    f:id:uhoo:20181108220952p:plain

  9. インストール中

    f:id:uhoo:20181108221400p:plain

  10. close をクリック

    f:id:uhoo:20181108221420p:plain

 

こんどは VMware  に Windows Server 2012 R2 をインストールしてみます。

uhoo.hatenablog.com

Rails でウェブアプリ作成(1)

Rails でウェブアプリを作ってみます。

$ rails new gohan
  create  
  create  README.md
  create  Rakefile
  create  .ruby-version
  create  config.ru
  create  .gitignore
  create  Gemfile
     run  git init from "."

  (中略)

Using sass 3.6.0
Using tilt 2.0.8
Using sass-rails 5.0.7
Using selenium-webdriver 3.141.0
Using spring 2.0.2
Using spring-watcher-listen 2.0.1
Using sqlite3 1.3.13
Using turbolinks-source 5.2.0
Using turbolinks 5.2.0
Using uglifier 4.1.19
Using web-console 3.7.0
Bundle complete! 18 Gemfile dependencies, 79 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
         run  bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted

 

これで下地ができました。gohan のフォルダに移動して、rails server と入力すると、ウェブサーバが起動します。

~$ cd gohan
~$ rails server
=> Booting Puma
=> Rails 5.2.1 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.3-p105), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

 

ウェブブラウザで http://localhost:3000 と入力すると、このような画面が表示されます。

f:id:uhoo:20181106135047p:plain

 

自分のスマートホンからもアクセスできます。

~$ ifconfig
enp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.11.2  netmask 255.255.255.0  broadcast 192.168.11.255
        inet6 fe8x::b95x:4fcx:8e3x:4b4x  prefixlen 64  scopeid 0x20
        ether 00:2x:6x:1x:5x:7x  txqueuelen 1000  (イーサネット)
        RX packets 312394  bytes 405455608 (405.4 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 124703  bytes 16762415 (16.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 16  

 

f:id:uhoo:20181106143900p:plain

 

 さてなに作ろうか。

お絵かきソフト Krita について

ご飯は、イラストをちょっとかじっています。今回は、Krita という無料のお絵かきソフトで何か描いてみます。

 f:id:uhoo:20181106162453p:plain

f:id:uhoo:20181106163025p:plain

まだ使い方がよくわからないので、レイヤーとブラシぐらいしか使えません。

f:id:uhoo:20181106211521p:plain

 

こんな感じです。

f:id:uhoo:20181106212120p:plain

はやく輪郭を指定してバケツで塗れるようになりたいです。

 

Ruby で a: :b コロンが向き合っている記述について

Ruby のコードで、メソッドの引数に a: :b のようにコロンが向き合っている記述をよくみかけます。

render 'uhoo', a: :b

 

不安な思いで調べ続けたところ、シンボルのハッシュだとわかりました。

x = {a: :b}
render 'uhoo', x

 

irb で確認してみると、このようにハッシュであることがわかります。

~$ irb

irb(main):001:0> x = {a: :b}
=> {:a=>:b}

irb(main):002:0> x[:a]
=> :b

 

ところでハッシュというのは、ご飯が思いつく限りでは、つぎのようなものでした。

irb(main):003:0> x = {"a" => "b"}
=> {"a"=>"b"}

irb(main):004:0> x["a"]
=> "b"

 

おそらく => などと入力するとShiftキーを押さなくてはならないし、見た目も不格好だから、このように作られたのだろうと、ご飯は勝手に推測しています。そういえば、JSONの書式も非常によく似ています。JSONでは次のように書きます。

{"a": "b"}

 

 おもむろに、これを ruby で書いてみたところ、

irb(main):005:0> {"a": "b"}
=> {:a=>"b"}

 

受け入れてくれました。なんと、キーがシンボルとして認識されています。

そこでハッシュのキーがなぜシンボルになっているかについて調べてみました。よく思い出せないのですが、文字列よりも高速に動作するからなのだそうです。ハッシュは、キーを指定して値を取り出すことが目的ですから、キーは識別さえできれば良いのです。シンボルは識別されることに存在意義があります。しかも高速ともなれば大歓迎です。まさに渡りに船だったのです。

では、値までもシンボルにするのはなぜでしょうか。おそらく同じ理由からでしょう。識別さえできれば良いという、使う側の都合でシンボルが選択されたのです。ご飯の勝手な推測ですが。

{a: :b}

それにしても、すっきりしていて理にかなっています。最初の違和感はいったいなんだったのでしょうか。ご飯はわがままなのです。さて、謎がとけたところでお酒でも買ってきます。