source tmate binary from docker image
This commit is contained in:
@@ -53,6 +53,12 @@ type Resources struct {
|
||||
ShmSize int64
|
||||
}
|
||||
|
||||
// Tmate defines tmate settings.
|
||||
type Tmate struct {
|
||||
Image string
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
// Compiler compiles the Yaml configuration file to an
|
||||
// intermediate representation optimized for simple execution.
|
||||
type Compiler struct {
|
||||
@@ -92,6 +98,10 @@ type Compiler struct {
|
||||
// applies to pipeline containers.
|
||||
Resources Resources
|
||||
|
||||
// Tate provides global configration options for tmate
|
||||
// live debugging.
|
||||
Tmate Tmate
|
||||
|
||||
// Secret returns a named secret value that can be injected
|
||||
// into the pipeline step.
|
||||
Secret secret.Provider
|
||||
@@ -307,6 +317,38 @@ func (c *Compiler) Compile(ctx context.Context, args runtime.CompilerArgs) runti
|
||||
}
|
||||
}
|
||||
|
||||
// create internal steps if build running in debug mode
|
||||
if c.Tmate.Enabled && args.Build.Debug && pipeline.Platform.OS != "windows" {
|
||||
// first we need to add an internal setup step to the pipeline
|
||||
// to copy over the tmate binary. Internal steps are not visible
|
||||
// to the end user.
|
||||
spec.Internal = append(spec.Internal, &engine.Step{
|
||||
ID: random(),
|
||||
Labels: labels,
|
||||
Pull: engine.PullIfNotExists,
|
||||
Image: image.Expand(c.Tmate.Image),
|
||||
Entrypoint: []string{"/bin/sh", "-c"},
|
||||
Command: []string{"cp /bin/tmate /usr/drone/bin/"},
|
||||
Network: "none",
|
||||
})
|
||||
|
||||
// next we create a temporary volume to share the tmate binary
|
||||
// with the pipeline containers.
|
||||
for _, step := range append(spec.Steps, spec.Internal...) {
|
||||
step.Volumes = append(step.Volumes, &engine.VolumeMount{
|
||||
Name: "_addons",
|
||||
Path: "/usr/drone/bin",
|
||||
})
|
||||
}
|
||||
spec.Volumes = append(spec.Volumes, &engine.Volume{
|
||||
EmptyDir: &engine.VolumeEmptyDir{
|
||||
ID: random(),
|
||||
Name: "_addons",
|
||||
Labels: labels,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if isGraph(spec) == false {
|
||||
configureSerial(spec)
|
||||
} else if pipeline.Clone.Disable == false {
|
||||
@@ -345,7 +387,7 @@ func (c *Compiler) Compile(ctx context.Context, args runtime.CompilerArgs) runti
|
||||
}
|
||||
}
|
||||
|
||||
for _, step := range spec.Steps {
|
||||
for _, step := range append(spec.Steps, spec.Internal...) {
|
||||
STEPS:
|
||||
for _, cred := range creds {
|
||||
if image.MatchHostname(step.Image, cred.Address) {
|
||||
|
||||
@@ -58,23 +58,8 @@ echo + %s
|
||||
|
||||
const tmateScript = `
|
||||
remote_debug() {
|
||||
if [ "$?" -ne "0" ];
|
||||
then
|
||||
|
||||
if command -v apt-get &> /dev/null
|
||||
then
|
||||
apt-get update -qq
|
||||
apt-get install xz-utils --assume-yes -qq
|
||||
fi
|
||||
|
||||
wget https://github.com/tmate-io/tmate/releases/download/2.4.0/tmate-2.4.0-static-linux-amd64.tar.xz
|
||||
tar -xf tmate-2.4.0-static-linux-amd64.tar.xz
|
||||
mv tmate-2.4.0-static-linux-amd64/tmate /usr/bin/
|
||||
chmod +x /usr/bin/tmate
|
||||
rm -rf tmate-2.4.0-static-linux-amd64
|
||||
rm -rf tmate-2.4.0-static-linux-amd64.tar.xz
|
||||
tmate -F
|
||||
|
||||
if [ "$?" -ne "0" ]; then
|
||||
/usr/drone/bin/tmate -F
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/drone-runners/drone-runner-docker/internal/docker/errors"
|
||||
"github.com/drone-runners/drone-runner-docker/internal/docker/image"
|
||||
@@ -90,6 +91,35 @@ func (e *Docker) Setup(ctx context.Context, specv runtime.Spec) error {
|
||||
Labels: spec.Network.Labels,
|
||||
})
|
||||
|
||||
// launches the inernal setup steps
|
||||
for _, step := range spec.Internal {
|
||||
if err := e.create(ctx, spec, step, ioutil.Discard); err != nil {
|
||||
logger.FromContext(ctx).
|
||||
WithError(err).
|
||||
WithField("container", step.ID).
|
||||
Errorln("cannot create tmate container")
|
||||
return err
|
||||
}
|
||||
if err := e.start(ctx, step.ID); err != nil {
|
||||
logger.FromContext(ctx).
|
||||
WithError(err).
|
||||
WithField("container", step.ID).
|
||||
Errorln("cannot start tmate container")
|
||||
return err
|
||||
}
|
||||
if !step.Detach {
|
||||
// the internal containers perform short-lived tasks
|
||||
// and should not require > 1 minute to execute.
|
||||
//
|
||||
// just to be on the safe side we apply a timeout to
|
||||
// ensure we never block pipeline execution because we
|
||||
// are waiting on an internal task.
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Minute)
|
||||
defer cancel()
|
||||
e.wait(ctx, step.ID)
|
||||
}
|
||||
}
|
||||
|
||||
return errors.TrimExtraInfo(err)
|
||||
}
|
||||
|
||||
@@ -104,12 +134,12 @@ func (e *Docker) Destroy(ctx context.Context, specv runtime.Spec) error {
|
||||
}
|
||||
|
||||
// stop all containers
|
||||
for _, step := range spec.Steps {
|
||||
for _, step := range append(spec.Steps, spec.Internal...) {
|
||||
e.client.ContainerKill(ctx, step.ID, "9")
|
||||
}
|
||||
|
||||
// cleanup all containers
|
||||
for _, step := range spec.Steps {
|
||||
for _, step := range append(spec.Steps, spec.Internal...) {
|
||||
e.client.ContainerRemove(ctx, step.ID, removeOpts)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ type (
|
||||
Spec struct {
|
||||
Platform Platform `json:"platform,omitempty"`
|
||||
Steps []*Step `json:"steps,omitempty"`
|
||||
Internal []*Step `json:"internal,omitempty"`
|
||||
Volumes []*Volume `json:"volumes,omitempty"`
|
||||
Network Network `json:"network"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user