-
Notifications
You must be signed in to change notification settings - Fork 1.3k
WIP: Uses docker to build Go and packages #750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Uses docker to build Go and packages #750
Conversation
This allows us to quickly upgrade (or test) go versions. It also simplifies the current process that downloads the go binaries and messing with the GOPATH. We build in the docker/ folder to avoid sending the entire directory (vendor/ included) to the docker context. That can add some unneccesary time to the build since we're not copying anything.
|
@shlomi-noach here's a first look at the updates to the build process. This is still WIP. My next steps are to convert |
.gitignore
Outdated
| /libexec/ | ||
| /.vendor/ | ||
| /.cache | ||
| /build |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the output of the build artifacts. Now everything ends up in ./build:
% find ./build
./build
./build/dist
./build/dist/gh-ost-binary-osx-20190531141809.tar.gz
./build/dist/gh-ost_1.0.48_amd64.deb
./build/dist/gh-ost-1.0.48-1.x86_64.rpm
./build/dist/gh-ost-binary-linux-20190531141809.tar.gz
./build/bin
./build/bin/gh-ost-linux-amd64
./build/bin/gh-ost-darwin-amd64Totally get it if you don't like this. I thought I'd offer it up first though. That way we're not splitting the ./bin and /tmp/gh-ost-release directories.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
build/ makes perfect sense! Let's add /build/ to .gitignore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will change!
For my own education, how does git treat /build and /build/ differently?
| exit 1 | ||
| if [ "$goos" == "darwin" ]; then | ||
| # specify cross compiler | ||
| envs="$envs -e CC=x86_64h-apple-darwin14-cc" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the magic of dockercore/golang-cross. By specifying the CC that's already bundled, we can cross compile for darwin.
I'm 90% sure this is fine for the release. I copied this over to a mac machine I have and verified that I can run at least --version. (I might eat my hat once the localtests, but I'm pretty confident this will be okay)
| && fpm -v "${RELEASE_VERSION}" --epoch 1 -f -s dir -n gh-ost -m "shlomi-noach <[email protected]>" --description "GitHub'"'"'s Online Schema Migrations for MySQL " --url "https://${PACKAGE_PATH}" --vendor "GitHub" --license "Apache 2.0" -C /gh-ost --prefix=/ -t rpm . \ | ||
| && cp *.rpm ${OUTPUT_PATH}' | ||
|
|
||
| $fpm_cmd bash -c 'mkdir -p /gh-ost/usr/bin \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can test out the output of any of these in docker too:
% docker run --rm -it -v $(pwd):/ghost ubuntu dpkg -c /ghost/build/dist/gh-ost_1.0.48_amd64.deb
drwxrwxrwx 0/0 0 2019-05-31 18:18 ./
drwxr-xr-x 0/0 0 2019-05-31 18:18 ./usr/
drwxr-xr-x 0/0 0 2019-05-31 18:18 ./usr/share/
drwxr-xr-x 0/0 0 2019-05-31 18:18 ./usr/share/doc/
drwxr-xr-x 0/0 0 2019-05-31 18:18 ./usr/share/doc/gh-ost/
-rw-r--r-- 0/0 155 2019-05-31 18:18 ./usr/share/doc/gh-ost/changelog.gz
drwxr-xr-x 0/0 0 2019-05-31 18:18 ./usr/bin/
-rwxr-xr-x 0/0 10029736 2019-05-31 18:18 ./usr/bin/gh-ost
% docker run --rm -it -v $(pwd):/ghost fedora rpm -qlp /ghost/build/dist/gh-ost-1.0.48-1.x86_64.rpm
/usr/bin/gh-ost
build.sh
Outdated
| ldflags="-X main.AppVersion=${RELEASE_VERSION}" | ||
| function distro_packages() { | ||
| echo "Creating Distro full packages" | ||
| docker build -t gh-ost/fpm -f docker/Dockerfile.fpm docker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's true that this will build the fpm image every time, but the docker layer cache will make this super fast on repeated runs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point I will want to get rid of fpm.
| script/build | ||
|
|
||
| cd .gopath/src/github.com/github/gh-ost | ||
| if [ "$1" != "fast" ]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you just want to run gofmt and test, you can run this as ./script/cibuild fast.
However, see my top-level comment. Something feels off that this is separate from build.sh. I'm thinking that this code should just be combined into one script at this point.
| RELEASE_VERSION=$(cat RELEASE_VERSION) | ||
| fi | ||
|
|
||
| DGO="docker run -u $(id -u):$(id -g) --rm \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-u $(id -u):$(id -g) I do this so that the user/group permissions of the files generated stay the host user's. Otherwise it becomes root:root and a permissions pain.
|
|
||
| cd .gopath/src/github.com/github/gh-ost | ||
| go "$@" | ||
| $DGO go "$@" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still felt somewhat useful. Shouldn't be necessary if you have go installed locally, but 🤷♂️
| @@ -1,13 +0,0 @@ | |||
| #!/bin/bash | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure where this script runs. This is equivalent to ./script/go test ./go/... (or ./script/go test -count 1 ./go/... if you want to disable test caching)
| envs="-e GOOS=$goos \ | ||
| -e GOARCH=amd64 \ | ||
| -e CGO_ENABLED=1 \ | ||
| -e GOCACHE=/go/src/${PACKAGE_PATH}/.cache \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is necessary since we don't run these commands as root inside the container (so we can't write to /).
Maintaining these files in the host directory does have a benefit of repeated builds being faster if you keep around the ./.cache folder.
| osshort=$goos | ||
|
|
||
| envs="-e GOOS=$goos \ | ||
| -e GOARCH=amd64 \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically, nothing is stopping this from extending to also offering 386 or windows at this point. But I didn't go that far.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an open issue+PR for supporting Raspberry Pi. Truly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hah. I haven't tried compiling for ARM but it doesn't look that difficult https://www.thepolyglotdeveloper.com/2017/04/cross-compiling-golang-applications-raspberry-pi/
I imagine ARM is going to get more popular with the Intel NUC crowd and the rumors MacBook Pro will ditch Intel and move to it.
Only build distributions when -d is passed
|
@shlomi-noach Ok this is getting very close to a full PR. However in this process I started running into the intermittent tests that I mentioned in #738. So I noodled on it a bit. At first I started with a similar tactic you already had of starting a single server for the version and running all tests against it. Then after seeing the intermittent failures, I decided to start/kill a docker container for each test. It's slower but safer because we don't leave any remnants of a previous test on a fresh container boot. But even after that I'm still seeing errors crop up. I thought perhaps this was a v1.12.x only issue, but even changing the GO_VERSION file back to 1.9.2. But I still saw errors. I wonder if perhaps there's a default variable with the dbdeployer mysql servers that isn't lenient enough that we're tripping over. Or maybe something with the default values we're passing gh-ost. I'm not sure. I haven't dug deeper yet, but here are two snippets from intermittent failures: https://gist.github.com/zmoazeni/4ea85d89fa07280f6fc5c41c0e2020c0 Note: they are not the same tests that regularly fail. Seems to happen all over place. |
|
@zmoazeni thank you for your work thus far! I'm not sure either about these intermittent replicaiton-not-running failures. I've seen these from time to time and I'm just not sure why they keep coming up. OK, some news: at a strange timing coincidence, we (GitHub) are to now move all our internal builds to run on Docker. All our This makes me both grateful for the work you've done, as well as uncomfortable that if you continue doing it, you'll be contributing your volunteer work on something we now need to do internally on our pay job. This is all new, so I don't have much insight into the work yet, but please consider this as heads up -- and for your consideration ❤️ |
|
Ah! Thanks for letting me know. I really appreciate that. What I'll do then is back off this initiative until you get more information and let you push it forward. I'll leave this PR up so feel free to pick-n-choose what makes sense for that. And if you have any questions about why I did something a certain way, definitely feel free to ask. I was also wondering if we should do this on orchestrator too, but GH's internal build changes will require that too. I'll probably poke at these intermittent failures with this code, maybe I can find a reliable way to reproduce it on a single test. I feel like it's pretty close. My first intuition is that this isn't gh-ost code itself running into an issue. With the "ERROR replication not running; Slave_IO_Running=No, Slave_SQL_Running=No", I might try turning on the general log and inspecting the MySQL container when the test fails to see what it ran up to that point to break replication. |
There are some legitimate retries that can occur during testing. Namely `logic.ExpectProcess()` (in `applier.go`). We'll look for a process that does exist, but timing-wise doesn't have the `state` or `info` columns populated. Without this, the test will fail abruptly.
|
Closing unmerged. I have since moved my focus elsewhere. |
This is related to the conversation at #740
Note: this is a draft PR to request feedback
I still need to convert
script/cibuild-gh-ost-replica-testsandlocaltests/test.sh.Overall this works really well. I have made a few changes to the output directories, which I imagine you'll have opinions on.
./build.shstill builds the binaries and deb/rpm/tarball packages.I added a new option for
./script/cibuildto optionally skip building everything. Though I do wonder ifbuild.shshould be pushed into./script/buildand./script/cibuildeither be deleted (and folded into the build script). I'm not sure, something feels off organizationally with those behaviors.