Skip to content

Commit

Permalink
feat: support disk image in talosctl cluster create
Browse files Browse the repository at this point in the history
Fixes: #2973

Can now supply disk image using `--disk-image-path` flag.
May need to enable `--with-apply-config` if it's necessary to bootstrap
nodes properly.

Signed-off-by: Artem Chernyshev <artem.0xD2@gmail.com>
  • Loading branch information
Unix4ever authored and smira committed Dec 22, 2020
1 parent b1d4814 commit 6540e9b
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .drone.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,11 @@ local integration_uefi = Step("e2e-uefi", target="e2e-qemu", privileged=true, de
"WITH_UEFI": "true",
"REGISTRY": local_registry,
});
local integration_disk_image = Step("e2e-disk-image", target="e2e-qemu", privileged=true, depends_on=[integration_uefi], environment={
"SHORT_INTEGRATION_TEST": "yes",
"USE_DISK_IMAGE": "true",
"REGISTRY": local_registry,
});
local push_edge = {
name: 'push-edge',
image: 'autonomy/build-container:latest',
Expand Down Expand Up @@ -379,6 +384,7 @@ local integration_steps = default_steps + [
integration_provision_tests_track_1,
integration_cilium,
integration_uefi,
integration_disk_image,
push_edge,
];

Expand Down
12 changes: 12 additions & 0 deletions cmd/talosctl/cmd/mgmt/cluster/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ var (
nodeVmlinuzPath string
nodeInitramfsPath string
nodeISOPath string
nodeDiskImagePath string
applyConfigEnabled bool
bootloaderEnabled bool
uefiEnabled bool
configDebug bool
Expand Down Expand Up @@ -173,6 +175,7 @@ func create(ctx context.Context) (err error) {
KernelPath: nodeVmlinuzPath,
InitramfsPath: nodeInitramfsPath,
ISOPath: nodeISOPath,
DiskImagePath: nodeDiskImagePath,

SelfExecutable: os.Args[0],
StateDirectory: stateDir,
Expand Down Expand Up @@ -370,6 +373,13 @@ func create(ctx context.Context) (err error) {
clusterAccess := access.NewAdapter(cluster, provisionOptions...)
defer clusterAccess.Close() //nolint: errcheck

if applyConfigEnabled {
err = clusterAccess.ApplyConfig(ctx, request.Nodes, os.Stdout)
if err != nil {
return err
}
}

if err = postCreate(ctx, clusterAccess); err != nil {
if crashdumpOnFailure {
provisioner.CrashDump(ctx, cluster, os.Stderr)
Expand Down Expand Up @@ -563,6 +573,8 @@ func init() {
createCmd.Flags().StringVar(&nodeVmlinuzPath, "vmlinuz-path", helpers.ArtifactPath(constants.KernelAssetWithArch), "the compressed kernel image to use")
createCmd.Flags().StringVar(&nodeISOPath, "iso-path", "", "the ISO path to use for the initial boot (VM only)")
createCmd.Flags().StringVar(&nodeInitramfsPath, "initrd-path", helpers.ArtifactPath(constants.InitramfsAssetWithArch), "the uncompressed kernel image to use")
createCmd.Flags().StringVar(&nodeDiskImagePath, "disk-image-path", "", "disk image to use")
createCmd.Flags().BoolVar(&applyConfigEnabled, "with-apply-config", false, "enable apply config when the VM is starting in maintenance mode")
createCmd.Flags().BoolVar(&bootloaderEnabled, "with-bootloader", true, "enable bootloader to load kernel and initramfs from disk image after install")
createCmd.Flags().BoolVar(&uefiEnabled, "with-uefi", false, "enable UEFI on x86_64 architecture (always enabled for arm64)")
createCmd.Flags().StringSliceVar(&registryMirrors, "registry-mirror", []string{}, "list of registry mirrors to use in format: <registry host>=<mirror URL>")
Expand Down
8 changes: 1 addition & 7 deletions hack/test/e2e-iso.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ function create_cluster {

"${TALOSCTL}" cluster create \
--iso-path=${ARTIFACTS}/talos-amd64.iso \
--skip-injecting-config \
--wait=false \
--with-init-node \
--provisioner "${PROVISIONER}" \
--name "${CLUSTER_NAME}" \
--masters=1 \
Expand All @@ -25,6 +22,7 @@ function create_cluster {
--memory 2048 \
--cpus 2.0 \
--cidr 172.20.2.0/24 \
--with-apply-config \
--install-image ${REGISTRY:-ghcr.io}/talos-systems/installer:${TAG} \
--cni-bundle-url ${ARTIFACTS}/talosctl-cni-bundle-'${ARCH}'.tar.gz \
${REGISTRY_MIRROR_FLAGS}
Expand All @@ -37,9 +35,5 @@ function destroy_cluster() {
}

create_cluster
timeout -v --preserve-status 1m bash -c "until ${TALOSCTL} apply-config -n ${NODE} --insecure -f controlplane.yaml; do sleep 5; done"
sleep 5
timeout -v --preserve-status 2m bash -c "until nc -z ${NODE} 50000; do sleep 5; done"
${TALOSCTL} bootstrap -n "${NODE}"
${TALOSCTL} health --wait-timeout=10m0s -n "${NODE}" --control-plane-nodes="${NODE}"
destroy_cluster
10 changes: 10 additions & 0 deletions hack/test/e2e-qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ case "${WITH_UEFI:-false}" in
;;
esac

case "${USE_DISK_IMAGE:-false}" in
false)
DISK_IMAGE_FLAG=
;;
*)
tar -xf _out/metal-amd64.tar.gz -C _out/ --strip-components=1
DISK_IMAGE_FLAG="--disk-image-path=_out/disk.raw --with-apply-config"
;;
esac

function create_cluster {
build_registry_mirrors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,7 @@ func readConfigFromISO() (b []byte, err error) {

// KernelArgs implements the runtime.Platform interface.
func (m *Metal) KernelArgs() procfs.Parameters {
return nil
return []*procfs.Parameter{
procfs.NewParameter("console").Append("ttyS0").Append("tty0"),
}
}
60 changes: 60 additions & 0 deletions pkg/cluster/apply-config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package cluster

import (
"context"
"crypto/tls"
"io"
"time"

"github.com/talos-systems/go-retry/retry"

machineapi "github.com/talos-systems/talos/pkg/machinery/api/machine"
"github.com/talos-systems/talos/pkg/machinery/client"
"github.com/talos-systems/talos/pkg/provision"
)

// ApplyConfigClient client to apply config.
type ApplyConfigClient struct {
ClientProvider
Info
}

// ApplyConfig on the node via the API using insecure mode.
func (s *APIBoostrapper) ApplyConfig(ctx context.Context, nodes []provision.NodeRequest, out io.Writer) error {
for _, node := range nodes {
n := node

configureNode := func() error {
c, err := client.New(ctx, client.WithTLSConfig(&tls.Config{
InsecureSkipVerify: true,
}), client.WithEndpoints(n.IP.String()))
if err != nil {
return retry.UnexpectedError(err)
}

cfgBytes, err := n.Config.Bytes()
if err != nil {
return retry.UnexpectedError(err)
}

_, err = c.ApplyConfiguration(ctx, &machineapi.ApplyConfigurationRequest{
Data: cfgBytes,
})
if err != nil {
return retry.ExpectedError(err)
}

return nil
}

if err := retry.Constant(2*time.Minute, retry.WithUnits(250*time.Millisecond), retry.WithJitter(50*time.Millisecond)).Retry(configureNode); err != nil {
return err
}
}

return nil
}
1 change: 1 addition & 0 deletions pkg/provision/access/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type Adapter struct {
cluster.APICrashDumper
cluster.APIBoostrapper
cluster.Info
cluster.ApplyConfigClient
}

type infoWrapper struct {
Expand Down
27 changes: 27 additions & 0 deletions pkg/provision/providers/qemu/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe
return provision.NodeInfo{}, err
}

err = p.populateSystemDisk(diskPaths, clusterReq)
if err != nil {
return provision.NodeInfo{}, err
}

logFile, err := os.OpenFile(state.GetRelativePath(fmt.Sprintf("%s.log", nodeReq.Name)), os.O_APPEND|os.O_CREATE|os.O_RDWR, 0o666)
if err != nil {
return provision.NodeInfo{}, err
Expand Down Expand Up @@ -226,3 +231,25 @@ func (p *provisioner) findBridgeListenPort(clusterReq provision.ClusterRequest)

return port, l.Close()
}

func (p *provisioner) populateSystemDisk(disks []string, clusterReq provision.ClusterRequest) error {
if len(disks) > 0 && clusterReq.DiskImagePath != "" {
disk, err := os.OpenFile(disks[0], os.O_RDWR, 0o755)
if err != nil {
return err
}
defer disk.Close() // nolint:errcheck

image, err := os.Open(clusterReq.DiskImagePath)
if err != nil {
return err
}
defer image.Close() // nolint:errcheck

_, err = io.Copy(disk, image)

return err
}

return nil
}
1 change: 1 addition & 0 deletions pkg/provision/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type ClusterRequest struct {
KernelPath string
InitramfsPath string
ISOPath string
DiskImagePath string

// Path to talosctl executable to re-execute itself as needed.
SelfExecutable string
Expand Down
2 changes: 2 additions & 0 deletions website/content/docs/v0.8/Reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ talosctl cluster create [flags]
--crashdump print debug crashdump to stderr when cluster startup fails
--custom-cni-url string install custom CNI from the URL (Talos cluster)
--disk int default limit on disk size in MB (each VM) (default 6144)
--disk-image-path string disk image to use
--dns-domain string the dns domain to use for cluster (default "cluster.local")
--docker-host-ip string Host IP to forward exposed ports to (Docker provisioner only) (default "0.0.0.0")
--endpoint string use endpoint instead of provider defaults
Expand All @@ -109,6 +110,7 @@ talosctl cluster create [flags]
--vmlinuz-path string the compressed kernel image to use (default "_out/vmlinuz-${ARCH}")
--wait wait for the cluster to be ready before returning (default true)
--wait-timeout duration timeout to wait for the cluster to be ready (default 20m0s)
--with-apply-config enable apply config when the VM is starting in maintenance mode
--with-bootloader enable bootloader to load kernel and initramfs from disk image after install (default true)
--with-debug enable debug in Talos config to send service logs to the console
--with-init-node create the cluster with an init node
Expand Down

0 comments on commit 6540e9b

Please sign in to comment.