Skip to content

Commit

Permalink
Changes for slim rly images (#349)
Browse files Browse the repository at this point in the history
* Use relayer home dir in slim rly image

* Remove requirement for chown in rly image
  • Loading branch information
agouin committed Dec 2, 2022
1 parent e8b8627 commit d856fa8
Showing 1 changed file with 4 additions and 142 deletions.
146 changes: 4 additions & 142 deletions relayer/docker.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package relayer

import (
"archive/tar"
"bytes"
"context"
"fmt"
Expand Down Expand Up @@ -135,13 +134,9 @@ func (r *DockerRelayer) AddChainConfiguration(ctx context.Context, rep ibc.Relay
return fmt.Errorf("failed to generate config content: %w", err)
}

tar, err := r.generateConfigTar(chainConfigFile, configContent)
if err != nil {
return fmt.Errorf("generating tar for configuration: %w", err)
}

if err := r.untarIntoNodeHome(ctx, tar); err != nil {
return err // Already wrapped.
fw := dockerutil.NewFileWriter(r.log, r.client, r.testName)
if err := fw.WriteFile(ctx, r.volumeName, chainConfigFile, configContent); err != nil {
return fmt.Errorf("failed to rly config: %w", err)
}

cmd := r.c.AddChainConfiguration(chainConfigContainerFilePath, r.HomeDir())
Expand All @@ -155,40 +150,6 @@ func (r *DockerRelayer) AddChainConfiguration(ctx context.Context, rep ibc.Relay
return res.Err
}

// generateConfigTar returns an io.Reader containing the content of a tar archive
// which contains only the initial relayer config content.
func (r *DockerRelayer) generateConfigTar(relativeConfigPath string, content []byte) (io.Reader, error) {
var buf bytes.Buffer

// Although the docker module offers a "pkg/archive" package,
// there is no simple support for setting users and permissions.
// That package also brings in a surprising number of dependencies.
//
// Instead, just use a plain tar instance from the standard library.
tw := tar.NewWriter(&buf)
if err := tw.WriteHeader(&tar.Header{
Name: relativeConfigPath,

Size: int64(len(content)),
Mode: 0600,
Uname: r.c.DockerUser(),

ModTime: time.Now(),

Format: tar.FormatPAX,
}); err != nil {
return nil, fmt.Errorf("writing config file to tar: %w", err)
}
if _, err := tw.Write(content); err != nil {
return nil, fmt.Errorf("writing config content to tar: %w", err)
}
if err := tw.Close(); err != nil {
return nil, fmt.Errorf("closing tar writer: %w", err)
}

return &buf, nil
}

func (r *DockerRelayer) AddKey(ctx context.Context, rep ibc.RelayerExecReporter, chainID, keyName, coinType string) (ibc.Wallet, error) {
cmd := r.c.AddKey(chainID, keyName, coinType, r.HomeDir())

Expand Down Expand Up @@ -498,9 +459,7 @@ func (r *DockerRelayer) Bind() []string {

// HomeDir returns the home directory of the relayer on the underlying Docker container's filesystem.
func (r *DockerRelayer) HomeDir() string {
// Relayer writes to these files, so /var seems like a reasonable root.
// https://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/var.html
return "/var/relayer-" + r.c.Name()
return "/home/relayer"
}

func (r *DockerRelayer) HostName(pathName string) string {
Expand All @@ -511,103 +470,6 @@ func (r *DockerRelayer) UseDockerNetwork() bool {
return true
}

// untarIntoNodeHome untars the given io.Reader into r's NodeHome() directory.
func (r *DockerRelayer) untarIntoNodeHome(ctx context.Context, tar io.Reader) error {
return r.runOneOff(ctx, oneOffOptions{
ContainerNameDetail: "untar-chown",
Entrypoint: []string{},
Cmd: []string{"chown", "-R", r.c.DockerUser(), r.HomeDir()},
User: dockerutil.GetRootUserString(),
TarContent: tar,
})
}

// oneOffOptions indicate how to configure the container for a one-off job.
type oneOffOptions struct {
// Very short description of this container's purpose.
ContainerNameDetail string

// The entrypoint and command to use on the container.
Entrypoint, Cmd []string

// User for when the container runs.
User string

// If set, will be copied into the docker container into the NodeHome directory.
TarContent io.Reader
}

func (r *DockerRelayer) runOneOff(ctx context.Context, opts oneOffOptions) error {
containerName := r.Name() + "-" + opts.ContainerNameDetail + "-" + dockerutil.RandLowerCaseLetterString(5)
cc, err := r.client.ContainerCreate(
ctx,
&container.Config{
// Always use the main container image,
// because oftentimes this depends on the presence of the relayer user.
Image: r.containerImage().Ref(),

Entrypoint: opts.Entrypoint,
Cmd: opts.Cmd,

Hostname: r.HostName(containerName),
User: opts.User,

Labels: map[string]string{dockerutil.CleanupLabel: r.testName},
},
&container.HostConfig{
Binds: r.Bind(),
AutoRemove: false,
},
nil, // No network config in the one-off jobs for now. Could move to an option if we need it.
nil,
containerName,
)
if err != nil {
return fmt.Errorf("creating container for %s: %w", opts.ContainerNameDetail, err)
}
defer func() {
if err := r.client.ContainerRemove(ctx, cc.ID, types.ContainerRemoveOptions{Force: true}); err != nil {
r.log.Info(
"Failed to remove one-off container",
zap.String("container_name_detail", opts.ContainerNameDetail),
zap.String("container_id", cc.ID),
zap.Error(err),
)
}
}()

if opts.TarContent != nil {
// It is safe to copy into the container before starting it.
if err := r.client.CopyToContainer(
ctx,
cc.ID,
r.HomeDir(),
opts.TarContent,
types.CopyToContainerOptions{},
); err != nil {
return fmt.Errorf("copying tar to one-off %s container: %w", opts.ContainerNameDetail, err)
}
}

if err := r.client.ContainerStart(ctx, cc.ID, types.ContainerStartOptions{}); err != nil {
return fmt.Errorf("starting one-off %s container: %w", opts.ContainerNameDetail, err)
}

waitCh, errCh := r.client.ContainerWait(ctx, cc.ID, container.WaitConditionNotRunning)
select {
case <-ctx.Done():
return ctx.Err()
case err := <-errCh:
return err
case res := <-waitCh:
if res.Error != nil {
return fmt.Errorf("waiting for one-off %s container: %s", opts.ContainerNameDetail, res.Error.Message)
}
}

return nil
}

type RelayerCommander interface {
// Name is the name of the relayer, e.g. "rly" or "hermes".
Name() string
Expand Down

0 comments on commit d856fa8

Please sign in to comment.