-
Notifications
You must be signed in to change notification settings - Fork 25
Trigger server #39
base: master
Are you sure you want to change the base?
Trigger server #39
Conversation
We'll deploy it with a on-start generated shared secret, which can be retrieved from the master node. It'll be packaged as a systemd .service file so that it runs on startup, etc. Packaged as RPM/DEB via FPM Tests now run successfully with this version.
RPM/DEB build artifacts:
|
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.
In this form the server still suffers the problem that it's going to run whatever ipfs/ipfs-cluster docker container there is.
Instead, it should run the tests with the code that it's being currently being tested (in a PR).
As I pointed out somewhere else, that means that a container needs to be built, published, and the deployment file needs to be pointed to it.
@@ -0,0 +1,11 @@ | |||
To build RPM/DEB |
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 guess this needs more docs. What is trigger-server, how is it built, how is it deployed, where etc.
ipfs-cluster/trigger-server/build.sh
Outdated
@@ -0,0 +1,16 @@ | |||
if [ -z $1 ] |
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.
#!/bin/bash
set -e
set -x
ipfs-cluster/trigger-server/build.sh
Outdated
exit 1 | ||
fi | ||
VERSION=$1 | ||
if [[ ! $(docker images | grep fpm) ]] |
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.
Improve this grep so it doesn't have the chance to match something unrelated (`docker images --format '{{ .Repository }}' ...)
ipfs-cluster/trigger-server/build.sh
Outdated
docker build -t="fpm" github.com/jordansissel/fpm/ | ||
fi | ||
go build triggerserver.go | ||
docker run -v $(pwd):/data --rm fpm /bin/sh -c "cd /data && fpm -s dir -t rpm -n triggerserver -v $VERSION -p /data/ --deb-no-default-config-files triggerserver=/usr/bin/ triggerserver.service=/usr/lib/systemd/system/" |
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.
make the image name a variable at the top
ipfs-cluster/trigger-server/build.sh
Outdated
fi | ||
go build triggerserver.go | ||
docker run -v $(pwd):/data --rm fpm /bin/sh -c "cd /data && fpm -s dir -t rpm -n triggerserver -v $VERSION -p /data/ --deb-no-default-config-files triggerserver=/usr/bin/ triggerserver.service=/usr/lib/systemd/system/" | ||
docker run -v $(pwd):/data --rm fpm /bin/sh -c "cd /data && fpm -s dir -t deb -n triggerserver -v $VERSION -p /data/ --deb-no-default-config-files triggerserver=/usr/bin/ triggerserver.service=/lib/systemd/system/" |
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 is customary to add custom units to /etc/systemd/system/ and leave /lib/systemd for the system.
// This command takes a while, so we'll hang out here while it runs | ||
cmd := exec.Command("bash", "runner.sh", RUNNER_NUM_NODES, RUNNER_NUM_PINS) | ||
cmd.Dir = RUNNER_PATH | ||
out, err := cmd.CombinedOutput() |
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.
find a way to stream the output of the command as it happens. Seems https://golang.org/pkg/os/exec/#Cmd.StdinPipe might help. May want to run with a command context so you can cancel the command if you cannot write anymore.
Also, should make sure the deployment is cleaned up from the cluster after the tests have run so they can run again without finding anything dirty.
} | ||
|
||
func main() { | ||
secret_bytes, readErr := ioutil.ReadFile(CONFIG_PATH) |
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.
since the config file needs several sections, probably json is a good format.
secret_bytes, readErr := ioutil.ReadFile(CONFIG_PATH) | ||
if readErr != nil { | ||
log.Printf("Missing secret configuration in %s. We'll generate one for you...\n", CONFIG_PATH) | ||
rand.Seed(time.Now().UnixNano()) |
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.
customary to initialize seeds in init(). Might as well use a proper random source from crypto
package. Just need to read enough bytes into a buffer and SHA it for example.
} | ||
} | ||
secret = string(secret_bytes) | ||
log.Printf("Starting with secret as %s on port %d\n", secret, PORT) |
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.
better not log secrets
https://github.com/ipfs/kubernetes-ipfs/ | ||
`) | ||
}) | ||
log.Println(http.ListenAndServe(":" + strconv.FormatInt(PORT, 10), nil)) |
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.
fmt.Sprintf("%d", PORT)
. Saves one import.
Major changes: - Output is now streamed from the daemon rather than being dumped at the end. - At the end of the run, data is dumped to IPFS and you are provided an IFPS link to the output. - `golint` now passes sucessfully - The server now responds with 401 to unauthorized users - User can now specify what they want to run - Config is now in JSON format - Config is generated as JSON on first load
@hsanjuan, will you check my recent changes? |
@@ -1,3 +1,9 @@ | |||
# What is trigger server | |||
|
|||
The trigger server's purpose is defined in ipfs/ipfs-cluster/issues/244. The goal is to create an endpoint |
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.
That issue is very long, and deals with other things. In any case, the user should not have to look up an issue in a different repository to find out what the project does, when reading's the project readme.
The trigger server's purpose is defined in ipfs/ipfs-cluster/issues/244. The goal is to create an endpoint | ||
which can be triggered remotely and automated to run the tests, obtaining their results. | ||
|
||
|
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.
Explain that it runs in the kubernetes master? Explain the authentication mechanism and how to set it up? Explain how to put it there after you have the packages? explain that it includes a systemd unit file? how to obtain credentials or where to reach out if needed...
The trigger server's purpose is defined in ipfs/ipfs-cluster/issues/244. The goal is to create an endpoint | ||
which can be triggered remotely and automated to run the tests, obtaining their results. | ||
|
||
|
||
To build RPM/DEB | ||
--- | ||
|
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.
As an additional note, we don't need new issues for every commit addressing issues in a PR. Commit messages should be more descriptive than this, but it's fine too if you just write WIP
, and at the end of the review process squash it all together in a single commit, but in any case an additional issue is not needed.
// This command takes a while, so we'll hang out here while it runs | ||
cmd := exec.Command("bash", "-c", fmt.Sprintf("%s%s %s", config.RunnerPath, config.Runner, config.RunnerArgs)) | ||
cmd.Dir = config.RunnerPath | ||
pipeReader, pipeWriter := io.Pipe() |
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.
Perhaps implement a custom io.Writer. The Write
method in it just writes the bytes to both the response writer and your out
buffer. That way you don't need a go-routine on the side reading from one reader and writing somewhere else.
|
||
func init() { | ||
rand.Seed(time.Now().UnixNano()) | ||
configFile, readErr := ioutil.ReadFile(configPath) |
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.
configuration handling to ->main()
, but do create functions for it.. DefaultConfig()
, ReadConfig()
, WriteConfig()
.. they can live in config.go
cwd, _ := os.Getwd() | ||
config.Secret = randLetters(30) | ||
config.Port = 8082 | ||
config.RunnerPath = cwd |
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.
probably need a way to specify several runners for several projects
fmt.Fprintf(rw, `Kubernetes-IPFS Trigger Server | ||
https://github.com/ipfs/kubernetes-ipfs/ | ||
`) | ||
json.Unmarshal(configFile, &config) |
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.
error check
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.
and I think golint would ask you to return from the if
and not have an else
clause.
Tests now run successfully with this version.
ipfs-cluster/ipfs-cluster#244