File: generate_bundle.go

package info (click to toggle)
golang-github-crc-org-crc 2.34.0%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,548 kB
  • sloc: sh: 398; makefile: 326; javascript: 40
file content (128 lines) | stat: -rw-r--r-- 3,532 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package machine

import (
	"context"
	"os"
	"path/filepath"

	"github.com/crc-org/crc/v2/pkg/crc/cluster"
	"github.com/crc-org/crc/v2/pkg/crc/constants"
	"github.com/crc-org/crc/v2/pkg/crc/logging"
	"github.com/crc-org/crc/v2/pkg/crc/machine/bundle"
	"github.com/crc-org/crc/v2/pkg/crc/oc"
	crcssh "github.com/crc-org/crc/v2/pkg/crc/ssh"
	"github.com/crc-org/machine/libmachine/state"
	"github.com/pkg/errors"
)

func (client *client) GenerateBundle(forceStop bool) error {
	bundleMetadata, sshRunner, err := loadVM(client)
	if err != nil {
		return err
	}
	defer sshRunner.Close()

	if bundleMetadata.IsOpenShift() {
		ocConfig := oc.UseOCWithSSH(sshRunner)
		if err := cluster.RemovePullSecretFromCluster(context.Background(), ocConfig, sshRunner); err != nil {
			return errors.Wrap(err, "Error removing pull secret from cluster")
		}

		if err := cluster.RemoveOldRenderedMachineConfig(ocConfig); err != nil {
			return errors.Wrap(err, "Error removing old rendered machine configs")
		}
	}

	// Stop the cluster
	if _, err := client.Stop(); err != nil {
		if forceStop {
			if err := client.PowerOff(); err != nil {
				return err
			}
		} else {
			return err
		}
	}
	running, err := client.IsRunning()
	if err != nil {
		return err
	}
	if running {
		return errors.New("VM is still running")
	}

	tmpBaseDir, err := os.MkdirTemp(constants.MachineCacheDir, "crc_custom_bundle")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tmpBaseDir)

	// Create the custom bundle directory which is used as top level directory for tarball during compression
	customBundleName := bundle.GetCustomBundleName(bundleMetadata.GetBundleName())
	customBundleNameWithoutExtension := bundle.GetBundleNameWithoutExtension(customBundleName)

	copier, err := bundle.NewCopier(bundleMetadata, tmpBaseDir, customBundleNameWithoutExtension)
	if err != nil {
		return err
	}
	defer copier.Cleanup() //nolint
	customBundleDir := copier.CachedPath()

	if err := copier.CopyKubeConfig(); err != nil {
		return err
	}

	if err := copier.CopyPrivateSSHKey(constants.GetPrivateKeyPath()); err != nil {
		return err
	}

	if err := copier.CopyFilesFromFileList(); err != nil {
		return err
	}

	// Copy disk image
	logging.Infof("Copying the disk image to %s", customBundleNameWithoutExtension)
	logging.Debugf("Absolute path of custom bundle directory: %s", customBundleDir)
	diskPath, diskFormat, err := copyDiskImage(customBundleDir)
	if err != nil {
		return err
	}

	if err := copier.SetDiskImage(diskPath, diskFormat); err != nil {
		return err
	}

	if err := copier.GenerateBundle(customBundleNameWithoutExtension); err != nil {
		return err
	}
	cwd, err := os.Getwd()
	if err != nil {
		return err
	}
	logging.Infof("Bundle is generated in %s", filepath.Join(cwd, customBundleName))
	logging.Infof("You need to perform 'crc delete' and 'crc start -b %s' to use this bundle", filepath.Join(cwd, customBundleName))
	return nil
}

func loadVM(client *client) (*bundle.CrcBundleInfo, *crcssh.Runner, error) {
	vm, err := loadVirtualMachine(client.name, client.useVSock())
	if err != nil {
		return nil, nil, errors.Wrap(err, "Cannot load machine")
	}
	defer vm.Close()

	currentState, err := vm.Driver.GetState()
	if err != nil {
		return nil, nil, errors.Wrap(err, "Cannot get machine state")
	}
	if currentState != state.Running {
		return nil, nil, errors.New("machine is not running")
	}

	sshRunner, err := vm.SSHRunner()
	if err != nil {
		return nil, nil, errors.Wrap(err, "Error creating the ssh client")
	}

	return vm.bundle, sshRunner, nil
}