GAEアプリのデプロイ

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,343

raccoondog

score 17

GAEアプリのデプロイを実施して、Bigquery上のテーブルに対して毎分処理を実装したいです。

デプロイ時にエラーが出力され原因がよくわからない状況となります。

●auto.sql
insert into `fluid-emissary-216806.embulk_test.INPUT_TEST_003` (ID,NUM,STR,VARSTR,DT,TIME0,TIME6,TIME9)
select * from `fluid-emissary-216806.embulk_test.INPUT_TEST_001`
where  Num In 
(select Num from `fluid-emissary-216806.embulk_test.INPUT_TEST_002` A 
where not exists(select 1 from `fluid-emissary-216806.embulk_test.INPUT_TEST_003` B where A.NUM=B.NUM));

commit;

●auto.yaml
projectid: fluid-emissary-216806
datasetid: embulk_test
tableid: INPUT_TEST_003

●cron.yaml
cron:
- description: daily run
  url: /home/dwhtest01/cron
  schedule: every 1 mins
  timezone: Asia/Tokyo

●app.yaml
runtime: go
api_version: go1

handlers:
- url: /.*
  login: admin
  script: _go_app

env_variables:
  BUCKET_NAME: sample-bucket

●app.go
package sample

import (
    "cloud.google.com/go/bigquery"
    "cloud.google.com/go/storage"
    "fmt"
    "golang.org/x/net/context"
    "google.golang.org/api/iterator"
    "google.golang.org/appengine"
    "google.golang.org/appengine/taskqueue"
    yaml "gopkg.in/yaml.v2"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
)

type SqlConfig struct {
    ProjectID string
    DatasetID string
    TableID   string
    Query     string
}

func init() {
    http.HandleFunc("/home/dwhtest01/cron/task", taskEnqueueHandler)
    http.HandleFunc("/home/dwhtest01/cron/maketable", makeTableHandler)
}

func taskEnqueueHandler(w http.ResponseWriter, r *http.Request) {
    ctx := appengine.NewContext(r)

    sc, err := getSqlConfig(ctx)
    if err != nil {
        log.Fatalf("Cannot get sql config: %v", err)
    }

    //taskqueueにpush
    task := taskqueue.NewPOSTTask("/home/dwhtest01/cron/maketable", url.Values{
        "project_id": {sc.ProjectID},
        "dataset_id": {sc.DatasetID},
        "table_id":   {sc.TableID},
        "query":      {sc.Query},
    })
    taskqueue.Add(ctx, task, "default")
}

func getSqlConfig(ctx context.Context) (SqlConfig, error) {

    bucketname := ""
    if name, ok := os.LookupEnv("BUCKET_NAME"); ok {
        bucketname = name
    }

    sqlpath := "/home/dwhtest01/cron/auto.sql"
    confpath := "/home/dwhtest01/cron/auto.yaml"

    confbuf, err := getFileGCS(ctx, bucketname, confpath)
    if err != nil {
        log.Fatalf("Cannot read object: %v", err)
    }
    var sc SqlConfig
    if err := yaml.Unmarshal(confbuf, &sc); err != nil {
        log.Fatalf("file is not in yaml format: %v", err)
    }
    log.Printf("yaml format: %v", sc)

    querybuf, err := getFileGCS(ctx, bucketname, sqlpath)
    if err != nil {
        log.Fatalf("Cannot read object: %v", err)
    }
    sc.Query = string(querybuf)

    return sc, err
}

func makeTableHandler(w http.ResponseWriter, r *http.Request) {

    ctx := appengine.NewContext(r)
    project_id := r.FormValue("project_id")
    dataset_id := r.FormValue("dataset_id")
    table_id := r.FormValue("table_id")
    query := r.FormValue("query")
    // Creates a client
    client, err := bigquery.NewClient(ctx, project_id)
    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }
    ds := client.Dataset(dataset_id)

    // query settings & run
    q := client.Query(query)
    q.Dst = ds.Table(table_id)
    q.CreateDisposition = "CREATE_IF_NEEDED"
    q.WriteDisposition = "WRITE_TRUNCATE"

    job, err := q.Run(ctx)
    if err != nil {
        // TODO handle error
    }

    // Wait until async querying is done.
    status, err := job.Wait(ctx)
    if err != nil {
        // TODO handle error
    }
    if err := status.Err(); err != nil {
        // TODO handle error
    }

    it, err := job.Read(ctx)
}

func getFileGCS(ctx context.Context, bucketname string, filepath string) ([]byte, error) {
    client, err := storage.NewClient(ctx)
    if err != nil {
        log.Fatal(err)
    }

    rc, err := client.Bucket(bucketname).Object(filepath).NewReader(ctx)
    if err != nil {
        return nil, err
    }
    defer rc.Close()

    data, err := ioutil.ReadAll(rc)
    if err != nil {
        log.Fatal(err)
    }
    return data, err
}

※エラー

dwhtest01@cloudshell:~/cron (fluid-emissary-216806)$ gcloud app deploy app.yaml
ERROR: gcloud crashed (BadStatusLine): ''

If you would like to report this issue, please run the following command:
  gcloud feedback

To check gcloud for common problems, please run the following command:
  gcloud info --run-diagnostics


dwhtest01@cloudshell:~/cron (fluid-emissary-216806)$ gcloud info --run-diagnostics
Network diagnostic detects and fixes local network connection issues.
Checking network connection...done.
Reachability Check passed.
Network diagnostic passed (1/1 checks passed).

Property diagnostic detects issues that may be caused by properties.
Checking hidden properties...done.
ERROR: Hidden Property Check failed.
The following hidden properties have been set:
    [compute/gce_metadata_read_timeout_sec]
Properties files
    User: /tmp/tmp.xFf1q20vjB/configurations/config_cloudshell-397
    Installation: /google/google-cloud-sdk/properties

ERROR: Property diagnostic failed (0/1 checks passed).
dwhtest01@cloudshell:~/cron (fluid-emissary-216806)$

※2019/01/10

dwhtest01@cloudshell:~/cron (fluid-emissary-216806)$ gcloud app deploy app.yaml
ERROR: (gcloud.app.deploy) Staging command [/google/google-cloud-sdk/platform/google_appengine/go-app-stager /home/dwhtest01/cron/app.yaml /home/dwhtest01/cron /tmp/tmpd9Qyvc/tmpN8ZvfG] failed with return code [1].

------------------------------------ STDOUT ------------------------------------
------------------------------------ STDERR ------------------------------------
2019/01/10 08:46:45 staging for go1.9
2019/01/10 08:46:45 Staging Standard app: failed analyzing /home/dwhtest01/cron: cannot find package "google.golang.org/api/iterator" in any of:
        ($GOROOT not set)
        /home/dwhtest01/gopath/src/google.golang.org/api/iterator (from $GOPATH)
        /google/gopath/src/google.golang.org/api/iterator
GOPATH: /home/dwhtest01/gopath:/google/gopath
--------------------------------------------------------------------------------

dwhtest01@cloudshell:~/cron (fluid-emissary-216806)$

※2019/1/11 ■Go用Google API拡張モジュールインストール後にリトライ、再びエラー発生

$ go get -u github.com/googleapis/gax-go
$ go get -u google.golang.org/api/bigquery/v2
$ go get -u gopkg.in/yaml.v2
$ go get -u go.opencensus.io/trace
$ go get -u fmt
$ go get -u google.golang.org/api/iterator

dwhtest01@cloudshell:~/cron (fluid-emissary-216806)$ gcloud app deploy app.yaml
Services to deploy:

descriptor:      [/home/dwhtest01/cron/app.yaml]
source:          [/home/dwhtest01/cron]
target project:  [fluid-emissary-216806]
target service:  [default]
target version:  [20190111t105305]
target url:      [https://fluid-emissary-216806.appspot.com]


Do you want to continue (Y/n)?  y

Beginning deployment of service [default]...
??????????????????????????????????????????????????????????????
?? Uploading 1 file to Google Cloud Storage                 ??
??????????????????????????????????????????????????????????????
File upload done.
Updating service [default]...failed.
ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed:
/work_dir/app.go:50:17: undefined: os
2019/01/10 17:53:23 go-app-builder: build timing: 108×compile (24.98s total), 0×link (0s total)
2019/01/10 17:53:23 go-app-builder: failed running compile: exit status 2

dwhtest01@cloudshell:~/cron (fluid-emissary-216806)$

※※2019/1/21 ■app.goを編集し再実行

dwhtest01@cloudshell:~/cron (fluid-emissary-216806)$ gcloud app deploy app.yaml
Services to deploy:

descriptor:      [/home/dwhtest01/cron/app.yaml]
source:          [/home/dwhtest01/cron]
target project:  [fluid-emissary-216806]
target service:  [default]
target version:  [20190121t160337]
target url:      [https://fluid-emissary-216806.appspot.com]


Do you want to continue (Y/n)?  y

Beginning deployment of service [default]...
??????????????????????????????????????????????????????????????
?? Uploading 1 file to Google Cloud Storage                 ??
??????????????????????????????????????????????????????????????
File upload done.
Updating service [default]...failed.
ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed:
/work_dir/app.go:110:22: it declared and not used
2019/01/20 23:03:57 go-app-builder: build timing: 108×compile (24.657s total), 0×link (0s total)
2019/01/20 23:03:57 go-app-builder: failed running compile: exit status 2
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

以下のようなエラーが出てますね。

ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed:
/work_dir/app.go:50:17: undefined: os

osが定義されていないとのこと。

app.go内にて、
os.LookupEnv
を使っていますが、
osパッケージが、importされてないように見えます。

それが原因な気がします。

使用しているエディタにGoのプラグインなどを入れると、
こういったことに未然に対策できるかもしれません。

-- 追記(2019/01/21) --

app.goの中で、すでに他パッケージのimport処理は書かれていると思います。
以下の部分です。

import (
    "cloud.google.com/go/bigquery"
    "cloud.google.com/go/storage"
    "fmt"
    "golang.org/x/net/context"
    "google.golang.org/api/iterator"
    "google.golang.org/appengine"
    "google.golang.org/appengine/taskqueue"
    yaml "gopkg.in/yaml.v2"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
)

ここにosパッケージを追記します。

import (
    "cloud.google.com/go/bigquery"
    "cloud.google.com/go/storage"
    "fmt"
    "golang.org/x/net/context"
    "google.golang.org/api/iterator"
    "google.golang.org/appengine"
    "google.golang.org/appengine/taskqueue"
    yaml "gopkg.in/yaml.v2"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "os"
)

osパッケージに関しては以下の公式ドキュメントを参照。
https://golang.org/pkg/os/

標準パッケージですのでapp.go内への記載だけで大丈夫のはずです。

-- 追記(2019/01/23) --

エラーの内容は

ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed:
/work_dir/app.go:110:22: it declared and not used

となっていますね。
もし英語などで何を言っているかわからない、ということであれば、
「it declared and not used」を翻訳してみましょう。

翻訳結果

「宣言されていて使われていない」とでてます。

実際にapp.goの110行目付近を見ると、

    }
    if err := status.Err(); err != nil {
        // TODO handle error
    }

    it, err := job.Read(ctx)
}

宣言されているitという変数がどこにも使われていないことがわかります。
これはGoではエラーになります。
Goでは宣言した変数は使用しなければいけません。
使わないなら宣言してはいけない決まりです。

なので、エラーを消すには、

・itという変数を使う
・使わないならエラーの出ているこの行を消す

のどちらかの対応になるかと思われます。

補足ですが、こういったエラーは、エディタの機能を使うと、実行前に判明させることができます。
たとえばVisual Studio CodeというエディタにGoのプラグインを入れると、
以下のように事前にエラー箇所をハイライトしてくれます。

visual studio code

興味があれば調べてみてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/21 16:08

    ご回答ありがとうございます。

    app.goを改修し、再実行しました。結果を質問事項に追記しました。
    また別のエラーが出力され原因調査中となります。

    キャンセル

  • 2019/01/23 15:21

    回答に追記しました。

    キャンセル

  • 2019/02/07 14:07

    ご回答有難うございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る