source tmate binary from docker image
This commit is contained in:
@@ -37,6 +37,7 @@ type compileCommand struct {
|
|||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
Secrets map[string]string
|
Secrets map[string]string
|
||||||
Resources compiler.Resources
|
Resources compiler.Resources
|
||||||
|
Tmate compiler.Tmate
|
||||||
Clone bool
|
Clone bool
|
||||||
Config string
|
Config string
|
||||||
}
|
}
|
||||||
@@ -101,6 +102,7 @@ func (c *compileCommand) run(*kingpin.ParseContext) error {
|
|||||||
Environ: provider.Static(c.Environ),
|
Environ: provider.Static(c.Environ),
|
||||||
Labels: c.Labels,
|
Labels: c.Labels,
|
||||||
Resources: c.Resources,
|
Resources: c.Resources,
|
||||||
|
Tmate: c.Tmate,
|
||||||
Privileged: append(c.Privileged, compiler.Privileged...),
|
Privileged: append(c.Privileged, compiler.Privileged...),
|
||||||
Networks: c.Networks,
|
Networks: c.Networks,
|
||||||
Volumes: c.Volumes,
|
Volumes: c.Volumes,
|
||||||
@@ -192,6 +194,13 @@ func registerCompile(app *kingpin.Application) {
|
|||||||
cmd.Flag("docker-config", "path to the docker config file").
|
cmd.Flag("docker-config", "path to the docker config file").
|
||||||
StringVar(&c.Config)
|
StringVar(&c.Config)
|
||||||
|
|
||||||
|
cmd.Flag("tmate-image", "tmate docker image").
|
||||||
|
Default("drone/drone-runner-docker:latest").
|
||||||
|
StringVar(&c.Tmate.Image)
|
||||||
|
|
||||||
|
cmd.Flag("tmate-enabled", "tmate enabled").
|
||||||
|
BoolVar(&c.Tmate.Enabled)
|
||||||
|
|
||||||
// shared pipeline flags
|
// shared pipeline flags
|
||||||
c.Flags = internal.ParseFlags(cmd)
|
c.Flags = internal.ParseFlags(cmd)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,11 @@ type Config struct {
|
|||||||
Config string `envconfig:"DRONE_DOCKER_CONFIG"`
|
Config string `envconfig:"DRONE_DOCKER_CONFIG"`
|
||||||
Stream bool `envconfig:"DRONE_DOCKER_STREAM_PULL" default:"true"`
|
Stream bool `envconfig:"DRONE_DOCKER_STREAM_PULL" default:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tmate struct {
|
||||||
|
Enabled bool `envconfig:"DRONE_TMATE_ENABLED" default:"true"`
|
||||||
|
Image string `envconfig:"DRONE_TMATE_IMAGE" default:"drone/drone-runner-docker:latest"`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// legacy environment variables. the key is the legacy
|
// legacy environment variables. the key is the legacy
|
||||||
|
|||||||
@@ -141,6 +141,10 @@ func (c *daemonCommand) run(*kingpin.ParseContext) error {
|
|||||||
CPUSet: config.Resources.CPUSet,
|
CPUSet: config.Resources.CPUSet,
|
||||||
ShmSize: config.Resources.ShmSize,
|
ShmSize: config.Resources.ShmSize,
|
||||||
},
|
},
|
||||||
|
Tmate: compiler.Tmate{
|
||||||
|
Image: config.Tmate.Image,
|
||||||
|
Enabled: config.Tmate.Enabled,
|
||||||
|
},
|
||||||
Environ: provider.Combine(
|
Environ: provider.Combine(
|
||||||
provider.Static(config.Runner.Environ),
|
provider.Static(config.Runner.Environ),
|
||||||
provider.External(
|
provider.External(
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ type execCommand struct {
|
|||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
Secrets map[string]string
|
Secrets map[string]string
|
||||||
Resources compiler.Resources
|
Resources compiler.Resources
|
||||||
|
Tmate compiler.Tmate
|
||||||
Clone bool
|
Clone bool
|
||||||
Config string
|
Config string
|
||||||
Pretty bool
|
Pretty bool
|
||||||
@@ -120,6 +121,7 @@ func (c *execCommand) run(*kingpin.ParseContext) error {
|
|||||||
Environ: provider.Static(c.Environ),
|
Environ: provider.Static(c.Environ),
|
||||||
Labels: c.Labels,
|
Labels: c.Labels,
|
||||||
Resources: c.Resources,
|
Resources: c.Resources,
|
||||||
|
Tmate: c.Tmate,
|
||||||
Privileged: append(c.Privileged, compiler.Privileged...),
|
Privileged: append(c.Privileged, compiler.Privileged...),
|
||||||
Networks: c.Networks,
|
Networks: c.Networks,
|
||||||
Volumes: c.Volumes,
|
Volumes: c.Volumes,
|
||||||
@@ -327,6 +329,13 @@ func registerExec(app *kingpin.Application) {
|
|||||||
cmd.Flag("docker-config", "path to the docker config file").
|
cmd.Flag("docker-config", "path to the docker config file").
|
||||||
StringVar(&c.Config)
|
StringVar(&c.Config)
|
||||||
|
|
||||||
|
cmd.Flag("tmate-image", "tmate docker image").
|
||||||
|
Default("drone/drone-runner-docker:latest").
|
||||||
|
StringVar(&c.Tmate.Image)
|
||||||
|
|
||||||
|
cmd.Flag("tmate-enabled", "tmate enabled").
|
||||||
|
BoolVar(&c.Tmate.Enabled)
|
||||||
|
|
||||||
cmd.Flag("debug", "enable debug logging").
|
cmd.Flag("debug", "enable debug logging").
|
||||||
BoolVar(&c.Debug)
|
BoolVar(&c.Debug)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
FROM alpine:3.6 as alpine
|
FROM alpine:3 as alpine
|
||||||
RUN apk add -U --no-cache ca-certificates
|
RUN apk add -U --no-cache ca-certificates
|
||||||
|
|
||||||
FROM alpine:3.6
|
RUN wget https://github.com/tmate-io/tmate/releases/download/2.4.0/tmate-2.4.0-static-linux-amd64.tar.xz
|
||||||
|
RUN tar -xf tmate-2.4.0-static-linux-amd64.tar.xz
|
||||||
|
RUN mv tmate-2.4.0-static-linux-amd64/tmate /bin/
|
||||||
|
RUN chmod +x /bin/tmate
|
||||||
|
|
||||||
|
FROM alpine:3
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
ENV GODEBUG netdns=go
|
ENV GODEBUG netdns=go
|
||||||
@@ -9,6 +14,7 @@ ENV DRONE_PLATFORM_OS linux
|
|||||||
ENV DRONE_PLATFORM_ARCH amd64
|
ENV DRONE_PLATFORM_ARCH amd64
|
||||||
|
|
||||||
COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||||
|
COPY --from=alpine /bin/tmate /bin
|
||||||
|
|
||||||
LABEL com.centurylinklabs.watchtower.stop-signal="SIGINT"
|
LABEL com.centurylinklabs.watchtower.stop-signal="SIGINT"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
FROM alpine:3.6 as alpine
|
FROM alpine:3 as alpine
|
||||||
RUN apk add -U --no-cache ca-certificates
|
RUN apk add -U --no-cache ca-certificates
|
||||||
|
|
||||||
FROM alpine:3.6
|
RUN wget https://github.com/tmate-io/tmate/releases/download/2.4.0/tmate-2.4.0-static-linux-arm32v7.tar.xz
|
||||||
|
RUN tar -xf tmate-2.4.0-static-linux-arm32v7.tar.xz
|
||||||
|
RUN mv tmate-2.4.0-static-linux-arm32v7/tmate /bin/
|
||||||
|
RUN chmod +x /bin/tmate
|
||||||
|
|
||||||
|
FROM alpine:3
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
ENV GODEBUG netdns=go
|
ENV GODEBUG netdns=go
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
FROM alpine:3.6 as alpine
|
FROM alpine:3 as alpine
|
||||||
RUN apk add -U --no-cache ca-certificates
|
RUN apk add -U --no-cache ca-certificates
|
||||||
|
|
||||||
FROM alpine:3.6
|
RUN wget https://github.com/tmate-io/tmate/releases/download/2.4.0/tmate-2.4.0-static-linux-arm64v8.tar.xz
|
||||||
|
RUN tar -xf tmate-2.4.0-static-linux-arm64v8.tar.xz
|
||||||
|
RUN mv tmate-2.4.0-static-linux-arm64v8/tmate /bin/
|
||||||
|
RUN chmod +x /bin/tmate
|
||||||
|
|
||||||
|
FROM alpine:3
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
ENV GODEBUG netdns=go
|
ENV GODEBUG netdns=go
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ type Resources struct {
|
|||||||
ShmSize int64
|
ShmSize int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tmate defines tmate settings.
|
||||||
|
type Tmate struct {
|
||||||
|
Image string
|
||||||
|
Enabled bool
|
||||||
|
}
|
||||||
|
|
||||||
// Compiler compiles the Yaml configuration file to an
|
// Compiler compiles the Yaml configuration file to an
|
||||||
// intermediate representation optimized for simple execution.
|
// intermediate representation optimized for simple execution.
|
||||||
type Compiler struct {
|
type Compiler struct {
|
||||||
@@ -92,6 +98,10 @@ type Compiler struct {
|
|||||||
// applies to pipeline containers.
|
// applies to pipeline containers.
|
||||||
Resources Resources
|
Resources Resources
|
||||||
|
|
||||||
|
// Tate provides global configration options for tmate
|
||||||
|
// live debugging.
|
||||||
|
Tmate Tmate
|
||||||
|
|
||||||
// Secret returns a named secret value that can be injected
|
// Secret returns a named secret value that can be injected
|
||||||
// into the pipeline step.
|
// into the pipeline step.
|
||||||
Secret secret.Provider
|
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 {
|
if isGraph(spec) == false {
|
||||||
configureSerial(spec)
|
configureSerial(spec)
|
||||||
} else if pipeline.Clone.Disable == false {
|
} 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:
|
STEPS:
|
||||||
for _, cred := range creds {
|
for _, cred := range creds {
|
||||||
if image.MatchHostname(step.Image, cred.Address) {
|
if image.MatchHostname(step.Image, cred.Address) {
|
||||||
|
|||||||
@@ -58,23 +58,8 @@ echo + %s
|
|||||||
|
|
||||||
const tmateScript = `
|
const tmateScript = `
|
||||||
remote_debug() {
|
remote_debug() {
|
||||||
if [ "$?" -ne "0" ];
|
if [ "$?" -ne "0" ]; then
|
||||||
then
|
/usr/drone/bin/tmate -F
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/drone-runners/drone-runner-docker/internal/docker/errors"
|
"github.com/drone-runners/drone-runner-docker/internal/docker/errors"
|
||||||
"github.com/drone-runners/drone-runner-docker/internal/docker/image"
|
"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,
|
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)
|
return errors.TrimExtraInfo(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,12 +134,12 @@ func (e *Docker) Destroy(ctx context.Context, specv runtime.Spec) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stop all containers
|
// stop all containers
|
||||||
for _, step := range spec.Steps {
|
for _, step := range append(spec.Steps, spec.Internal...) {
|
||||||
e.client.ContainerKill(ctx, step.ID, "9")
|
e.client.ContainerKill(ctx, step.ID, "9")
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup all containers
|
// cleanup all containers
|
||||||
for _, step := range spec.Steps {
|
for _, step := range append(spec.Steps, spec.Internal...) {
|
||||||
e.client.ContainerRemove(ctx, step.ID, removeOpts)
|
e.client.ContainerRemove(ctx, step.ID, removeOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ type (
|
|||||||
Spec struct {
|
Spec struct {
|
||||||
Platform Platform `json:"platform,omitempty"`
|
Platform Platform `json:"platform,omitempty"`
|
||||||
Steps []*Step `json:"steps,omitempty"`
|
Steps []*Step `json:"steps,omitempty"`
|
||||||
|
Internal []*Step `json:"internal,omitempty"`
|
||||||
Volumes []*Volume `json:"volumes,omitempty"`
|
Volumes []*Volume `json:"volumes,omitempty"`
|
||||||
Network Network `json:"network"`
|
Network Network `json:"network"`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user