2018/02/25

GCP: GAE上にAPI(POST)を作成ーDatastoreの操作(Create) ー Python



  • Goal
    GAE(Google App Engine)上にREST API(メソッドはPOST)を作成する。
    APIが呼び出されたら、GCP(Google Cloud Platform)のDatastoreに新規Entity(レコード)を追加する。言語・環境はPython+flask。
  • case
    名前、点数、教科名をjsonでPOSTしたら、GCPのDatastoreに書き込みして、Keyを返信する。
  • How
    1:開発環境は、以下でセットアップ
      Ubuntu16.4 + Pyenv:Python2.7.13 on GCE
      GCP: Google App Engine上にPython(Flask)アプリを立ち上げる手順

    2:ライブラリのセットアップ
      app.yaml に、flaskの記述を追加
      - name: flask
        version: 0.12

    3:mainプログラム と curl 結果

    # -*- coding: utf-8 -*-
    # app.yamlに追記すればOK.libで持っていかなくてもよい。
    from flask import Flask,request,jsonify,abort
    # GCPのDatastoreを使うには必要。libで持っていかなくても、GAE上にある
    from google.appengine.ext import ndb
    import datetime
    app = Flask(__name__)
    # DatastoreのEntityの定義
    class test(ndb.Model):
    name = ndb.StringProperty()
    points = ndb.IntegerProperty()
    subject = ndb.StringProperty()
    creationdate = ndb.DateTimeProperty()
    # rootにアクセスされた場合のコントール
    @app.route('/')
    def hello():
    """Return a friendly HTTP greeting."""
    return 'Hello!'#abort(402) -- abortにしてもよい
    # 今回は、/addtest を Postで呼び出すという想定
    @app.route('/addtest', methods=['POST'])
    def runaddtest():
    testrecord = {}
    # jsonがなかったり、Nameがなければ、400で返す
    if not request.json or not 'name' in request.json:
    abort(400)
    # 登録するために、jsonを各項目にパースする
    testrecord = test(
    name = request.json['name'],
    points = request.json['points'],
    subject = request.json['subject'],
    creationdate = datetime.datetime.now()
    )
    # datastoreに登録する
    testrecord.put()
    # 登録したEntityのKeyの値を取ってくる。
    recordid = str(testrecord.key.id())
    # 返信用のjson作成。登録したEntityのKeyを返す
    replymes = {
    'id': recordid
    }
    # json と STATUS 201を返す
    return jsonify({'result': replymes}), 201
    @app.errorhandler(404)
    def page_not_found(e):
    """Return a custom 404 error."""
    return 'Sorry, Nothing at this URL.', 404
    @app.errorhandler(500)
    def application_error(e):
    """Return a custom 500 error."""
    return 'Sorry, unexpected error: {}'.format(e), 500
    $ curl -i -H "Content-Type: application/json" -X POST -d '{"name":"toshi","points":81,"subject":"kokugo"}' https://<project>.appspot.com/addtest
    HTTP/2 201
    content-type: application/json
    x-cloud-trace-context: XXXXXX;o=1
    date: Sun, 25 Feb 2018 03:15:06 GMT
    server: Google Frontend
    content-length: 51
    alt-svc: hq=":443"; ma=000; quic=531; quic=339; quic=338; quic=337; quic=335,quic=":443"; ma=2592000; v="41,39,38,37,35"
    {
    "result": {
    "id": "56765079040"
    }
    }
    view raw test-curl hosted with ❤ by GitHub

    4:Datastoreの結果

  • Thanks!

2018/02/24

Docker CE のディレクトリを引っ越しする方法

AWSのEC2 RHEL7.4 にDocker CEをセットアップする手順 の後に、Rootディレクトリを引っ越しする方法


・システム領域のハードディスクを大量に消費するので、別ディレクトリへ引っ越しする
以下の例は、/var/lib/docker から /xxx/mnt/docker/ へ引越し
0.初期設定確認
1.ServiceSTOP
2.ディレクトリを作ってコピー
3.設定変更
4.ServiceStart


## 0.初期状態確認
$ docker info | grep 'Docker Root Dir'
Docker Root Dir: /var/lib/docker
##RHEL7+Docker-CEの場合の設定ファイルを見ると、”dockerd”
##本設定は、dockerd の場合有効です。
$ sudo cat /usr/lib/systemd/system/docker.service
[sudo] xxxxのパスワード:
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
## 1.Service Stop ー Docker の停止
$ sudo service docker stop
Redirecting to /bin/systemctl stop docker.service
## 2.ディレクトリを作ってコピー
$ sudo mkdir /xxx/mnt/docker
$ sudo cp -r /var/lib/docker /xxx/mnt/docker
## 3.設定変更 - 設定ファイルを作成する
$ cd /etc/docker/         ##これが設定ファイル置き場。Jsonで置くらしい
$ ls
key.json
##ここに、daemon.jsonを作る
$ vi daemon.json
{
"graph": "/xxx/mnt/docker"
}
~
~
~
## 以下のように作成される。
$ ls
daemon.json key.json
##4. Service Start
$ sudo service docker start
Redirecting to /bin/systemctl start docker.service
## Root Directoryが変更されているので成功!!
$ docker info | grep 'Docker Root Dir'
Docker Root Dir: /xxx/mnt/docker
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 7239615c0645 7 weeks ago 177MB

2018/02/11

GCP: GAE(Google App Engine)のバージョン別のURL

GAEは、バージョン別に個別のURLをもっている。
なので、同時に複数バージョンを公開してテストできる。
知らなかった。。。

サンプル

https://"バージョン名"-dot-"プロジェクト名".appspot.com/

GCP: Google App Engine上にPython(Flask)アプリを立ち上げる手順



  • Goal
    開発環境も何も無い状態から、GAE(Google App Engine)上にFlaskアプリ(Hello World)を30分以内に立ち上げる。
    GAEは、Standard Environmentなので、Pythonは、2.7
  • How
    1. GCP上に新プロジェクト作成(xxxxx-test−0001) ⇒ 手順割愛
    2. GCP上で、GAEを有効にする。 ⇒ 手順割愛
      初めてのアプリ作成で、Pythonを選ぶ。
      チュートリアルはやらなくて良いので、途中で抜ける。
      1プロジェクトで、1GAEアプリしか持てない。
    3. GCP上に新VMインスタンス(Ubuntu16.4)作成(dev001) ⇒ 手順割愛
      TYPEはMicro(無料マシン)でOK。
      別にローカルマシンがあればそれでもOK。
    4. VM(dev001)の設定 ー 開発環境構築
        4-1. 初期設定 + Pyenv + GAEのSDKの導入
          以下のファイルを実行
       
         ~$ . UbuntuSetupForGAE.sh
    #! /bin/bash
    #update and upgrade
    sudo apt-get update
    sudo apt-get -y upgrade
    #install - I may put unnessary package
    sudo apt-get install -y git gcc make openssl build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils libgtk2.0-dev pkg-config unzip
    #Set up Pyenv and GAE SDK
    git clone https://github.com/yyuu/pyenv.git ~/.pyenv
    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
    echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
    echo 'eval "$(pyenv init -)"' >> ~/.bashrc
    git clone https://github.com/pyenv/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
    echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
    #Please select version
    wget https://storage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.66.zip
    mkdir bin
    cd bin
    unzip ~/google_appengine_1.9.66.zip
    cd
    echo 'export PATH="$PATH:$HOME/bin/google_appengine"' >> ~/.bashrc
    exec $SHELL -l

        4-2. Localに開発用フォルダの作成とPyenvのセットアップ      
           
    # 開発を行うディレクトリで操作すること
    # 必要なファイルを取ってくる ー GAEへのデプロイに必要なファイル
    git clone https://github.com/pumpkinpietea/GAEdevelopping-with-Flask.git
    # PYTHONの環境を作成
    pyenv install 2.7.14
    pyenv virtualenv 2.7.14 GAEFlask
    cd ./GAEdevelopping-wtih-Flask
    pyenv local GAEFlask
    # 必要なライブラリを開発を行うディレクトリ内のlibディレクトリにインスト−ルする。
    # そうすると、Deploy時に一緒に持っていく
    pip install -r requirements.txt -t lib

    5. Deploy
      localでのテスト。main.pyがあるディレクトリで以下を実行
          $ 
    dev_appserver.py .
     
       Deploy。 main.pyがあるディレクトリで以下を実行する
          $ appcfg.py update --noauth_local_webserver -A "project id" -V "version" .

    6. 確認する。以下のURLにアクセスする。
      
    https://”projectid”.appspot.com
         



  • Notes
    これを使って、LineのBotなどマイクロサービスを立ち上げれる
    main.pyの編集と必要なlibのインストールが必要
  • Thanks!!