Email me: jollen # jollen.org

more: Jollen 的 Embedded Linux 教育訓練

« January 2016 | (回到Blog入口) | March 2016 »

February 2016 歸檔

February 4, 2016

如何自行架設 Parse API Server

Facebook 在 2016 年 1 月 28 日(台北時間 1 月 28 日)宣佈,將關閉 Parse.com 平台服務,但也同時釋出 Prase Platform 的 API Server 原始碼。本文介紹如何自行架設 Parse Server。

本文章採用 Markdown 語法撰寫(why?),若無法完整閱讀全文,請點擊這裡。

前言

WoT.City 將在 2 月 4 日晩間 08:00PM ,舉辦 Parse.com API 伺服器的架設教學與討論交流。在家裡上網,跟著大家在 IRC 上一起架設 Parse 伺服器,共同迎接 IoT 個人架構時代的開始。

parse-server 是一個相容於 Express 的 URL Router 套件,這表示:

  • 以 npm 模組方式引入使用,不需要直接 fork 此專案
  • 可以建立新的 Express application 專案來使用
  • 或是,將 parse-server 掛載(mount)到現有的 Express application 專案上使用

以下從建立新的 Express application 專案開始,介紹 parse-server URL router 套件的使用方法。

如果不想自行使用 Express Generator 產生專案的話,請參考 nodejs-express 並直接由 Step 4 開始。

本文目標:

  • 前置作業
  • 建立 Node.js 與 Express 專案
  • Create the first ParseServer instance and Cloud Code
  • Use restAPIKey
  • 測試 REST API

前置作業

環境安裝:

  • 安裝 Node.js 4.1 以上版本(建議 v4.2.x TLS)
  • 安裝 MongoDB Server,或直接到 MongoLab 申請免費的 MongoDB 資料庫服務即可

MongoDB 的新手建議可先申請 MongoLab 服務。MongoLab 目錄提供 500MB 的免費資料庫服務(如圖一)。

2016-02-04 12 27 02 圖一:申請 MongoLab 服務

Step 1: 安裝 Express Generator

$ sudo npm install express-generator -g

Step 2: 建立新的 Express 專案

$ express my-parse-app

   create : my-parse-app
   create : my-parse-app/package.json
   create : my-parse-app/app.js
   create : my-parse-app/public
   create : my-parse-app/public/javascripts
   create : my-parse-app/public/images
   create : my-parse-app/public/stylesheets
   create : my-parse-app/public/stylesheets/style.css
   create : my-parse-app/routes
   create : my-parse-app/routes/index.js
   create : my-parse-app/routes/users.js
   create : my-parse-app/views
   create : my-parse-app/views/index.jade
   create : my-parse-app/views/layout.jade
   create : my-parse-app/views/error.jade
   create : my-parse-app/bin
   create : my-parse-app/bin/www

   install dependencies:
     $ cd my-parse-app && npm install

   run the app:
     $ DEBUG=my-parse-app:* npm start

進入專案目錄,並安裝 npm 模組:

$ cd my-parse-app/
$ npm install

目前的專案內容:

$ ls -l
total 16
-rw-r--r--  1 apple  staff  1442  2  3 14:22 app.js
drwxr-xr-x  3 apple  staff   102  2  3 14:22 bin
drwxr-xr-x  3 apple  staff   102  2  3 14:23 node_modules
-rw-r--r--  1 apple  staff   362  2  3 14:23 package.json
drwxr-xr-x  5 apple  staff   170  2  3 14:22 public
drwxr-xr-x  4 apple  staff   136  2  3 14:22 routes
drwxr-xr-x  5 apple  staff   170  2  3 14:22 views

Step 3: 安裝 parse-server 模組

$ npm i parse-server --save

Step 4: 修改 app.js 主程式

開啟 app.js 主程式,分別加入以下幾段程式碼。

4.1. 引入 parse-server 模組:

var ParseServer = require('parse-server').ParseServer;

4.2. 建立 ParseServer 的 instance

修改 app.js,加入:

// Specify the connection string for your mongodb database
// and the location to your Parse cloud code
var api = new ParseServer({
  databaseURI: 'mongodb://localhost:27017/dev',
  cloud: '/home/myApp/cloud/main.js', // Provide an absolute path
  appId: 'myAppId',
  masterKey: 'mySecretMasterKey',
  fileKey: 'optionalFileKey'
});

以上有幾個選項要修改:

  • databaseURI:MongoDB 的 URI
  • cloud:Cloud Code 主程式
  • appId:Application ID

4.3 修改 databaseURI

如果是申請 MongoLab 的服務,請填入 MongoLab 提供的 URI 填入(如圖二)。<dbuser> 與 <dbpassword> 填入自行建立的 database user。

2016-02-04 12 35 16 圖二:申請的 MongoDB URI

4.4 加入 Cloud Code

這個是 Parse Cloud Code 的程式碼路徑,請建立想存放 Parse Cloud Code 的路徑,接著建立 main.js 主程式,內容如下:

Parse.Cloud.define("hello", function(request, response) {
  response.success('hello');
});

4.5 設定 appId

Application ID 用來管理 Parse API 的使用權限,原則上可以自行指定一個任意字串,例如:5de49f1cd4bd09be95bf35ecbf1117b0。Mac 或 Linux 的使用者,可以用 md5 做一個 md5sum 當 appId 用:

$ md5 /etc/hosts
MD5 (/etc/hosts) = 91df01d82a846dbddc163a65c0f7b047

4.6 掛載 parse-server 的 URL router

修改 app.js 加入:

// Serve the Parse API on the /parse URL prefix
app.use('/parse', api);

4.6 練習加入 restAPIKey

同樣的觀念,為 Parse Server 加入 restAPIKey。修改示範:

完整示範

提供 app.js 程式碼修改示範:

Step 5: 啟動 MongoDB

申請 MongoLab 服務請略過本步驟。

Step 6: 啟動 Node.js

$ npm start

API 測試

使用 curl 來呼叫 Parse 的 REST API 進行初步測試。閱讀 REST API Guide 了解 Parse Server API 細節。

Creating Objects

測試指令:

curl -X POST \
-H "X-Parse-Application-Id: 123456789" \
-H "X-Parse-REST-API-Key: 9d676c364a11d96b8c67e69bf7bbfb82" \
-H "Content-Type: application/json" \
-d '{"score":1337,"playerName":"Sean Plott","cheatMode":false}' \
http://localhost:3000/parse/classes/GameScore

返回結果:

{"objectId":"B2BjW12yXo","createdAt":"2016-02-04T05:29:35.187Z"}

Parse API 使用 X-Parse-Application-Id 檔頭送出 appId,請填入自行設定的 appId。

參考資源

  • Parse Server Guide, https://parse.com/docs/server/guide

Reports and Discussion

February 15, 2016

學習 Unikernel 與 Runtime.js (Part 1)

Unikernel 是一個很有趣的概念。不久前 Docker 收購 Unikernel Systems[1] 是很多人對它的第一印象,台灣的新聞媒體將 Unikernel 翻譯為「無核化」或「去核化」...

本文章採用 Markdown 語法撰寫(why?),若無法完整閱讀全文,請點擊這裡。

前言

Unikernel 是一個很有趣的概念。不久前 Docker 收購 Unikernel Systems[1] 是很多人對它的第一印象,台灣的新聞媒體將 Unikernel 翻譯為「無核化」或「去核化」;不過,Unikernel 並「不是」要消滅作業系統核心,當然也不是要去除作業系統核心;相反地,作業系統核心技術,將更顯重要。

Library OS

相較傳統的作業系統核心(conventional OS),Unikernel 的作業系統核心是以「Library」的形式實作 。技術上來說,Unikernel 可以說是一個「Library OS」的概念。

Unikernel 的做法(implementation)是將應用程式(applications)、相關模組(modules)與 library OS 打包(construct)成一個 image 檔。這樣做的目的,是希望將目標系統(target image)儘量簡化;簡化的目的,是縮小 images 的大小(image size)。

根據維基百科上的解釋[2]:

These libraries are then compiled with the application and configuration code to build sealed, fixed-purpose images (unikernels) which run directly on a hypervisor or hardware without an intervening OS such as Linux or Windows.

簡單來說,打包出來的 images 檔就稱為「Unikernel」。這個打包的過程,會將 library OS 編譯到應用程式裡,因此,製作 unikernel image 也需要配套工具。

Unikernel 並不是要去除作業系統。所謂的「無核化」的「核」,更精準的解釋應該是去掉 conventional OS 的「核(kernel)」,改採 library OS 的「核」。

專研作業系統與編譯器的工程師,不但沒有身價眨值的問題,還可能會倍數增值呢。為什麼學習作業系統又更重要了呢?因為 Unikernel image 是一種特定用途的 image file,這種 image file 也稱為 immutable VM image。

Immutable image 裡面的 library OS 讓 unikernel image 能直接(directly)在虛擬機上(hypervisor)運行,而不需要透過像是 Linux 或 Windows 的 conventional OS[2]。實作這個 library OS 需要對作業系統、微處理器、虛擬機、編譯器與 software stacks 有綜合的知識。

Unikernel 是一個 image file,也是一種 immutable image。它的用途單一不變(immutable),Unikernel 的「Uni」正能表達它的理念。Unikernel 自然有許多不同的實作;針對不同的應用程式(applications)甚致是不同的雲端佈署架構,也需要更多單一的 library OS。

受到 jserv 一直在自幹編譯器[3]的激勵,新的一年(2016 猴年)就幫自已定了一道作業:期許在新的一年,也可以自已做一個 Unikernel。不過,因為 Unikernel from scratch 的目標有點遠大,所以:

因為,近幾年一直是 JavaScript 的愛好者,所以找了 runtime.js 做為研究目標。

Runtime.js

Runtime.js 是 Unikernel 的一個實作。Runtime.js 提供一個稱為 runtimeify 的編譯器,可以將 JavaScript 應用程式,打包為 ramdisk image,並透過 initrd 啟動。這是第一階段的學習重點,關於這個部份的學習紀錄,都會發佈在 jollen/simple-iot-runtime

沒想到 Embedded Linux 也能有這樣的面貌,這是一種有點熟悉又有些陌生的奇妙感覺。initrd 與 JavaScript 放在一起使用,又是一個奇妙的感覺。

隨著 Node.js 的發展,以及 frontend 模組化(JavaScript modules)技術的進步,出現了 Browserify 技術,Browserify 今天更是運用在 Unikernel 概念裡,果真是 JavaScript 無極限。

Runtime.js 是一個開源的 library OS 實作,裡面包含二個 component [4]:

  • Runtime.js 的 OS kernel
  • Runtime.js 程式庫本身

Runtime.js 的 OS kernel 引入了 V8 JavaScript engine;整體來看,Runtime.js 提供了一個優雅的 JavaScript Unikernel 技術方案。

相關資源

  • [1] Unikernel Systems Joins Docker, https://blog.docker.com/2016/01/unikernel/
  • [2] Unikernel, https://en.wikipedia.org/wiki/Unikernel
  • [3] 從無到有開發 C 編譯器, https://goo.gl/aqBw9R
  • [4] Runtime.js, https://github.com/runtimejs/runtime
  • [5] https://github.com/jollen/simple-iot-runtime

延伸閱讀

Reports and Discussion

February 16, 2016

學習 Unikernel 與 Runtime.js (Part 2)-Build Runtime.js VM Image

Runtime.js 可以讓我們用 Node.js 與 JavaScript 來開發 Unikernel,熟悉 Node.js 是第一個基本功課,Runtime.js 的 OS kernel 採用 V8 JavaScript Engine,目前支援 KVM,研究 Runtime.js 的 kernel 實作,是第二個基本功課...

本文章採用 Markdown 語法撰寫(why?),若無法完整閱讀全文,請點擊這裡。

前言

以下步驟參考自 Runtime.js 官網 的說明,目標是初始化一個新的 Runtime.js 專案。請參考 Getting Started 上的環境安裝說明。

要使用 Runtime.js 必須安裝 Node.js 執行環境,以下步驟以 Mac 環境為主,Node.js 的版本為 v4.2.6。

建立 Runtime.js 專案

Runtime.js 仍是一個發展中的開源計畫,目前的發展狀態如下:

  • Hypervisor 部份,目前僅支援 KVM
  • API 部份,目前 Runtime.js 提供的 JavaScript library 非常有限,不過根據應用程式需求,可以自行安裝 Node.js 模組來使用
  • 目前提供 runtimeify 工具來製作 Unikernel image,這是 browserify 的前端(wrapper)命令列工具

即便 Runtime.js 還是處於這麼早期的階段,但實作簡單的 IoT cloud VM image 問題並不大。以下是使用 runtime.js 製作 unikernel image 的準備工作說明。

1. 安裝 QEMU VM

安裝 QEMU VM 做為 Runtime.js 的執行環境。以 Mac 為例,使用 homebrew 安裝 qemu:

$ brew install qemu   

Runtime.js 目前僅支援 KVM。

2. 建立新的 Node.js 專案

使用 npm 建立新的 Node.js 專案:

$ mkdir simple-iot-runtime
$ cd simple-iot-runtime
$ npm init

這次的學習計畫,將不使用 Express。如果要實作 REST API 的話,後續就要實作一個小型的 URL router。

3. 安裝 Runtime.js 模組

安裝 Runtime.js 的 core library:

$ npm install runtimejs --save

4. 安裝 Runtime.js CLI 與 Runtimeify

Runtime.js 提供二個命令列工具(CLI):

  • runtime-cli 是 qemu 的 wrapper,用來啟動 qemu,方便測試 runtime.js VM image
  • runtimeify 是 browserify 的 wrapper,用來將 Node.js 的相依模組打包(bundle)成一個檔案
$ sudo npm install runtime-cli -g
$ sudo npm install runtimeify -g

Browserify 原本是用給 frontend 開發使用的工具,讓 frontend 的 JavaScript 程式碼,也能以 require() 的風格引入相依模組。現在被應用於 Runtime.js 專案中。

5. 製作 Unikernel Images

撰寫應用程式 index.js,目前內容僅只是簡單的 console.log(),可參考 jollen/simple-iot-runtime/index.js。

使用 runtimeify 將主程式 index.js 打包(bundle)成 initrd 檔案:

$ runtimeify index.js -o initrd

6. 啟動 Unikernel

使用 runtime-cli 啟動製作出來的 initrd:

$ runtime start 

2016-02-15 6 58 35

小結

上述步驟得到的 initrd 就是一個 unikernel image。runtime-cli 是 qemu 的 wrapper,測試方式是使用 runtime-cli 啟動 qemu,並載入 initrd 檔案。initrd 是 runtime.js 預設的 unikernel 檔案。

雖然 unikernel 的檔名是 initrd,但這與 GNU/Linux 上的 initrd(init process)是完全不同的實作。Runtime.js 所製作的 initrd,其實就是 browserify 所編譯出來的 JavaScript 應用程式。

這個部份並沒有難度,只是操作層面的練習,熟悉指令就可以很容易上手。從這個練習也可以知道:

  • Runtime.js 可以讓我們用 Node.js 與 JavaScript 來開發 Unikernel,熟悉 Node.js 是第一個基本功課
  • Runtime.js 的 OS kernel 採用 V8 JavaScript Engine,目前支援 KVM,研究 Runtime.js 的 kernel 實作,是第二個基本功課
  • Runtime.js 的 OS kernel 架構與 Exokernel 相似,所以研究 Exokernel 與 Runtime.js kernel 的架構,是第三個功課

延伸閱讀

Reports and Discussion

關於 February 2016

此頁面包含了在February 2016發表於Jollen's Blog的所有日記,它們從老到新列出。

前一個存檔 January 2016。

後一個存檔 March 2016。

更多信息可在 主索引 頁和 歸檔 頁看到。

Top | 授權條款 | Jollen's Forum: Blog 評論、討論與搜尋
Copyright(c) 2006 www.jollen.org