Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create libvirt xml files from templates with python #343

Merged
merged 10 commits into from
May 26, 2015

Conversation

MaximilianMeister
Copy link
Contributor

No description provided.

@MaximilianMeister MaximilianMeister changed the title [dont merge yet] Create libvirt xml files from templates with python [WIP][dont merge yet] Create libvirt xml files from templates with python May 13, 2015
import argparse
import libvirt_helpers
from string import Template

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are using flake8, I would suggest to follow some 'second-line' rules:

  • Put first (in alphabetically order) the Python libraries (argparse and string)
  • Separated with a line, put the other imports (also sorted) non-python libs (libvirt, libvirt_helpers)

https://www.python.org/dev/peps/pep-0008/#id17

def main():
cloud = args.cloud
cpuflags = libvirt_helpers.cpuflags()
fout = open("/tmp/{0}-admin.xml".format(cloud), "w")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is not used until the end. I would suggest to use with statement:

with open("/tmp/{0}-admin.xml".format(cloud), "w") as f:
    f.write(xml)

http://effbot.org/zone/python-with-statement.htm

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for @aplanas's suggestion.

libvirt_onhost_create_adminnode_config
libvirt_onhost_create_admin_network_config
onhost_local_repository_mount
python ${mkcloud_lib_dir}/libvirt/admin-config.py $cloud $admin_node_memory $adminvcpus $emulator $admin_node_disk "$local_repository_mount"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you can chmod a+x admin-config.py and call as a normal command. In this case even I would recommend removing the .py extension too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, these scripts should definitely be executable. +1 for @aplanas's suggestion here too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Remember that git tracks file permissions too, not just contents.)

fout.write(xml)
fout.close()

if __name__ == "__main__":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same in this file - currently this __name__ check is useless because your CLI-handling code is in the wrong place.

@aspiers
Copy link
Contributor

aspiers commented May 13, 2015

Great work, but please cleanly separate the CLI code from the library code like I suggested.

@MaximilianMeister MaximilianMeister force-pushed the python-libvirt-xml branch 2 times, most recently from eab4112 to d313b98 Compare May 13, 2015 09:35
@MaximilianMeister
Copy link
Contributor Author

thanks for all the input :) i will continue after lunch

@MaximilianMeister
Copy link
Contributor Author

Great work, but please cleanly separate the CLI code from the library code like I suggested.

@aplanas @aspiers
I also had the intention to write this more modular, hence not one CLI for each "function", but I was really not sure how.
e.g. how I should pass all the computed variables that we need from mkcloud, how should I call it from within mkcloud and so on. I was even thinking about one central script with subcommands for each function but I don't know what makes most sense in the long term (and longer... if we go beyond libvirt with mkcloud)

I would definitely need some more help on that from the python side, due to lack of expertise.
So my suggestion would be doing this in a separate PR (maybe with some dedicated discussion of the python experts about the architecture), as it affects also the python scripts that have already been merged. This here is just another small step in the refactoring of mkcloud. What do you suggest?

@aplanas
Copy link
Contributor

aplanas commented May 13, 2015

@MaximilianMeister I see.

So far the logic behind this code is not big. Initially I would put all the functions in a single Python package, and create several CLI (as you did) that parse the args and call the appropriate (and slim) library.

This approach can be used if mkcloud is finally written in Bash or Ruby. But if is done in Python we will need to refactor the library into several new packages with coupled functionality, because it will grow up a lot : )

Do we have a final decision about mkcloud?

@jdsn
Copy link
Member

jdsn commented May 13, 2015

Do we have a final decision about mkcloud?

@aplanas No, we don't. And this is IMHO not related (direclty). The overall goal is to split mkcloud into separate tools (not just libraries). It should become separate tools that can be used individually, and mkcloud is using all of them.
Once mkcloud is small enough we can do a rewrite of it. I see python as the most likely option here (this is where it is related). Once mkcloud itself is python it can use the librarlies of the other tools directly. Until then it will call the scripts (ideally with subcommands, and not one script per function).

@aplanas
Copy link
Contributor

aplanas commented May 13, 2015

@jdsn @MaximilianMeister I can help to refactor this to create subcommands. I will do it after the merge of this PR.

Can we provide some test file for this PR, so we can start the refactoring in a good way?

@MaximilianMeister
Copy link
Contributor Author

I will try to setup some basic unittests as well for now. And maybe extract some of the logic in each CLI into the libvirt_helpers "module", which will be the base for the unittests.

@MaximilianMeister MaximilianMeister force-pushed the python-libvirt-xml branch 2 times, most recently from b4927d4 to c0f91f5 Compare May 13, 2015 14:32
@aspiers
Copy link
Contributor

aspiers commented May 13, 2015

Great work, but please cleanly separate the CLI code from the library code like I suggested.

@aplanas @aspiers
I also had the intention to write this more modular, hence not one CLI for each "function", but I was really not sure how.

No problem, but since then I explained how you can do it :-)

e.g. how I should pass all the computed variables that we need from mkcloud, how should I call it from within mkcloud and so on.

The bash -> python interface you have done is already good. You only need to change the scripts so they're also usable as modules.

I was even thinking about one central script with subcommands for each function but I don't know what makes most sense in the long term (and longer... if we go beyond libvirt with mkcloud)

Big -1 for a single script. Code should always be in small, clean chunks, where each chunk does one thing really well.

I think you're too focused on the CLI aspect. Sure we can support a CLI as long as we need one, but the focus should be on writing reusable, testable, maintainable code, and the right way to do that is to ensure clean separation of concerns into separate modules, and to keep the CLI code separate from the business logic.

I would definitely need some more help on that from the python side, due to lack of expertise.
So my suggestion would be doing this in a separate PR (maybe with some dedicated discussion of the python experts about the architecture), as it affects also the python scripts that have already been merged. This here is just another small step in the refactoring of mkcloud. What do you suggest?

I suggest:

  • make each script reusable as a module by separating the CLI code from the business logic
  • later, move each script into a new module namespace which groups them all together, and move the CLI code into a single script which provides subcommands which delegate to each submodule in that namespace.


cloud = args.cloud
cpuflags = libvirt_helpers.cpuflags()
fin = libvirt_helpers.readfile("templates/admin-node.xml")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still not quite right. The template name is not specific to the CLI code so it doesn't belong here. The goal is ultimately to be able to write something like this from a Python-based mkcloud caller:

import mkcloud.libvirt

...

mkcloud.libvirt.write_admin_node_xml(output_file, values)

targetbus = "virtio"
else:
nicmodel = "virtio"
targetdev = "sda"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should cover all vd* sd*

@MaximilianMeister MaximilianMeister force-pushed the python-libvirt-xml branch 4 times, most recently from 591ea52 to c9d91ec Compare May 22, 2015 08:48
libvirt_modprobe_kvm
libvirt_start_daemon
python ${mkcloud_lib_dir}/libvirt/net-start.py $cloud-admin || exit $?
python ${mkcloud_lib_dir}/libvirt/vm-start.py $cloud-admin || exit $?
${mkcloud_lib_dir}/libvirt/net-start $cloud-admin || exit $?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use full path to xml file here as well

@MaximilianMeister MaximilianMeister force-pushed the python-libvirt-xml branch 3 times, most recently from 3a18f72 to 3f5e763 Compare May 22, 2015 14:08
@jdsn
Copy link
Member

jdsn commented May 22, 2015

👍 but waiting for results of final test run

MaximilianMeister and others added 10 commits May 26, 2015 09:32
Module Fuctions:

* helper methods
* VM + Network XML file creation methods
* VM + Network define/start methods
* cleanup method

Templates:

* XML Templates for VM's, Admin Network, CPU-Flags

Unittests and fixtures:

* helper methods
* VM + Network XML file creation methods

Fixes SUSE-Cloud#345
* remove .py extension and call it without python
* use libvirt_setup module for the business logic
* remove .py extension and call it without python
* use libvirt_setup module for the business logic
* remove .py extension and call it without python
* use libvirt_setup module for the business logic

suseinstall:
sudo zypper install perl-JSON-XS perl-libxml-perl
sudo zypper install perl-JSON-XS perl-libxml-perl libvirt-python

genericinstall:
sudo pip install bashate flake8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may also install libvirt-python in the generic install via. pip

$ pip install libvirt-python

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I find this ugly. There are installations via zypper and others via pip as root. I would never install anything with pip as root in my system. I would suggest two options here:

  • Because python-lake8 is in Factory, so I would submit python-bashate from Cloud:OpenStack:Master for Factory too.
  • and/or use virtualenv to install all the python dependencies that are not in any repository.

@dguitarbite
Copy link
Contributor

I would suggest making the code more modular as Adam did. I would like to note that keeping the test cases in the same folder is a bad idea. May be after splitting mkcloud into multiple repositories, the test cases can lie in their special tests/ folder (but suggest to do it sooner than later).

Some hard coding in the XML files, and some other minor issues which may be carried out in following patches. Looks good to me. +1

jdsn added a commit that referenced this pull request May 26, 2015
Create libvirt xml files from templates with python
@jdsn jdsn merged commit e2f0f0d into SUSE-Cloud:master May 26, 2015
@MaximilianMeister MaximilianMeister deleted the python-libvirt-xml branch May 27, 2015 08:48
aspiers pushed a commit to aspiers/automation that referenced this pull request Aug 10, 2016
The <features> was missing from the VM's libvirt config on
AMD hosts, and this was causing a lack of ACPI support, which
in turn meant that virsh shutdown etc. didn't work, and hence
that mkcloud didn't work properly.

Some history:

A long time ago, 5696c16 originally introduced some logic so
that if the 'npt' (AMD Nested Page Tables) flag was present in
/proc/cpuinfo on the host, the <cpu> section would not be included.

Later, PR SUSE-Cloud#343 switched libvirt VM creation code from bash to Python
with templates, but at this point <features> was always included.

Much more recently, 7fe19ff from PR SUSE-Cloud#1049 moved the <features> section
into the CPU templates, resulting in it missing when the AMD npt flag
was present.  668a415 then added support for other architectures, but
still left AMD broken.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants