inertia deploy [REMOTE] (up, down, status, reset) and authentication#30
Conversation
| err = CheckForGit() | ||
| if err != nil { | ||
| // Clone project | ||
| remoteURL := "" // TODO |
There was a problem hiding this comment.
Is this in config somewhere?
There was a problem hiding this comment.
Try using getRepo and pull out the repo.Remotes() list. The information you want should be in there.
There was a problem hiding this comment.
I think this particular case is for when CheckForGit() fails and I need to do a clone - wouldn't that mean there's either no repository at all, or that the repository has no remotes to do repo.Remotes() on?
There was a problem hiding this comment.
Why don't we ship that info in the /up body? 😬
| // downHandler tries to bring the project down. | ||
| // deploy does git pull, docker-compose build, docker-compose up | ||
| func deploy(repo *git.Repository) error { | ||
| cfg, err := GetProjectConfigFromDisk() |
There was a problem hiding this comment.
This seems to be booting up the daemon? If this function is called, it's the daemon that called it 😂 Maybe this is just WIP.
| } | ||
|
|
||
| w.Header().Set("Content-Type", "text/html") | ||
| w.WriteHeader(http.StatusOK) |
There was a problem hiding this comment.
201 - Created might be a nice return code here.
There was a problem hiding this comment.
This is for shut down 😛 changed up to return created
| http.Error(w, err.Error(), 501) | ||
| } | ||
| if len(containers) == 1 { | ||
| http.Error(w, "No Docker containers are currently active", 501) |
There was a problem hiding this comment.
Nice! Maybe a 412 - Precondition Failed works here.
| } | ||
|
|
||
| // Take project offline | ||
| daemonCmd, err := Asset("cmd/bootstrap/project-down.sh") |
There was a problem hiding this comment.
Don't know if it's necessary to take the daemon down - if we do, they have to re-bootstrap the HTTP communication to continue using the server.
There was a problem hiding this comment.
The script (project-down) looks like this:
DAEMON_NAME=inertia-daemon
docker rm $(docker ps -a -q | grep -v "$DAEMON_NAME")From what I understand this should leave the daemon alone right?
| } | ||
|
|
||
| repo, err := git.NewFilesystemRepository(gitFolder) | ||
| repo, err := git.PlainOpen(gitFolder) |
There was a problem hiding this comment.
👍 Could not make this function work - silly git package.
| @@ -0,0 +1,4 @@ | |||
| # Script for taking down all Docker containers except the Inertia daemon | |||
There was a problem hiding this comment.
Any reason you wouldn't use the golang docker client to handle this?
chadlagore
left a comment
There was a problem hiding this comment.
Couple drive-by comments. Haven’t read the whole thing yet. But looking great! 🤩
I’d really like to avoid using bash to bring up the project! The bash work should be done once the server is bootstrapped. Is there a reason we can’t play with containers only using the go docker client?
| sudo docker run -d \ | ||
| -p "$PORT":8081 \ | ||
| -v /var/run/docker.sock:/var/run/docker.sock \ | ||
| -v /usr/bin/docker:/usr/bin/docker \ |
There was a problem hiding this comment.
As far as I can tell, there’s no guarantee this binary (installed for the host) works inside of the container (the container likely runs a different OS).
There was a problem hiding this comment.
Haven’t had the opportunity to test that but I don’t see any indication that the container runs a different OS to the host with the way we’re starting the daemon up here, or maybe I jut don’t understand docker 😅 I’ll look into it
There was a problem hiding this comment.
Looks like the container should be the same as the host:
Docker originally used LinuX Containers (LXC), but later switched to runC (formerly known as libcontainer), which runs in the same operating system as its host. This allows it to share a lot of the host operating system resources.
There was a problem hiding this comment.
The first comment to that thread:
Ken, in some places you conflate the OS with the kernel. All containers on a host run under the same kernel, but the rest of the OS files can be unique per container.
One host kernel is orchestrating our container processes here. But each container we run via the host may use a different OS. Here is the example in inertia's case (say we've just allocated a gcloud vps with ubuntu installed on it):
- We boostrap the VPS (installing docker via this).
- It figures out what operating system its running on and installs
dockerfor that OS. - You mount that binary into the daemon (running Alpine Linux).
Theres no guarantee that the binary is executable on Alpine Linux! 🙈
Heres a working example (pretending the host is running macOS 😂):
~/git/tmp master ✔
▶ cp `which docker` .
~/git/tmp master ✗
▶ docker run -it -v `pwd`:/home alpine
/ $ ls
bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var
/ $ cd home
/home $ ls
docker
/home $ ./docker
./docker: line 1: ������: not found
./docker: line 2: @��__gosymtab__TEXT������__gopclntab__TEXT���5�A���__cstring__TEXT�t�l�t�__const__TEXTP: not found
./docker: line 2: ��P: not found
./docker: line 2: �__unwind_info__TEXT
���
��__eh_frame__TEXT��-��h__DATA��: not found
./docker: line 2: ���,: not found
./docker: line 2: �H__PAGEZER__TEXT����
__text__TEXT#n�#�__stubs__TEXTn��n�__stub_helper__TEXTD�D��__rodata__TEXT�__typelink__TEXT: not found
./docker: line 3: ���: not found
./docker: line 4: syntax error: unexpected word (expecting ")")
/home $There was a problem hiding this comment.
Hang on, I've been mounting my local (macOS) installation into the daemon, should that not be working?
There was a problem hiding this comment.
You don't appear to be using the docker binary anywhere in this PR. That's probably why it works.
The go docker library does everything you need, it never has to access a docker binary in a file somewhere, all it needs is to look at /var/run/docker.sock and find a socket there 😄 - which we provide with -v /var/run/docker.sock:/var/run/docker.sock.
I think we can just remove the -v /usr/bin/docker:/usr/bin/docker here. It's not doing anything and it would break if we tried to actually use it somewhere.
There was a problem hiding this comment.
Oh yeah you're right, was using the docker binary for back when I was still using the shell script - not needed anymore
Speaking of which running that project-up.sh script was working before and I think that used the mounted docker binary?
There was a problem hiding this comment.
Not sure! It may work sporadically, if we happen to use a host compatible with Alpine - but in general we can't assume that a binary built from source in one OS will work inside other OS.
| log.Println(fmt.Sprintf("Ref: %s", event.GetRef())) | ||
|
|
||
| // Clone repository if not available | ||
| err := checkForGit(projectDirectory) |
| } | ||
|
|
||
| w.Header().Set("Content-Type", "text/html") | ||
| w.WriteHeader(http.StatusOK) |
|
Thanks @chadlagore ! The main problem is Note I'm mounting all of Tried mounting There is a docker client for docker-compose in Go that I wanted to try but believe it or not, it currently has a dependency clash with the normal go docker client resulting from a case change (capital S vs lowercase s in something) 😠 I didn’t look too much into it because I thought there would still be the issue about the lack of docker-compose installation |
|
@chadlagore got rid of the |
| return err | ||
| } | ||
|
|
||
| println(token) |
|
Forgot in the commit message but 40ba979 also compares the remote URL of requests (e.g. from |
Hotfix the config writer; unexport initialization functions
|
Thanks @chadlagore ! |
| sudo chmod +x $DOCKER_COMPOSE_DEST | ||
|
|
||
| # Try using. | ||
| docker-compose --version |
| ssh-keygen -f $ID_DESTINATION -t rsa -N '' | ||
| fi | ||
|
|
||
| ssh-keyscan github.com >> ~/.ssh/known_hosts |
| println("It is recommended that you DO NOT commit this folder in source") | ||
| println("control since it will be used to store sensitive information.") | ||
| println("\nYou can now use 'inertia remote add' to connect your remote") | ||
| println("VPS instance.") |
|
|
||
| assert.Equal(t, sshURL, getSSHRemoteURL(httpsURL)) | ||
| assert.Equal(t, sshURL, getSSHRemoteURL(sshURL)) | ||
| } |
| sudo docker run --rm \ | ||
| -v $HOME:/app/host \ | ||
| -e SSH_KNOWN_HOSTS=$SSH_KNOWN_HOSTS \ | ||
| -e SSH_KNOWN_HOSTS='/app/host/.ssh/known_hosts' \ |
chadlagore
left a comment
There was a problem hiding this comment.
+1 best code 🏅
Deployed my project:
~/git/inertia-deploy-test master ✗ 6m ◒
▶ ./inertia deploy gcloud up
(Status code 201) Project up
~/git/inertia-deploy-test master ✗ 6m ◒
▶ ./inertia deploy gcloud status
(Status code 200) git@github.com:chadlagore/inertia-deploy-test.git
b3bc12a2f816f727be550dd05759144a0abf0ffa refs/heads/master
Active containers:
python (/project_webdev_1)Looks totally awesome:
For the record, we keep getting this error:
▶ ./inertia deploy gcloud up
(Status code 500) Unknown response from daemon: Error response from daemon: Conflict. The container name "/docker-compose" is already in use by container "9e223216098ede70e100ea8de80e472943aa6e7afcde91c746790951d679e22f". You have to remove (or rename) that container to be able to reuse that name.And we're not in love with this chunk:
// Check if build failed abruptly
time.Sleep(2 * time.Second)
_, err = getActiveContainers(cli)
if err != nil {
err := killActiveContainers(cli)
return errors.New("Docker-compose failed: " + err.Error())
}And we know it breaks when the project expects its images to have docker-compose canonical names.
But this thing works for straightforward docker-compose projects 👍

⌛ Status: ready for review
🎟️ Ticket(s): Closes #27, closes #32, closes #33, closes #38
👷 Changes
inertia deploy [REMOTE] down:inertia deploy [REMOTE] up:postrequestdeploy()projectinertia deploy [REMOTE] status:inertia deploy [REMOTE] reset:authentication using github token (Chad/#38 authorization #39)
Push events to Daemon:
deploy()projectdeploy():docker-composeusing similar docker-in-docker workaround todaemon-upA bunch of minor typo fixes, refactored some shared helper functions to
util.goTodo
updocker-compose🔦 Testing Instructions
This next thing basically
bootstraps without pulling master inertia:If needed, do
docker rm -f $(docker ps -a -q)Now you can:
For example, with Sleuth: