しばたテックブログ

気分で書いている技術ブログです。

Azure Cloud Shell(PowerShell)がLinuxコンテナになりました。

先週の話*1なのですが、以前、

blog.shibata.tech

でお伝えした様にWindows Serverコンテナで動作しているAzure Cloud Shell(PowerShell)がLinuxコンテナ上で動作する様になりました。

中の人のツイートがこちら。

PowerShell 6.0がデフォルトに

新しいAzure Cloud Shell(PowerShell)を起動すると下図の様になり、Linux(Ubuntu)上でPowerShell Core 6.0がデフォルトで起動する様になっています。

f:id:stknohg:20180709170144p:plain

ちなみに今回試すにあたりCloud Shellを作り直したのですが、最初の画面が

f:id:stknohg:20180709170156p:plain

の様に「PowerShell(Linux)」と変わっていました。

Azure Cloud Shell(Bash)との違い

Azure Cloud Shell(Bash)とAzure Cloud Shell(PowerShell)は同一OS上で動くことになったわけですが、おそらく、同一のコンテナイメージを使っています。

公式な情報は無くコンテナ内を調べてもズバリな情報を見つけることができなかったのですが、両コンテナで/var/log/dpkg.logが完全に一致しており、ここから間接的ではありますが同一イメージだと推測できます。
(さすがに別イメージならdpkg.logは一致しないでしょう...他にコンテナの同一性を調べる良い方法があれば教えて欲しいです...)

このためAzure Cloud Shell(Bash)とAzure Cloud Shell(PowerShell)の違いはログインシェルだけになります。

Azure Cloud Shell(PowerShell)のこれから?

Azure Cloud Shell(PowerShell)が今後どうなるかについては未だ公式なアナウンスはありません。

Azure Cloud Shell(Bash)でもPowerShell Coreは利用できますので、いまとなっては、Azure Cloud Shell(PowerShell)の存在意義は

「ログインシェルをPowerShellにしたい。」

位しか無い様に思えます。
PowerShellが大好きな私から見ても

「これいる?Bashでログインして pwsh って4文字打てば良いだけでは?」

というのが正直な気持ちです。

ここからは完全に私見ですが、現在Azureを管理するためのコマンドはAzure CLIAzure PowerShellの二系統あり、両者の使い分けのためにAzure Cloud Shell(Bash)とAzure Cloud Shell(PowerShell)は分かれたまま残り続けるのかなと思っています。

実際にどうなっていくかは今後の情報を追っていきたい感じです。

*1:ちょっとプライベートが忙しくブログを書き上げるのが遅くなってしまいました...

はてなブログのエントリ一覧をPowerShellで取得する

小ネタです。

blog.shibata.tech

で少し触れたはてなブログのエントリ一覧を取得する方法を紹介します。

sitemap.xmlからエントリ一覧を取得する

はてなブログに限った話ではなく一般的な話として、SEO対策でクローラー向けにサイトのトップにsitemap.xmlを置いているサイトが多くあります。

はてなブログにもこのsitemap.xml*1が用意されており、以下のスクリプトでエントリの一覧を取得することができます。

$url = 'ブログのURL'
$res = Invoke-WebRequest -Uri ([IO.Path]::Combine($url, 'sitemap.xml'))
if ($res.StatusCode -ne 200) {
    return
}
# sitemapの場合
Write-Output ([xml]$res.Content).urlset.url.loc
# sitemap indexの場合
foreach ($loc in ([xml]$res.Content).sitemapindex.sitemap.loc) {
    $res2 = Invoke-WebRequest -Uri $loc
    if ($res2.StatusCode -ne 200) {
        continue
    }
    Write-Output ([xml]$res2.Content).urlset.url.loc
}

実行結果はこんな感じです。

f:id:stknohg:20180621231023p:plain

sitemap.xmlは単体でサイト内のリンクを記述している場合と、別のxmlファイルへのリンクを記述している場合があるので両者に対応しておく必要があります。
このスクリプトでは両方のケースの値を無理矢理取得しようとする単純な作りにしています。

はてなブログAtomPubを使ってエントリ一覧を取得する

はてなブログではAtom Publishing Protocol(AtomPub)によるAPIが提供されています。

このAPIを使うと、エントリの一覧や、タイトル、エントリ内容などにアクセスすることができます。
エントリの一覧を取得するには以下の様なスクリプトを実行すればOKです。

# 設定
# IDや認証情報ははてなブログの詳細設定から確認可能
$hatenaId = 'はてなID'
$blogId = 'ブログID'
$cred = Get-Credential -UserName $hatenaId

# エントリ取得(下書き含む)
$entries = & {
    function GetXmlContent ([string]$Uri, [PSCredential]$Credential) {
        $result = [PSCustomObject]@{
            Content = $null;
            NextUri = $null;
        }
        $ret = Invoke-WebRequest -Uri $Uri -Credential $Credential
        if ($ret.StatusCode -ne 200) {
            return $result
        }
        $xml = [xml]$ret.Content
        $result.Content = $xml.feed.entry
        $result.NextUri = $xml.feed.link | Where-Object rel -eq next | Select-Object -ExpandProperty href
        return $result
    }

    $result = GetXmlContent -Uri "https://blog.hatena.ne.jp/$hatenaId/$blogId/atom/entry" -Credential $cred
    Write-Output $result.Content
    while (-not [string]::IsNullOrEmpty($result.NextUri)) {
        $result = GetXmlContent -Uri $result.NextUri -Credential $cred
        Write-Output $result.Content
    }
}

# 適当に出力
$entries | ForEach-Object {
    [PSCustomObject]@{
        Title = $_.Title;
        Url = $_.link | Where-Object rel -eq alternate | Select-Object -ExpandProperty href;
        IsDraft = $_.control.draft -eq 'yes';
        #Content = $_.content.'#text';
    }
} | Format-List

実行結果はこんな感じです。

f:id:stknohg:20180621231406p:plain

このサンプルでは簡単のためにBasic認証を使用しています。
実際にスクリプトを利用する場合は自己の責任において認証方法を選択してください。

スクリプトの内容に特に目を見張るところはありませんが、ページネーションのために内部関数を用意したくらいが工夫したところでしょうか。

なお、出力形式はかなり適当なので適宜カスタマイズして利用するのがオススメです。

【補足】 Gist

当初、上記スクリプトはGistに上げていました。
補足としてリンクを記載しておきます。

*1:昔はsitemap_index.xmlだったらしい

LinuxとmacOSでPowerShell Coreのパッケージ管理方法が変わります

先日公開されたPowerShell Core 6.1.0-preview.3からLinuxとmacOSでパッケージマネージャーを使ったインストールをする際のパッケージ名に変更が入ります。

github.com

安定版とプレビュー版の分離

PowerShell Core 6.1.0-preview.2まではLinuxやmacOSのパッケージマネージャーを使う際のパッケージ名は「powershell」の一つで管理していました。
これだと安定版のみを更新していきたい人に対してプレビュー版の更新が強制されることになり非常に問題がありました。

本件に先立ってGitHubのホームにあるインストーラーのリンクが安定版とプレビュー版で分離される様になり、今回PowerShell Core 6.1.0-preview.3でパッケージ名も分離されることとなりました。

f:id:stknohg:20180615132146p:plain

(図は安定版、プレビュー版が分離されたGitHubのホーム画面)

パッケージ名の変更

ここまでを踏まえて、今後PowerShell Coreのパッケージ名は以下の様に変更されます。

  • 安定版 : powershell
  • プレビュー版 : powershell-preview

例としてapt-getの場合は以下の様に使い分けることになります。

# 安定版のインストール
sudo apt-get install -y powershell

# プレビュー版のインストール
sudo apt-get install -y powershell-preview

インストール可能なバージョン

ここから少しややこしいのですが、「OSやディストリビューションによってサポート対象となるPowerShellのバージョンが異なる」、「既にPowerShell Core 6.1.0-preview.1~preview.2をリリースしてしまっている」といった事情があるため、パッケージ毎にインストール可能なPowerShell Coreのバージョンはややこしいことになっています。

以下に現時点での一覧を記載します。

f:id:stknohg:20180615131756p:plain

これが将来的には下図の様になっていくのですが、既存のPowerShell Core 6.1.0-preview.1~preview.2がどうなるかはまだ不明です。

f:id:stknohg:20180615131837p:plain

シンボリックリンクの変更

パッケージ名の変更に合わせてPowerShell Coreの実行バイナリに対するシンボリックリンクにも変更が入ります。

たとえばUbuntuの場合、PowerShell Coreのバイナリは

  • /opt/microsoft/powershell/<バージョン番号>/pwsh

にあり、シンボリックリンクが

  • /usr/bin/pwsh

に貼られていますが、このシンボリックリンクが

  • /usr/bin/pwsh-preview

に変更されます。
安定版は/usr/bin/pwshのまま変わりません。

最後に

ざっとこんな感じです。

本来この点は最初のプレビューリリース前に考えるべき話でした。
若干対応が遅れたものの、あるべき姿に落ち着いたのは良いことだと思います。