2021年3月3日 星期三

Laravel-S (Swoole 加速) 的初步探索整理

在測試了最熱門的 swooletw/laravel-swoole 不成功之後,再測熱門程度差了好幾個等級,甚至 Google "laravel swoole" 的關鍵字,在搜尋結果都不會出現的 hhxsv5/laravel-s,成功了,那就繼續探所下去吧。

首先,新手真的不曉得該如 rewrite rule,轉過來的 request,有啟動 php 程式,但一直出 match route 錯誤,真是讓人感到挫折灰心。後來根據錯誤訊息,追縱 Laravel 的原始碼,直接找到 Illuminate\Routing\Router.php,在出錯的那個 function,加上下列程式片段,這樣它就會在執行的命令視窗顯示轉過來的網址,再依此結果修正 rewrite rule。

findRoute($request)
{
    echo "findRoute\n";
    var_dump($request->getRequestUri()); exit;
    ....
} 

發現在沒有指定檔名,要開啟預設檔案時,會轉過來 index.html,解決方式是在 .htaccess 加入。
DirectoryIndex index.php

然後在 route.php 將 Route::get('/', ... 改成如下
Route::get('/index.php', function () { ... });
在 Laravel 中使用的 dump() 是 Symfony\Component\VarDumper::dump() 建立的 helper function,會呼叫 CliDumper(),其會將資料輸出到執行 laravels start 的命令視窗。

解決辦法,參考原程式,自己另建一個 dump()

static 變數的測試,噢,會互相影響,所以要改很多 ...,只能再看看吧!!

另一困擾,假如網頁不是放在伺服器的 DocumentRoot 目錄下,asset() 和 url() 不會加上網頁的目錄,如 http://ll.cc/blog/list ...,其中 blog 不會出現。這要改的也是不少。

解決辦法是修改檔案 app/Providers/AppServiceProvider.php 中的 boot method。
public function boot()
{
    \URL::forceRootUrl("http://localhost:8180/blog"); 
}

亦可將其定義在 .env 中,例如 APP_URL。只要加上兩行就能解決問題,算是不錯了。

經過反覆測試,最後修改 boot() 的內容如下,程式的其餘部份不用改太多就可順利執行。
/*
 * 此為 laravels.received_request, After LaravelS parsed Swoole\Http\Request 
 * to Illuminate\Http\Request, before Laravel's Kernel handles this request.
 */
public function boot()
{
    // 只會在 loading 時被 call 一次
    echo "===================\n";

    \Event::listen('laravels.received_request', 
        function (\Illuminate\Http\Request $req, $app) 
        {
            // 這裡才是真的透過 browser瀏覽
            // 才有某些關於 client 的 SERVER 資料
            // 去除附加的預設執行檔 index.php
            $req_uri = $req->server->get("REQUEST_URI");
            $def_php = '/index.php';

            if (substr($req_uri, 0, strlen($def_php)) == $def_php) {
                $req_uri = substr($req_uri, strlen($def_php));
                if ($req_uri == '') {
                    $req_uri = '/';
                }

                $req->server->set("REQUEST_URI", $req_uri);
            }

            // 看起來,root url 並不是依據 "HTTP_HOST" 產生的
            // 改變 "HTTP_HOST",並不會改變 url() 和 asset() 的結果
            // 但是又找不到其他變數含有 port 資料
            // $req_host = $req->server->get("HTTP_HOST");
            // echo $req_host."<br>\n";
            // $req->server->set("HTTP_HOST", $req_host.'abc');
            // $req->server->set("HTTP_HOST", env('URL_PATH'));
            var_dump($req->request->all());
            echo base_path()."<br>\n";
            // initialize static varibles
            Util_sw::clean();
            // $req->query->set('get_key', 'hhxsv5');// Change query of request
            // $req->request->set('post_key', 'hhxsv5'); // Change post of request
            // echo asset(env('URL_PATH'))."<br>\n";
            \URL::forceRootUrl('http://'.$req->server->get('HTTP_HOST').'/'.env('URL_PATH'));
        }
    );
    
    // echo request()->getPathInfo();
    // echo \URL::to('/')."<br>\n";
    // var_dump(getallheaders());
    // \URL::forceRootUrl(env("APP_URL")); 
}

在上面的程式片段中,加了一堆測試輸出訊息的程式,就是在摸索階段為了瞭解其特性而加的。其餘的再繼續整理中。

依照 Laravel-S 專案上的說明,將 Laravel 的 .htaccess 的內容修改如下,就是在檔案不存在時,轉到 laravel-s 伺服程式處理。而 Apache 的 httpd,在瀏覽目錄時,設定的預設程式是 index.html,在這裡把它改成 index.php。

# Alternate default index page
DirectoryIndex index.php

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$  balancer://laravels/$1 [P,L]
</IfModule>

針對上面的 rewrite rule,要修改 reverse proxy 的設定。
<IfModule deflate_module>
    SetOutputFilter DEFLATE
    DeflateCompressionLevel 2
    AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml application/x-httpd-php image/jpeg image/gif image/png font/ttf font/otf image/svg+xml
</IfModule>


RemoteIPHeader X-Forwarded-For

ProxyRequests Off
ProxyPreserveHost On

<Proxy balancer://laravels>  
    BalancerMember http://127.0.0.1:5200 loadfactor=7
    #BalancerMember http://192.168.1.2:5200 loadfactor=3
    #BalancerMember http://192.168.1.3:5200 loadfactor=1 status=+H
    ProxySet lbmethod=byrequests
</Proxy>

因為一個伺服器不只一個網頁程式,所以並未依照 Laravel-S 的說明,將網頁指向根目錄 (/)。為了解決此問題,測試了好久才搞定。


另外,不想修改網站設定,依自己的習慣調網站的目錄架構,將 public 目錄下的東西移到網頁的根目錄,程式則移到 web-src 下面,storage 不太好移,仍然放在 web-src 下,所以還需進一步修改 bin/laravels.php、artisan,bootstrap/autoload.php。


後續發展,經過半個多月的摸索,終於將一個自己維護的網站套上 Laravel-S 了,後面再開一篇文章來整理修改和注意的重點。





測試 - 使用 Swoole 加速 Laravel

Swoole 這名稱聽過好一陣子了,但聽起來感覺不怎麼特別,另外也沒有特別要求速度的網頁,或者使用的 OS 是老掉牙的 Windows Server 2003,就沒什麼很注意。最近稍有空閒,想找點新東西來玩玩,活絡一下大腦,才稍微深入研究探討。

首先看一下執行的畫面,嗯,網頁主要是有個圖比較好看。


設定測試環境

現代程式開發人員的好處就是,不用在自己日常用的電腦上裝一堆不知有沒有的軟體來測試新的東西,只要寫個 docker 的設定檔,就可以弄一個測試環境。測試 Swoole 的 Dockerfile 如下。

FROM centos:7.9.2009

RUN yum -y install \
      http://rpms.famillecollet.com/enterprise/remi-release-7.rpm \
   && yum -y install --enablerepo=remi,remi-php70 \
        httpd php php-pdo php-mysqlnd \
        php-xml php-mbstring php-mcrypt \
        php-opcache php-pecl-swoole2 unzip \
    && yum clean all \
    && rm -rf /var/cache/yum \
    && curl -o /usr/bin/composer \
       https://getcomposer.org/download/1.10.20/composer.phar \
    && chmod a+x /usr/bin/composer

#port and entry
EXPOSE 80

CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

其中,大部分是 Laravel 使用的功能,只有 php-pecl-swoole2 為 PHP 增加 Swoole 功能,php-pecl-inotify 則是為了偵測檔案變動重新載入程式。


測試 laravel-swoole 及 Laravel-S

Google 和 Github 上,都是 swooletw/laravel-swoole 的關注度高很多,那就先測試 swooletw/laravel-swoole。

composer update 時發生錯誤,處理方式

使用個人使用者身分,進入 docker 中執行 composer

docker exec -it --user 1000:1000 docker_web_1 bash


在建立 Laravel 的 project 之後,依照 laravel-swoole 的說明修改 composer.json,然後執行 composer update,這時會出錯,錯誤訊息如下 
"Allowed memory size of 1610612736 bytes exhausted ... " 

參考網路找到的資訊
https://stackoverflow.com/questions/49212475/composer-require-runs-out-of-memory-php-fatal-error-allowed-memory-size-of-161

執行 composer update 時增加記憶體,成功安裝 PHP 的 Package

bash-4.2$ php -r "echo ini_get('memory_limit').PHP_EOL;"

128M

bash-4.2$ php -d memory_limit=-1 /usr/bin/composer update

然後依據說明,在命令列下指令啟動 swoole server 

php artisan swoole:http {start|stop|restart|reload|infos}

然後用瀏覽器瀏覽網頁,但是一直出錯。測試結果都是不成功,在讀取網頁時,一直出現下列錯誤

PHP Fatal error:  Call to undefined method Symfony\Component\HttpFoundation\ResponseHeaderBag::allPreserveCaseWithoutCookies() in /var/www/html/swoole_tst/vendor/swooletw/laravel-swoole/src/Server/Response.php on line 73

根據 google 到的資訊

allPreserveCaseWithoutCookies() is available after Symfony 3.4, what's your Laravel version?

Before Laravel 5.3, symfony/http-foundation is too old to use function allPreserveCaseWithoutCookies(). I'll try to make it compatible in the next release.

換了較舊版本的 laravel-swoole,或換較新版本的 Laravel,都不能成功,最後放棄。

第一次的測試碰到挫折,那就改為使用 hhxsv5/laravel-s 來測試。相對而言,laravel-s 較為麻煩,耐心的安裝設定後,依照說明下指令啟動 laravels,看到執行的畫面了,稍微了解運作方式之後,也可以在瀏覽器看到結果了。

bash-4.2$ php bin/laravels start

basePath: /var/www/html/swoole_tst/web-src 

VENDORDIR: /var/www/html/swoole_tst/web-src/../vendor

 _                               _  _____ 

| |                             | |/ ____|

| |     __ _ _ __ __ ___   _____| | (___  

| |    / _` | '__/ _` \ \ / / _ \ |\___ \ 

| |___| (_| | | | (_| |\ V /  __/ |____) |

|______\__,_|_|  \__,_| \_/ \___|_|_____/ 

                                           

Speed up your Laravel/Lumen

>>> Components

+---------------------------+--------------+

| Component                 | Version      |

+---------------------------+--------------+

| PHP                       | 7.0.33       |

| Swoole                    | 2.2.0        |

| LaravelS                  | 3.6.4        |

| Laravel Framework [local] | 5.1.46 (LTS) |

+---------------------------+--------------+

>>> Protocols

+-----------+--------+-------------------+----------------+

| Protocol  | Status | Handler           | Listen At      |

+-----------+--------+-------------------+----------------+

| Main HTTP | On     | Laravel Framework | 127.0.0.1:5200 |

+-----------+--------+-------------------+----------------+

>>> Feedback: https://github.com/hhxsv5/laravel-s

[2021-03-03 07:41:57] [TRACE] Swoole is running, press Ctrl+C to quit.


下面是 Laravel 5.1 的composer.json,只是多一行而已,為了保險起見,裝的 laravel-s 是前一版的。

{

    "name": "laravel/laravel",

    "description": "The Laravel Framework.",

    "keywords": ["framework", "laravel"],

    "license": "MIT",

    "type": "project",

    "require": {

        "php": ">=5.5.9",

        "laravel/framework": "5.1.*",

        "hhxsv5/laravel-s": "3.6.*"

    },

    "require-dev": {

        "fzaninotto/faker": "~1.4",

        "mockery/mockery": "0.9.*",

        "phpunit/phpunit": "~4.0",

        "phpspec/phpspec": "~2.1"

    },

    "autoload": {

        "classmap": [

            "database"

        ],

        "psr-4": {

            "App\\": "app/"

        }

    },

    "autoload-dev": {

        "classmap": [

            "tests/TestCase.php"

        ]

    },

    "scripts": {

        "post-root-package-install": [

            "php -r \"copy('.env.example', '.env');\""

        ],

        "post-create-project-cmd": [

            "php artisan key:generate"

        ],

        "post-install-cmd": [

            "Illuminate\\Foundation\\ComposerScripts::postInstall",

            "php artisan optimize"

        ],

        "post-update-cmd": [

            "Illuminate\\Foundation\\ComposerScripts::postUpdate",

            "php artisan optimize"

        ]

    },

    "config": {

        "preferred-install": "dist",

        "vendor-dir": "../vendor"

    }

}

在 laravel-s  的 git 專案網頁中,相關的說明蠻細的,一下子吸收不了那麼多,其中有一段是使用 httpd 的 reverse-proxy 來提供服務的說明,就照著設,內容大致如下,可以正常運作,但不盡完美,等後面測試累積較多經驗後,再來整理說明。

ProxyRequests Off


<Proxy *>

Order allow,deny

Allow from all

</Proxy>


# ProxyVia On


ProxyPass /swoole-web http://127.0.0.1:5200

ProxyPassReverse /swoole-web http://127.0.0.1:5200


初步測試後的心得

初步測試後,認為在使用上有一些要處理的問題,如下

  • 使用 url() 和 asset() 產生的 url 都是 http://127.0.0.1:5200 開頭
  • 只能處理透過 index.php 產生的網頁,assets 下的,如圖檔,js,css檔,都不能讀取
  • dump(),tracy debugger 等都不能運作
  • 依據 hhxsv5/laravel-s 的提示,必須使用 request,response 來處理輸入/輸出
目前的結論是,假如很在乎效能,就必須大幅調整程式,才能使用。另外,簡單的測試,原來的網頁存取次數 460.83 trans/sec,使用 swoole 加速後 1851.85 trans/sec,約 4倍,很爽的飆速感覺。

後續報告,經過 2 個多星期的奮鬥之後,想法有一些改變,可以在進入 kernel 的服務之前,預做一些處理,程式要改動部份就很少了。

2021年2月2日 星期二

玩舊遊戲 毀滅戰士 (DOOM)

DOOM

《毀滅戰士》的成功稍後由《毀滅戰士II》和數個資料片所延續,這些資料片包括《The Ultimate Doom》、《Master Levels for Doom II》和《Final Doom》。
下載遊戲 Shooter Games


Dosbox

在 Windows 中,需使用 dosbox 來玩舊遊戲。dosbox 0.74 可以在 Windows XP 上玩 DOOM 1993,但 DOOM 2 會沒有聲音。dosbox 0.74-3 則需在 Windows 7 以上的使用。

output 使用 overlay 亮度太暗,改成 ddraw 就亮多了
fullresolution 要改成 desktop,才會和桌面大小符合。

修改 default.cfg

設定 use_mouse: 1 就可以使用滑鼠玩遊戲。

鍵盤設定要使用 Ordinary scancodes

配合滑鼠控制,改用 WASD 做移動,W: 17, A: 30, S: 31, D: 32
key_strafeleft: 51 (<),key_straferight: 52 (>)

2020年12月29日 星期二

三星手機重複出現 "ANDROID系統 已斷開USB連接器,已連接USB連接器"

 依據相片的資訊,是去年11月17日開始用,到今天 12月30日,才一年一個月,連線接頭就出問題。

重開就好

但一插 USB 連接線,拔掉之後,又一直重複出現

Android 系統 已連接 USB 連接器
Android 系統 已斷開 USB 連接器

無法關閉手機螢幕

把一些沒用的應用程式移除,其中一個應用程式的名字就只有 "U" 一個字,看起來最可移,可以順利移除。移除後,上述訊息仍然不斷反覆顯示。但重開後,再插連接線,就不會出現了。但是也不能充電了。

怕沒手機用,立刻上 pchome 24小時到貨的網站買一個 A31 的福利品,$6,390,保固半年。

然後繼續想該如何處理不能充電的問題,上網 Google 解決方法,查到露天有人賣 A30 尾插,也有賣 Type-C 接頭,但要自己焊接,太困難了。

在官網上看到建議用退卡 pin 刮接頭,先前用牙線棒的尖端挖過無效,就放棄了。隔天想想,找不到退卡的 pin,就找根縫衣針來試試,結果,可以充了。但隔天拿到新手機,速度更快,就直接用新手機了,舊機當備份機吧。 


2020年12月13日 星期日

機車碟煞整理

主泵檢查視窗被惡意敲破

故事是這樣開始的。一直想和朋友一起騎車去司馬庫斯玩,某個假日趁天氣好,就自己先騎機車跑一趟,探一下路。當天天氣很好,可是在新竹之後,發現加裝的側貨箱上,有幾滴濕濕的水滴,想說是地上的水濺起來的。一直到司馬庫斯,那幾滴水滴都還在,就用布把它擦掉。在司馬庫斯稍微休息一下後,開始騎回台北。騎到新竹關西,側箱上又有幾滴水滴,只好開始仔細的研究它是怎麼來的。到處找,很來在前煞主泵下,拱到濕濕的痕跡,原來是煞車油漏出來了。繼續到處摸索,看是從那裡漏出來的。最後按到主泵的檢查視窗,稍一用力就一整個凹陷下去,原來是視窗破了。因為原本這個視窗就已變色有裂痕,就認為是老化裂掉,沒有多想。

回到台北,看看另一輛野狼傳奇的煞車主泵,發現也有白白的痕跡,由於天色已黑,靠著手機的照明,發現是被人用尖銳的東西用力敲破。因為野狼傳奇的煞車主泵是剛換新的,不可能會破,而兩台車的視窗主泵都破了,且是一樣的裂法,因此判斷是人為破壞,只是無法探究為何有人要做這種缺德事。

因為野狼傳奇的煞車主泵是剛換新的,花了 1,500,又很少騎,不想再花錢換一個新的。幸運的在網路上找到,可以自己買檢視窗的玻璃來換。

順便要換煞車油,在網路上找逆止閥工具,還有 DOT 4 煞車油。


雲豹200 改裝 VP4 總泵

因為隔週就要騎雲豹200 到阿里山,隔天要騎回中壢,想要立即修好,不可能去找週休三日的萊納斯,就找附近熟悉且看起來可靠的機車行。這家機車行生意很好,但有一個小問題,客人不能懂太多,問太多問題,更不能提到網路怎樣的。我曾提到我買東西來請他換,他就把東西擱著,給我來個冷處理,得等我低聲去拜托他修。服務算還好,但價格不算太便宜,雖然小事情可以免費幫一下忙。我也不想弄壞關係,因為有較急的狀況,必須有人幫我處理。

至於技術,介於可靠與不太可靠之間,會為了出清存貨,換不太合用的東西,這次就是沒有雲豹的主泵可換,換了一個庫存的代用前煞總泵。

主泵換了之後,隔天跑了一趟台北中壢,約一百公里。路上煞車無法完全煞住,按到底,押桿和把手碰在一起,車子還會一直往前滑。檢查拉桿的頂端和主泵活塞頂部有一段間隙,無法完全將活塞壓到底。後來在中間塞進布條,兩端綁住,讓間隙小一點,就這樣跑了一趟台北 - 塔塔加 - 阿里山。路上常常煞車按到底,還會繼續往前滑,還好我不常緊急煞車。

後來用 4VP 關鍵字找相關的資料,原來 4VP 是 BWS機車用的煞車。雲豹和野狼傳奇的主泵活塞直徑是 12.7mm,而這顆 4VP 的主泵活塞直徑應是 11mm,因為按煞車時,比較軟,行程比較長。也在拍賣網站找到了 4VP 的煞車拉桿,價格差異很大,可能有些是存貨出清,便宜賣,就買一支便宜的來試試吧,拍賣品名 YAMAHA 4VP 馬車 BWS 右煞車拉桿。下圖兩支拉桿,黑色是錯的,銀色才是正確的,可以看出正確的,接觸活塞的桿頂部位,旁邊的凹溝比較深,凸出來的部份比較長。拉桿換掉後,煞車就正常了。不然都已經在網路買了一個中古雲豹碟煞主泵,準備不得已時換掉。

換了正確的拉桿後,煞車正常多了,但拉桿頂端和活塞頂中間有約 1mm的間隙,按壓煞車的行程就變大了,騎長程幾個小時後,右手臂會很酸。不時想著要如何改善那多出來的一點點的間隙,若沒辦法就只好換回雲豹的主泵。

 

有天找了螺絲墊片,厚度約 1點多 mm,直徑約 10mm,用雙面膠黏在活塞頂部。手壓拉桿,行程少多了,但按幾次後,墊片會滑動,可能最後就噴飛了。

後來看看離合器的主泵,拉桿頂端和活塞頂部中間有一個厚厚的墊片,直徑和那個裝活塞的管孔一樣大,如上面的右圖所示。原來只要把墊片塞進那個活塞的孔就可以了,根本不用黏,直徑夠大就不會偏掉,也不會掉出來。配合那個裝活塞的孔徑,最後找到一元硬幣的厚度和直徑都剛好,塞進活塞和拉桿中間果然剛剛好,只要把硬幣邊緣的凸紋磨平即可。墊上硬幣後,煞車一按就有,少了那一段沒有煞車的行程,果然好用。假如按壓不順,或是表面不平整使得部分厚度較厚,可以將墊片的邊緣稍微磨一磨,或將較厚的部分磨平。

上面的圖看以看出離合器主泵的防塵套已破損,在賣油鏡的賣家,同時有單賣防塵套可以更換。拆下押桿換防塵套時,發現那個墊片正是用一元硬幣磨的,原來大家都在做一樣的事。


更換檢查視窗玻璃 (油鏡)

視鏡的直徑有 18mm和 12mm兩種,雲豹或野狼的是 18mm。

拆下主泵後,先想辦法把破掉的油鏡拆下。不是很好拆,用鈄口鉗把迫緊的金屬框破壞後,才拆下來,上圖是拆下的框和新的視鏡做比較。


本來想買油窗安裝特工,比較保險,但賣家說沒貨,且短期內不會進貨,建議若有足夠預算購買桌上型虎鉗,較好裝,且也可以挾持其他工件。

手邊只有一個做手工的小型虎鉗,按照網路上的分享,用硬幣頂住視鏡,避免弄壞視鏡。再慢慢鎖緊加壓,第一次,視鏡滑掉歪了,再重來一次才完全迫入。


換煞車油

接下來自己想辦法換煞車油和排空氣。不確定會消耗多少煞車油,乾脆買一公升的煞車油,同時買換煞車油的 DIY 工具。最後只用了一點點煞車油,還不小心翻倒流了不少,煞車油會吸水,放太久就沒用了,可能到最後也沒用丟掉。DIY 工具主要是單向閥,還有油管,注射筒,量杯,不用自己去另外買。有了單向閥就可以一個人換煞車油,排空氣。管路接好後,洩油螺絲打開,只要一邊壓,一邊補煞車油即可搞定。下面用空罐子接流出來的煞車油。


自己換了兩台機車的煞車油,其中一台流出來的都是生鏽的油,下圖是加了水稀釋後的樣子。另外,將上蓋鎖上後,繼續壓煞車,發現主泵上蓋邊邊會冒泡泡。原來上蓋的旁邊有一個小孔,可以平衡內外的壓力。





2020年12月6日 星期日

機車破輪經驗

 騎車出外到處跑,總有機率碰到輪胎被刺破。10月 (2020) 騎去阿里山,騎回台北在日月潭就碰上了。

從阿里山下來,騎往日月潭民宿,原本打算在向山遊客中心休息。騎到那兒才發現,日明潭環湖公路分段封閉單側道路,實施路面刨除重舖,而且是靠向山遊客中心一側的道路。騎到那路口,猶豫了一下,騎到刨除的路面停了一下,看能不能進遊客中心,然後再回到未施工的路面繼續往前騎去民宿。到水社壩附近的路邊,暫停確認民宿的位置,再次騎上馬路,發現後輪歪來歪去,不受控制,心裡一陣衝擊,不會是破胎吧,在這沒有住家的地方,可真有點麻煩。

停下來看,真的發現後輪扁扁的,輪胎沒氣了,只好把行李放到路邊的休息座椅,留下朋友來照顧,自己騎去找機車店。騎過一般住戶稍多的地段,但沒有機車店,頗感失望。繼續騎到一個土地公,看到有人騎機車來 路邊接水,鼓起勇氣,隨便抓一位婦人來問。她就很熱心的翻找機車行的電話,後來在後座下的貼紙上找一家,幫我打電話聯絡,報知所在位置。接下來就耐心等待,蹲下來,把後輪轉一轉,看是那裡破了。

輪胎上一片貓眼破片。


路邊很多當地居民來接水的土地公,幫助我打電話的婦人已再次來接水,還沒等到機車行的救援車。相片中的機車,是車行免費借我的小車車。在等待修車的時間,環日月潭也騎了不少的路。



用小貨車來救,雲豹200有點長,勉強調到可以把車斗的邊合上。

魚池新城村金進機車行,離等待的土地公約 9公里。當時是下午3點多,要從草屯叫貨過來,當天無法修好,要等到隔日退房後要回台北時,順路過去換車。這期間只好靠機車行借的代步車騎去玩。



花費的費用,救車 200元,換胎 2,200元,共 2,400元。還算可以接受,這是阿里山旅遊的一個小插曲。

2020年11月18日 星期三

建立 Gentoo overlay -- 啟動 Vmware Workstation Server

哀悼!! 到了 Vmware Workstation 16,這功能就被拿掉了。

這篇原來是想要建議上游,修改 overlay,在 systemd 的檔案中,加入對 server 模式的支援,但沒人理我,只好搬過來,自行修改。

To enable Vmware Workstation Server in systemd, I modified the vmware-workstation-15.0.2.10952284-r2.ebuild. The differences are as follows.

--- vmware-workstation-15.0.2.10952284-r2.ebuild	2018-12-16 10:02:59.220759030 +0800
+++ vmware-workstation-15.0.2.10952284-r3.ebuild	2019-02-13 10:00:15.091008507 +0800
@@ -22,9 +22,8 @@
 		vmware-tools-darwinPre15? ( https://softwareupdate.vmware.com/cds/vmw-desktop/fusion/${VMWARE_FUSION_VER}/packages/com.vmware.fusion.tools.darwinPre15.zip.tar -> com.vmware.fusion.tools.darwinPre15-${PV}.zip.tar )
 		vmware-tools-darwin? ( https://softwareupdate.vmware.com/cds/vmw-desktop/fusion/${VMWARE_FUSION_VER}/packages/com.vmware.fusion.tools.darwin.zip.tar -> com.vmware.fusion.tools.darwin-${PV}.zip.tar )
 	)
-	systemd? ( https://github.com/akhuettel/systemd-vmware/archive/${SYSTEMD_UNITS_TAG}.tar.gz -> vmware-systemd-${SYSTEMD_UNITS_TAG}.tgz )
 	"
-
+	
 LICENSE="GPL-2 GPL-3 MIT-with-advertising vmware"
 SLOT="0"
 KEYWORDS="~amd64"
@@ -191,6 +190,7 @@
 	net-dns/libidn
 	net-libs/gnutls
 	cups? ( net-print/cups )
+	server? ( sys-apps/lsb-release )
 	sys-apps/tcp-wrappers
 	sys-apps/util-linux
 	x11-libs/libXxf86vm
@@ -394,14 +394,23 @@
 
 		# install binaries
 		into "${VM_INSTALL_DIR}"/lib/vmware
-		dobin "${FILESDIR}"/configure-hostd.sh
+		dobin "${FILESDIR}"/{check-certificates.sh,shutdown-autostart-vm.sh}
+        
+        if use systemd; then
+            newbin "${FILESDIR}"/configure-hostd_systemd.sh configure-hostd.sh
+        else
+            dobin "${FILESDIR}"/configure-hostd.sh
+        fi
 
 		# install the libraries
 		insinto "${VM_INSTALL_DIR}"/lib/vmware/lib
 		doins -r lib/*
+		
+		dosym "${VM_INSTALL_DIR}"/lib/vmware/lib/libvmware-hostd.so/libvmware-hostd.so \
+            "${VM_INSTALL_DIR}"/lib/vmware/lib/libvmware-vim-cmd.so/libvmware-vim-cmd.so
 
 		into "${VM_INSTALL_DIR}"
-		for tool in vmware-hostd wssc-adminTool ; do
+		for tool in vmware-hostd vmware-wssc-adminTool ; do
 			cat > "${T}/${tool}" <<-EOF
 				#!/usr/bin/env bash
 				set -e
@@ -413,6 +422,9 @@
 			EOF
 			dobin "${T}/${tool}"
 		done
+		
+		into "${VM_INSTALL_DIR}"
+		dobin vmware-vim-cmd
 
 		insinto "${VM_INSTALL_DIR}"/lib/vmware
 		doins -r hostd
@@ -479,7 +491,7 @@
 	fperms 0755 "${VM_INSTALL_DIR}"/lib/vmware/lib/libvmware-gksu.so/gksu-run-helper
 	fperms 4711 "${VM_INSTALL_DIR}"/sbin/vmware-authd
 	if use server; then
-		fperms 0755 "${VM_INSTALL_DIR}"/bin/{vmware-hostd,wssc-adminTool}
+		fperms 0755 "${VM_INSTALL_DIR}"/bin/{vmware-hostd,vmware-vim-cmd,vmware-wssc-adminTool}
 		fperms 1777 "${VM_DATA_STORE_DIR}"
 	fi
 	if use vix; then
@@ -658,8 +670,14 @@
 
 	# install systemd unit files
 	if use systemd; then
-		systemd_dounit "${WORKDIR}/systemd-vmware-${SYSTEMD_UNITS_TAG}/"*.{service,target}
-	fi
+		systemd_dounit "${FILESDIR}/"vmware-{usb,vmblock,vmci,vmmon,vmnet,vmsock}.service
+		systemd_dounit "${FILESDIR}"/vmware.target
+		
+		if use server; then
+			systemd_dounit "${FILESDIR}/"vmware-{authentication,hostd}.service
+			systemd_dounit "${FILESDIR}/"vmware-workstation-server.target
+		fi
+	fi        
 
 	# enable macOS guests support
 	if use macos-guests; then

The modified files and new files are listed as follows.

File vmware.targetvmware-authentication.service is removed from this file.

[Unit]
Description=VMware Workstation Service(s)
Requires=vmware-vmmon.service
Wants=vmware-vmci.service
Wants=vmware-vmsock.service
Wants=vmware-vmblock.service
Wants=vmware-vmnet.service
Wants=vmware-usb.service

[Install]
WantedBy=multi-user.target

File vmware-workstation-server.target

[Unit]
Description=VMware Workstation server Service(s)
Requires=vmware.target
After=vmware.target
Wants=vmware-authentication.service
Wants=vmware-hostd.service

[Service]

[Install]
WantedBy=multi-user.target

File vmware-authentication.service, PartOf is modified to vmware-workstation-server.target.

[Unit]
Description=VMware Authentication Daemon
After=vmware.target
PartOf=vmware-workstation-server.target

[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/opt/vmware/sbin/vmware-authdlauncher

File vmware-hostd.service

[Unit]
Description=VMware Workstation Server
After=vmware-authentication.service
PartOf=vmware-workstation-server.target

[Service]
Type=simple
RemainAfterExit=yes
ExecStartPre=sh /opt/vmware/lib/vmware/bin/check-certificates.sh

PIDFile=/var/run/vmware/vmware-hostd.PID
ExecStart=/opt/vmware/bin/vmware-hostd -a -d /etc/vmware/hostd/config.xml

ExecStop=sh /opt/vmware/lib/vmware/bin/shutdown-autostart-vm.sh

File configure-hostd_systemd.sh, which is installed as /opt/vmware/lib/vmware/bin/configure-hostd.sh.

#!/bin/bash

action="$1"

case $action in
  add)
    systemctl -q enable vmware-workstation-server.target
    systemctl -q start vmware-workstation-server.target
    ;;
  remove)
    systemctl -q disable vmware-workstation-server.target
    systemctl -q stop vmware-workstation-server.target
    ;;
  status)
    systemctl -q is-active vmware-workstation-server.target && echo on || echo off
    ;;
  *)
    exit 1
    ;;
esac

File check-certificates.sh

#!/bin/bash

# Check if certificates exist.  If not, we need to generate them, ala sshd.
if [ ! -e /etc/vmware/ssl/rui.key -o ! -e /etc/vmware/ssl/rui.crt ]; then
        chmod 0600 /etc/vmware/ssl
        openssl req -x509 -days 365 -newkey rsa:2048 -keyout /etc/vmware/ssl/rui.key -out /etc/vmware/ssl/rui.crt -config /etc/vmware/ssl/hostd.ssl.config
        chmod 0600 /etc/vmware/ssl/rui.key /etc/vmware/ssl/rui.crt
fi

File shutdown-autostart-vm.sh

# "Shutdown VMs in the AutoStart Sequence"
HOHO_ADMIN="$(/opt/vmware/bin/vmware-wssc-adminTool "/etc/vmware/hostd/authorization.xml" 2>/dev/null)"

if [ "x" != "x${HOHO_ADMIN}" ]; then
	/opt/vmware/bin/vmware-vim-cmd -U "${HOHO_ADMIN}" hostsvc/autostartmanager/autostop
fi

The changes are summarized as follows.

  • Put the systemd services in files folder instead of downloading them.
  • Create vmware-workstation-server.target, and move vmware-authentication.service from vmware.target to vmware-workstation-server.target.
  • Create vmware-hostd.service to start hostd service, and create two scripts, which are invoked by this service, to check certificates and shutdown autostart VMs.
  • Use systemctl command instead of rc-service commands In configure-hostd.sh.
  • Create libvmware-vim-cmd.so link to libvmware-hostd.so to make vmware-vim-cmd work.

網誌存檔