kvm: Unbreak minikube on Fedora/RHEL
Since #20852 minikube is broken on Fedora/RHEL. We add console.log
(~/.minikube/machines/NAME/console.log) for dumping the console logs
during startup. Libvirt is blocked by selinux policy:
$ sudo ausearch -m AVC --start today
...
----
time->Sat Sep 13 22:14:10 2025
type=AVC msg=audit(1757790850.921:4801): avc: denied { open } for pid=215452 comm="virtlogd" path="/home/nsoffer/.minikube/machines/minikube/console.log" dev="vda3" ino=197349579 scontext=system_u:system_r:virtlogd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=1
----
Having better logs in the kvm driver can be helpful but it cannot break
basic functionality. Remove the code to create the log file and dump the
logs.
This is a manual revert of commit
2b81ce24e3. We cannot do a clean revert
since all commits in #20852 were squashed during merge.
Tested using:
$ make out/docker-machine-driver-kvm2
$ cp out/docker-machine-driver-kvm2 ~/.minikube/bin/
$ out/minikube start --driver kvm
😄 minikube v1.37.0 on Fedora 42 (kvm/amd64)
✨ Using the kvm2 driver based on user configuration
👍 Starting "minikube" primary control-plane node in "minikube" cluster
🔥 Creating kvm2 VM (CPUs=2, Memory=6144MB, Disk=20000MB) ...
🐳 Preparing Kubernetes v1.34.0 on Docker 28.4.0 ...
🔗 Configuring bridge CNI (Container Networking Interface) ...
🔎 Verifying Kubernetes components...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟 Enabled addons: storage-provisioner, default-storageclass
❗ /usr/local/bin/kubectl is version 1.32.1, which may have incompatibilities with Kubernetes 1.34.0.
▪ Want kubectl v1.34.0? Try 'minikube kubectl -- get pods -A'
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
pull/21550/head
parent
574f958887
commit
0aba0a8e31
|
|
@ -70,14 +70,7 @@ func closeDomain(dom *libvirt.Domain, conn *libvirt.Connect) error {
|
|||
func (d *Driver) defineDomain() (*libvirt.Domain, error) {
|
||||
tmpl := template.Must(template.New("domain").Parse(domainTmpl))
|
||||
var domainXML bytes.Buffer
|
||||
dlog := struct {
|
||||
Driver
|
||||
ConsoleLogPath string
|
||||
}{
|
||||
Driver: *d,
|
||||
ConsoleLogPath: consoleLogPath(*d),
|
||||
}
|
||||
if err := tmpl.Execute(&domainXML, dlog); err != nil {
|
||||
if err := tmpl.Execute(&domainXML, d); err != nil {
|
||||
return nil, errors.Wrap(err, "executing domain xml")
|
||||
}
|
||||
conn, err := getConnection(d.ConnectionURI)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ const domainTmpl = `
|
|||
<source file='{{.DiskPath}}'/>
|
||||
<target dev='hda' bus='virtio'/>
|
||||
</disk>
|
||||
<controller type='virtio-serial'/>
|
||||
<interface type='network'>
|
||||
<source network='{{.PrivateNetwork}}'/>
|
||||
<model type='virtio'/>
|
||||
|
|
@ -66,14 +65,10 @@ const domainTmpl = `
|
|||
</interface>
|
||||
<serial type='pty'>
|
||||
<target port='0'/>
|
||||
<log file='{{.ConsoleLogPath}}' append='on'/>
|
||||
</serial>
|
||||
<console type='pty'>
|
||||
<target type='serial' port='0'/>
|
||||
</console>
|
||||
<console type='pty'>
|
||||
<target type="virtio" port="1"/>
|
||||
</console>
|
||||
<rng model='virtio'>
|
||||
<backend model='random'>/dev/random</backend>
|
||||
</rng>
|
||||
|
|
|
|||
|
|
@ -314,24 +314,6 @@ func (d *Driver) Start() error {
|
|||
log.Debugf("starting domain XML:\n%s", domXML)
|
||||
}
|
||||
|
||||
// libvirt/qemu creates a console log file owned by root:root and permissions 0600,
|
||||
// so we pre-create it (and close it immediately), just to be able to read it later
|
||||
logPath := consoleLogPath(*d)
|
||||
f, err := os.Create(logPath)
|
||||
if err != nil {
|
||||
log.Debugf("failed to create console log file %q: %v", logPath, err)
|
||||
} else {
|
||||
f.Close()
|
||||
}
|
||||
// ensure console log file is cleaned up
|
||||
defer func() {
|
||||
if _, err := os.Stat(logPath); err == nil {
|
||||
if err := os.Remove(logPath); err != nil {
|
||||
log.Debugf("failed removing console log file %q: %v", logPath, err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err := dom.Create(); err != nil {
|
||||
return errors.Wrap(err, "creating domain")
|
||||
}
|
||||
|
|
@ -355,12 +337,6 @@ func (d *Driver) Start() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// consoleLogPath returns the path to the console log file for the given machine name.
|
||||
func consoleLogPath(d Driver) string {
|
||||
// return fmt.Sprintf("%s-console.log", machineName)
|
||||
return d.ResolveStorePath("console.log")
|
||||
}
|
||||
|
||||
// waitForDomainState waits maxTime for the domain to reach a target state.
|
||||
func (d *Driver) waitForDomainState(targetState state.State, maxTime time.Duration) error {
|
||||
query := func() error {
|
||||
|
|
@ -377,27 +353,11 @@ func (d *Driver) waitForDomainState(targetState state.State, maxTime time.Durati
|
|||
return fmt.Errorf("last domain state: %q", currentState.String())
|
||||
}
|
||||
if err := retry.Local(query, maxTime); err != nil {
|
||||
dumpConsoleLogs(consoleLogPath(*d))
|
||||
return fmt.Errorf("timed out waiting %v for domain to reach %q state: %w", maxTime, targetState.String(), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// dumpConsoleLogs prints out the console log.
|
||||
func dumpConsoleLogs(logPath string) {
|
||||
if _, err := os.Stat(logPath); err != nil {
|
||||
log.Debugf("failed checking console log file %q: %v", logPath, err)
|
||||
return
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(logPath)
|
||||
if err != nil {
|
||||
log.Debugf("failed dumping console log file %q: %v", logPath, err)
|
||||
return
|
||||
}
|
||||
log.Debugf("console log:\n%s", data)
|
||||
}
|
||||
|
||||
// waitForStaticIP waits for IP address of domain that has been created & starting and then makes that IP static.
|
||||
func (d *Driver) waitForStaticIP(conn *libvirt.Connect, maxTime time.Duration) error {
|
||||
query := func() error {
|
||||
|
|
@ -416,7 +376,6 @@ func (d *Driver) waitForStaticIP(conn *libvirt.Connect, maxTime time.Duration) e
|
|||
return nil
|
||||
}
|
||||
if err := retry.Local(query, maxTime); err != nil {
|
||||
dumpConsoleLogs(consoleLogPath(*d))
|
||||
return fmt.Errorf("domain %s didn't return IP after %v", d.MachineName, maxTime)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue