Why cant go-app-builder find local imports? - google-app-engine

I am currently writing an application in Go and trying to deploy multiple services. I am running the following command : gcloud app deploy dispatch.yaml app/app.yaml mod1/mod1.yaml.
The app.yaml file corresponds to the default service and is successfully deployed however the service mod1 returns this error:
ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed: 2016/07/22 18:17:14 go-app-builder: build timing: 1×compile (53ms total), 0×link (0 total) 2016/07/22 18:17:14 go-app-builder: failed running compile: exit status 1
mod1.go:4: can't find import: "myapp/mod1/web_console"
My-Macbook: myapp$ gcloud app deploy dispatch.yaml app/app.yaml mod1/mod1.yaml
My file structure is as follows:
/My_Project
/src
/myapp
/app
app.go
app.yaml
/mod1
mod1.go
mod1.yaml
/web_console
web_console.go
mod1.go :
package mod1
import (
"myapp/mod1/web_console"
)
func init() {
// Initializing Web Console establishes connection
// to the database and also creates routes
var wc *web_console.WebConsole
wc = web_console.NewWebConsole(true)
wc.Configure()
}
mod1.yaml :
module: mod1
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
app.yaml :
module: default
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
Thanks for taking the time to help!

Each GAE service/module is standalone and can not access anything outside the service/module dir which:
is the directory where the .yaml file exists
is what's uploaded during deployment
is considered the "root" directory for that service/module, everything is relative to it
In your particular case you need to make sure no service/module makes references to the parent myapp dir (which is nothing but an organisational placeholder for the app stuff, relevant on your side but with no actual presence on GAE). I believe your mod1.go import should looks like this:
package mod1
import (
"web_console"
)
But take it with a grain of salt, I'm not actually familiar with go.

It seems like I was using the wrong tool to deploy. I ran the command with goapp deploy app/app.yaml mod1/mod1.yaml and was able to successfully deploy the services without issue.

Related

How/where does Google App Engine cache YAML (changing `script`)?

Originally I had this in my app.yaml:
runtime: python39
- url: .*
script: main.app
I changed the script filename to gae.py and so updated app.yaml to thus:
runtime: python39
- url: .*
script: gae.app
The new version no longer starts up:
ModuleNotFoundError: No module named 'main'
I have tried changing the url but it's still trying to use a now-non-existent main.py to load the WSGI application. When I view the source of the version I see the correct app.yaml and file structure; I don't see main mentioned anywhere.
Any ideas?
The problem is not caching but rather that script is no longer used (and is ignored) in the Python 3 world of Google App Engine standard:
script: Optional. Specifies that requests to the specific handler should target your app. The only accepted value for the script element is auto because all traffic is served using the entrypoint command. In order to use static handlers, at least one of your handlers must contain the line script: auto or define an entrypoint element to deploy successfully.
(https://cloud.google.com/appengine/docs/standard/python3/config/appref#handlers_element)
The fix is to override entrypoint which defaults to:
/bin/sh -c exec gunicorn main:app --workers 2 -c /config/gunicorn.py
(https://cloud.google.com/appengine/docs/standard/python3/runtime#application_startup)

How to pass -ldflags to GAE build?

I have an HTTP service written in Go. Inside main.go I have a global version string.
package main
var version string
Locally, I build using -ldflags "-X main.version=$VERSION where $VERSION is determined by the shell environment, like so:
VERSION=v0.16.0 go build ./cmd/app -ldflags "-X main.version=$VERSION
I've recently decided to trial Google App Engine and started with a basic YAML file:
runtime: go111
handlers:
- url: /.*
script: auto
What can I set in the YAML file in order to instruct GAE to build with the equivalent ldflags to bake in my version string?
I should also mention I use go modules with GO111MODULE=on locally when building.
You can't do it with you app.yaml file.
However, you can use Cloud build to build and deploy your app to App Engine.
In your cloudbuild.yaml you can add a line to the build step
args: ['build', '-a', '-installsuffix', 'cgo', '-ldflags', '''-w''', '-o', 'main', './main.go']

App Engine deploy with Go libraries

I'm new on Google App Engine. And, I'm getting an issue that I can't solve.
I've a very simple app (developped in Go) like this :
main/
| model/
| | user.go
| main.go
| app.yaml
These are the imports of main.go :
import (
"github.com/julienschmidt/httprouter"
"log"
"net/http"
)
My code works well when I run it locally.
But, when I try to publish it on my Google App Engine instance, I receive this error :
$ gcloud app deploy
You are about to deploy the following services:
- <MY_APP_ENGINE_URL> (from [<MY_LOCAL_YAML_PATH>])
Deploying to URL: [<MY_APP_ENGINE_URL>]
Do you want to continue (Y/n)? Y
Beginning deployment of service [default]...
Some files were skipped. Pass `--verbosity=info` to see which ones.
You may also view the gcloud log file, found at
[<LOCAL_APP_ENGINE_LOG>].
File upload done.
Updating service [default]...failed.
ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed:
2017/05/27 14:48:24 go-app-builder: build timing: 5×compile (301ms total), 0×link (0s total)
2017/05/27 14:48:24 go-app-builder: failed running compile: exit status 2
main.go:4: can't find import: "github.com/julienschmidt/httprouter"
What did I do wrong ?
EDIT :
This is the content of my app.yaml file :
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
App Engine environment doesn't contain your dependencies, you can add an script to do a go get ... for each one but it's too hacky and Go has a solution for that, we can save our dependencies in a vendor folder on the root of our project.
Quick solution:
# Instal godep:
go get -v -u github.com/tools/godep
cd your/project/path
godep save
Now try to deploy again, you'll see a vendor folder in your project, don't remove it and add it to your git source, that folder contains all your third party dependencies like your httprouter (it's my favorite :) )
Note You can use other tools to save your dependencies
I haven't used the gcloud tool, but back in the day when goapp was the tool you had to create github.com/julienschmidt/httprouter (with the lib's source in it, of course) directly under you'r main and then deploy.
AFAIK the App Engine's go version is currently 1.6 which means that while the vendoring is on by default, it can be switched off - perhaps thats the case and thats why #Yandry Pozo's suggestion doesn't work.

AppEngine "appengine" package always fails with "syscall" or "unsafe" import failure

Using the AppEngine 1.9.40 SDK, I can't even import the "appengine" package.
app.yaml:
application: testapp
version: 1
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
Go code:
package main
import (
"google.golang.org/appengine"
)
func init() {
appengine.IsDevAppServer()
}
func main() {
// This is only here because go-get needs on it.
}
Command-line:
$ GOPATH=$(pwd) goapp serve
Error:
2016/08/01 23:58:02 go-app-builder: Failed parsing input: parser: bad import "unsafe" in src/golang.org/x/net/icmp/helper.go
What can be done to get past this?
All code in the application directory tree (the root is the directory containing app.yaml) is compiled in to the app. Appengine rejects code that uses "unsafe".
The fix is to move the offending code out of the application directory tree. Here's one possible way to arrange the code:
$GOPATH
src
testapp
app.yaml
app.go
golang.org
x
net
icmp
... and so on
It's also possible that using package main will cause some trouble. If the above does not work, change the package name.
Appengine apps are not go-gettable. Don't struggle to make them so.
There's more discussion on this topic at https://github.com/golang/gddo/issues/428.

Project Directory Does Not Contain app.yaml

I'm following the instructions here https://console.developers.google.com/start/appengine
I've downloaded and unzipped the project file from that page - it's the python and flask one. When I get to the instruction dev_appserver.py appending-try-python-flask it gives the error.
google.appengine.tools.devappserver2.errors.AppConfigNotFoundError: "." is a directory but does not contain app.yaml or app.yml
It most certainly does contain an app.yaml file. It looks like this.
application: hello-flask-app-engine
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: .*
script: main.app
libraries:
- name: jinja2
version: "2.6"
- name: markupsafe
version: "0.15"
Unlike this post Uploading a static project to google app engines mine doesn't have any skip files lines to delete.
There is a README.md that mostly follows the Google Dev web page, except that instead of downloading the project from that page it instructs to git clone https://github.com/GoogleCloudPlatform/appengine-python-flask-skeleton.git and that doesn't exactly match the zip file I downloaded.
The requirement.txt file says Run 'pip install -r requirements.txt -t lib/' but Windows 7 says pip is not a recognized command.
Is my app.yaml not correct? Why would it say it doesn't exist?
Simply closing the command prompt window and reopening it made it work. I don't know how or why.
You may be mis-typing appengine-try-python-flask (the real name) as appending-try-python-flask (which is what you show in your question).
If that's not the case, can you please show the effects of dir appengine-try-python-flask and dir appending-try-python-flask from the directory (AKA folder) you're now trying to run dev_appserver.py from?
probably you use py-charm, you need to add to configuration in line 'Working directory' the path of project like: C:\Users\user\Desktop\projects\water
It's repose to work

Resources