Skip to content

Commit

Permalink
Make sure that updated Pid and cgroup data is used on every VM start
Browse files Browse the repository at this point in the history
  • Loading branch information
rmohr committed Sep 5, 2017
1 parent 49148a9 commit a22cfee
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Vagrant.configure(2) do |config|
if $use_nfs then
config.vm.synced_folder "./", "/vagrant", type: "nfs"
else
config.vm.synced_folder "./", "/vagrant", type: "rsync", rsync__exclude: [ "cluster/vagrant/.kubectl", "cluster/vagrant/.kubeconfig", ".vagrant", "vendor"]
config.vm.synced_folder "./", "/vagrant", type: "rsync", rsync__exclude: [ "cluster/vagrant/.kubectl", "cluster/vagrant/.kubeconfig", ".vagrant", "vendor", ".git"]
end

config.vm.provision "shell", inline: <<-SHELL
Expand Down
6 changes: 3 additions & 3 deletions pkg/virt-controller/services/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ func (t *templateService) RenderLaunchManifest(vm *v1.VM) (*kubev1.Pod, error) {
ImagePullPolicy: kubev1.PullIfNotPresent,
Command: []string{"/virt-launcher",
"--qemu-timeout", "60s",
"-name", domain,
"-namespace", namespace,
"-socket-dir", t.socketBaseDir,
"--name", domain,
"--namespace", namespace,
"--socket-dir", t.socketBaseDir,
},
VolumeMounts: []kubev1.VolumeMount{
{
Expand Down
18 changes: 18 additions & 0 deletions pkg/virt-handler/virtwrap/cli/libvirt.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,21 @@ func newConnection(uri string, user string, pass string) (*libvirt.Connect, erro

return virConn, err
}

func IsDown(domState libvirt.DomainState) bool {
switch domState {
case libvirt.DOMAIN_NOSTATE, libvirt.DOMAIN_SHUTDOWN, libvirt.DOMAIN_SHUTOFF, libvirt.DOMAIN_CRASHED:
return true

}
return false
}

func IsPaused(domState libvirt.DomainState) bool {
switch domState {
case libvirt.DOMAIN_PAUSED:
return true

}
return false
}
46 changes: 32 additions & 14 deletions pkg/virt-handler/virtwrap/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,18 +202,13 @@ func (l *LibvirtDomainManager) SyncVM(vm *v1.VM) (*api.DomainSpec, error) {
wantedSpec.Name = domName
wantedSpec.UUID = string(vm.GetObjectMeta().GetUID())
dom, err := l.virConn.LookupDomainByName(domName)
newDomain := false
if err != nil {
// We need the domain but it does not exist, so create it
if domainerrors.IsNotFound(err) {
xmlStr, err := xml.Marshal(&wantedSpec)
newDomain = true
dom, err = l.setDomainXML(vm, wantedSpec)
if err != nil {
logging.DefaultLogger().Object(vm).Error().Reason(err).Msg("Generating the domain XML failed.")
return nil, err
}
logging.DefaultLogger().Object(vm).Info().V(3).With("xml", xmlStr).Msgf("Domain XML generated.")
dom, err = l.virConn.DomainDefineXML(string(xmlStr))
if err != nil {
logging.DefaultLogger().Object(vm).Error().Reason(err).Msg("Defining the VM failed.")
return nil, err
}
logging.DefaultLogger().Object(vm).Info().Msg("Domain defined.")
Expand All @@ -229,19 +224,28 @@ func (l *LibvirtDomainManager) SyncVM(vm *v1.VM) (*api.DomainSpec, error) {
logging.DefaultLogger().Object(vm).Error().Reason(err).Msg("Getting the domain state failed.")
return nil, err
}

// To make sure, that we set the right qemu wrapper arguments,
// we update the domain XML whenever a VM was already defined but not running
if !newDomain && cli.IsDown(domState) {
_, err = l.setDomainXML(vm, wantedSpec)
if err != nil {
return nil, err
}
}

// TODO Suspend, Pause, ..., for now we only support reaching the running state
// TODO for migration and error detection we also need the state change reason
//state := LifeCycleTranslationMap[domState[0]]
switch domState {
case libvirt.DOMAIN_NOSTATE, libvirt.DOMAIN_SHUTDOWN, libvirt.DOMAIN_SHUTOFF, libvirt.DOMAIN_CRASHED:
// TODO blocked state
if cli.IsDown(domState) {
err := dom.Create()
if err != nil {
logging.DefaultLogger().Object(vm).Error().Reason(err).Msg("Starting the VM failed.")
return nil, err
}
logging.DefaultLogger().Object(vm).Info().Msg("Domain started.")
l.recorder.Event(vm, kubev1.EventTypeNormal, v1.Started.String(), "VM started.")
case libvirt.DOMAIN_PAUSED:
} else if cli.IsPaused(domState) {
// TODO: if state change reason indicates a system error, we could try something smarter
err := dom.Resume()
if err != nil {
Expand All @@ -250,9 +254,8 @@ func (l *LibvirtDomainManager) SyncVM(vm *v1.VM) (*api.DomainSpec, error) {
}
logging.DefaultLogger().Object(vm).Info().Msg("Domain resumed.")
l.recorder.Event(vm, kubev1.EventTypeNormal, v1.Resumed.String(), "VM resumed")
default:
} else {
// Nothing to do
// TODO: blocked state
}

xmlstr, err := dom.GetXMLDesc(0)
Expand Down Expand Up @@ -339,3 +342,18 @@ func (l *LibvirtDomainManager) KillVM(vm *v1.VM) error {
l.recorder.Event(vm, kubev1.EventTypeNormal, v1.Deleted.String(), "VM undefined")
return nil
}

func (l *LibvirtDomainManager) setDomainXML(vm *v1.VM, wantedSpec api.DomainSpec) (cli.VirDomain, error) {
xmlStr, err := xml.Marshal(&wantedSpec)
if err != nil {
logging.DefaultLogger().Object(vm).Error().Reason(err).Msg("Generating the domain XML failed.")
return nil, err
}
logging.DefaultLogger().Object(vm).Info().V(3).With("xml", xmlStr).Msgf("Domain XML generated.")
dom, err := l.virConn.DomainDefineXML(string(xmlStr))
if err != nil {
logging.DefaultLogger().Object(vm).Error().Reason(err).Msg("Defining the VM failed.")
return nil, err
}
return dom, nil
}
1 change: 1 addition & 0 deletions pkg/virt-handler/virtwrap/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ var _ = Describe("Manager", func() {
mockConn.EXPECT().ListSecrets().Return(make([]string, 0, 0), nil)
mockConn.EXPECT().LookupDomainByName(testDomainName).Return(mockDomain, nil)
mockDomain.EXPECT().GetState().Return(state, 1, nil)
mockConn.EXPECT().DomainDefineXML(string(xml)).Return(mockDomain, nil)
mockDomain.EXPECT().Create().Return(nil)
mockDomain.EXPECT().GetXMLDesc(libvirt.DomainXMLFlags(0)).Return(string(xml), nil)
manager, _ := NewLibvirtDomainManager(mockConn, recorder, mockDetector)
Expand Down

0 comments on commit a22cfee

Please sign in to comment.