Skip to content

Commit

Permalink
[FIX/ENHANCEMENT] node/create: inherit registry config from existing …
Browse files Browse the repository at this point in the history
…nodes (#597)
  • Loading branch information
iwilltry42 authored May 11, 2021
1 parent 5fe8a3c commit bb1f5bd
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 5 deletions.
48 changes: 44 additions & 4 deletions pkg/client/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,20 @@ package client
import (
"bytes"
"context"
"errors"
"fmt"
"io/ioutil"
"os"
"reflect"
"strings"
"time"

dockerunits "github.com/docker/go-units"
"github.com/imdario/mergo"
"github.com/rancher/k3d/v4/pkg/actions"
"github.com/rancher/k3d/v4/pkg/runtimes"
"github.com/rancher/k3d/v4/pkg/runtimes/docker"
runtimeErrors "github.com/rancher/k3d/v4/pkg/runtimes/errors"
k3d "github.com/rancher/k3d/v4/pkg/types"
"github.com/rancher/k3d/v4/pkg/util"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -89,6 +93,25 @@ func NodeAddToCluster(ctx context.Context, runtime runtimes.Runtime, node *k3d.N

log.Debugf("Adding node %+v \n>>> to cluster %+v\n>>> based on existing node %+v", node, cluster, chosenNode)

// fetch registry config
registryConfigBytes := []byte{}
registryConfigReader, err := runtime.ReadFromNode(ctx, k3d.DefaultRegistriesFilePath, chosenNode)
if err != nil {
if !errors.Is(err, runtimeErrors.ErrRuntimeFileNotFound) {
log.Warnf("Failed to read registry config from node %s: %+v", node.Name, err)
}
} else {
defer registryConfigReader.Close()

var err error
registryConfigBytes, err = ioutil.ReadAll(registryConfigReader)
if err != nil {
log.Warnf("Failed to read registry config from node %s: %+v", node.Name, err)
}
registryConfigReader.Close()
registryConfigBytes = bytes.Trim(registryConfigBytes[512:], "\x00") // trim control characters, etc.
}

// merge node config of new node into existing node config
if err := mergo.MergeWithOverwrite(chosenNode, *node); err != nil {
log.Errorln("Failed to merge new node config into existing node config")
Expand Down Expand Up @@ -133,11 +156,27 @@ func NodeAddToCluster(ctx context.Context, runtime runtimes.Runtime, node *k3d.N
}
}

// add node actions
if len(registryConfigBytes) != 0 {
if createNodeOpts.NodeHooks == nil {
createNodeOpts.NodeHooks = []k3d.NodeHook{}
}
createNodeOpts.NodeHooks = append(createNodeOpts.NodeHooks, k3d.NodeHook{
Stage: k3d.LifecycleStagePreStart,
Action: actions.WriteFileAction{
Runtime: runtime,
Content: registryConfigBytes,
Dest: k3d.DefaultRegistriesFilePath,
Mode: 0644,
},
})
}

// clear status fields
node.State.Running = false
node.State.Status = ""

if err := NodeRun(ctx, runtime, node, k3d.NodeCreateOpts{}); err != nil {
if err := NodeRun(ctx, runtime, node, createNodeOpts); err != nil {
return err
}

Expand All @@ -162,7 +201,7 @@ func NodeAddToClusterMulti(ctx context.Context, runtime runtimes.Runtime, nodes

nodeWaitGroup, ctx := errgroup.WithContext(ctx)
for _, node := range nodes {
if err := NodeAddToCluster(ctx, runtime, node, cluster, k3d.NodeCreateOpts{}); err != nil {
if err := NodeAddToCluster(ctx, runtime, node, cluster, createNodeOpts); err != nil {
return err
}
if createNodeOpts.Wait {
Expand Down Expand Up @@ -230,8 +269,9 @@ func NodeRun(ctx context.Context, runtime runtimes.Runtime, node *k3d.Node, node
}

if err := NodeStart(ctx, runtime, node, k3d.NodeStartOpts{
Wait: nodeCreateOpts.Wait,
Timeout: nodeCreateOpts.Timeout,
Wait: nodeCreateOpts.Wait,
Timeout: nodeCreateOpts.Timeout,
NodeHooks: nodeCreateOpts.NodeHooks,
}); err != nil {
return err
}
Expand Down
26 changes: 26 additions & 0 deletions pkg/runtimes/docker/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"bytes"
"context"
"fmt"
"io"
"os"
"strings"

Expand All @@ -35,6 +36,7 @@ import (
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/archive"
"github.com/pkg/errors"
runtimeErrors "github.com/rancher/k3d/v4/pkg/runtimes/errors"
k3d "github.com/rancher/k3d/v4/pkg/types"
log "github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -140,6 +142,30 @@ func (d Docker) WriteToNode(ctx context.Context, content []byte, dest string, mo
return nil
}

// ReadFromNode reads from a given filepath inside the node container
func (d Docker) ReadFromNode(ctx context.Context, path string, node *k3d.Node) (io.ReadCloser, error) {
log.Tracef("Reading path %s from node %s...", path, node.Name)
nodeContainer, err := getNodeContainer(ctx, node)
if err != nil {
return nil, fmt.Errorf("Failed to find container for node '%s': %+v", node.Name, err)
}

docker, err := GetDockerClient()
if err != nil {
return nil, err
}

reader, _, err := docker.CopyFromContainer(ctx, nodeContainer.ID, path)
if err != nil {
if client.IsErrNotFound(err) {
return nil, errors.Wrap(runtimeErrors.ErrRuntimeFileNotFound, err.Error())
}
return nil, err
}

return reader, err
}

// GetDockerClient returns a docker client
func GetDockerClient() (*client.Client, error) {
var err error
Expand Down
5 changes: 4 additions & 1 deletion pkg/runtimes/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package runtimes
package errors

import "errors"

Expand All @@ -34,3 +34,6 @@ var (
ErrRuntimeNetworkNotExists = errors.New("network does not exist")
ErrRuntimeNetworkMultiSameName = errors.New("multiple networks with same name found")
)

// Container Filesystem Errors
var ErrRuntimeFileNotFound = errors.New("file not found")
1 change: 1 addition & 0 deletions pkg/runtimes/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ type Runtime interface {
GetImages(context.Context) ([]string, error)
CopyToNode(context.Context, string, string, *k3d.Node) error // @param context, source, destination, node
WriteToNode(context.Context, []byte, string, os.FileMode, *k3d.Node) error // @param context, content, destination, filemode, node
ReadFromNode(context.Context, string, *k3d.Node) (io.ReadCloser, error) // @param context, filepath, node
GetHostIP(context.Context, string) (net.IP, error)
ConnectNodeToNetwork(context.Context, *k3d.Node, string) error // @param context, node, network name
DisconnectNodeFromNetwork(context.Context, *k3d.Node, string) error // @param context, node, network name
Expand Down

0 comments on commit bb1f5bd

Please sign in to comment.