Merge lp:~jordanrinke/nova/hypervupdate2 into lp:~hudson-openstack/nova/trunk

Proposed by Jordan Rinke
Status: Work in progress
Proposed branch: lp:~jordanrinke/nova/hypervupdate2
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 194 lines (+137/-15)
2 files modified
bin/nova-compute (+57/-7)
nova/virt/hyperv.py (+80/-8)
To merge this branch: bzr merge lp:~jordanrinke/nova/hypervupdate2
Reviewer Review Type Date Requested Status
Todd Willey (community) Needs Fixing
Dan Prince (community) Needs Fixing
Review via email: mp+74499@code.launchpad.net

Description of the change

I had to create a new branch on the local filesystem to fix the execute bit issue.

To post a comment you must log in.
Revision history for this message
Dan Prince (dan-prince) wrote :

+ image_id=instance['image_id'],

Should this be instance['image_ref']?

review: Needs Fixing
Revision history for this message
Jordan Rinke (jordanrinke) wrote :

> + image_id=instance['image_id'],
>
> Should this be instance['image_ref']?

Fixed.

Revision history for this message
Dan Prince (dan-prince) wrote :

Okay. One more thing (sorry I didn't catch this the first time)

The images.fetch call you are using is a bit outdated. Can you merge with nova trunk and update the call so that it passes the nova context as the first argument? We need this to support the ability to download images when using keystone w/ Glance.

review: Needs Fixing
Revision history for this message
Todd Willey (xtoddx) wrote :

There are a couple of spacing issues in hyperv.py

line 91, pass is space over one too far
98, Caption= should be in line with other arg, or 8 spaces indented
same for args to cache_image on 117-122
blank line at end of multiline docstrings
period for single line docstrings

review: Needs Fixing

Unmerged revisions

1533. By Jordan Rinke

image_id to image_ref changes per Dan

1532. By Jordan Rinke

comment typo fix

1531. By Jordan Rinke

new branch to fix execute bit issues and resulting merge problems

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/nova-compute'
2--- bin/nova-compute 2011-08-19 20:25:49 +0000
3+++ bin/nova-compute 2011-09-12 20:07:27 +0000
4@@ -24,7 +24,14 @@
5
6 import os
7 import sys
8+import platform
9+import time
10
11+# check for windows before loading service modules
12+if platform.system() == "Windows":
13+ import win32service
14+ import win32serviceutil
15+
16 # If ../nova/__init__.py exists, add ../ to Python search path, so that
17 # it will override what happens to be installed in /usr/(local/)lib/python...
18 POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
19@@ -39,11 +46,54 @@
20 from nova import service
21 from nova import utils
22
23+class ComputeWin32Service(win32serviceutil.ServiceFramework):
24+ _svc_name_ = "openstack-compute"
25+ _svc_display_name_ = "OpenStack Compute Service"
26+ _svc_description_ = "OpenStack Compute Service Node"
27+
28+ def __init__(self,args):
29+ win32serviceutil.ServiceFramework.__init__(self,args)
30+ # moved the addition of the default flags location and init
31+ # of the flags to inside the class so the service wrapper
32+ # doesnt conflict with the command line variables
33+ utils.default_flagfile()
34+ flags.FLAGS(sys.argv)
35+ logging.setup()
36+ self.isAlive = True
37+
38+ def SvcDoRun(self):
39+ import servicemanager
40+
41+ servicemanager.LogInfoMsg("OpenStack Compute: Starting")
42+
43+ server = service.Service.create(binary='nova-compute')
44+ service.serve(server)
45+
46+ while self.isAlive :
47+ # instead of calling service.wait here we just sleep
48+ # giving us an active loop to exit out of on a stop command
49+ time.sleep(5)
50+
51+ servicemanager.LogInfoMsg("OpenStack Compute: Stopped")
52+
53+ def SvcStop(self):
54+ import servicemanager
55+
56+ servicemanager.LogInfoMsg("OpenStack Compute: Recieved stop signal")
57+ self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
58+ self.isAlive = False
59+
60+
61 if __name__ == '__main__':
62- utils.default_flagfile()
63- flags.FLAGS(sys.argv)
64- logging.setup()
65- utils.monkey_patch()
66- server = service.Service.create(binary='nova-compute')
67- service.serve(server)
68- service.wait()
69+ # If the platform is any windows platform expect to be run as a service
70+ if platform.system() == "Windows":
71+ win32serviceutil.HandleCommandLine(ComputeWin32Service)
72+ else:
73+ # moved default flags and flag init after handling of
74+ # the command line for the Win32 service wrapper
75+ utils.default_flagfile()
76+ flags.FLAGS(sys.argv)
77+ logging.setup()
78+ server = service.Service.create(binary='nova-compute')
79+ service.serve(server)
80+ service.wait()
81
82=== modified file 'nova/virt/hyperv.py'
83--- nova/virt/hyperv.py 2011-09-08 21:10:03 +0000
84+++ nova/virt/hyperv.py 2011-09-12 20:07:27 +0000
85@@ -116,13 +116,13 @@
86
87 def init_host(self, host):
88 #FIXME(chiradeep): implement this
89- LOG.debug(_('In init host'))
90- pass
91+ pass
92
93 def list_instances(self):
94 """ Return the names of all the instances known to Hyper-V. """
95 vms = [v.ElementName \
96- for v in self._conn.Msvm_ComputerSystem(['ElementName'])]
97+ for v in self._conn.Msvm_ComputerSystem(['ElementName'], \
98+ Caption="Virtual Machine")]
99 return vms
100
101 def list_instances_detail(self):
102@@ -146,11 +146,18 @@
103 raise exception.InstanceExists(name=instance.name)
104
105 #Fetch the file, assume it is a VHD file.
106- base_vhd_filename = os.path.join(FLAGS.instances_path,
107- instance.name)
108- vhdfile = "%s.vhd" % (base_vhd_filename)
109- images.fetch(instance['image_ref'], vhdfile,
110- instance['user_id'], instance['project_id'])
111+ base_vhd_folder = os.path.join(FLAGS.instances_path, instance.name)
112+ if not os.path.exists(base_vhd_folder):
113+ LOG.debug(_('Creating folder %s '), base_vhd_folder)
114+ os.mkdir(base_vhd_folder)
115+ vhdfile = os.path.join(base_vhd_folder, instance.name + ".vhd")
116+ self._cache_image(fn=self._fetch_image,
117+ target=vhdfile,
118+ fname=instance['image_ref'],
119+ cow=FLAGS.use_cow_images,
120+ image_id=instance['image_ref'],
121+ user=instance['user_id'],
122+ project=instance['project_id'])
123
124 try:
125 self._create_vm(instance)
126@@ -506,3 +513,68 @@
127 def set_host_enabled(self, host, enabled):
128 """Sets the specified host's ability to accept new instances."""
129 pass
130+
131+ def _cache_image(self, fn, target, fname, cow=False, *args, **kwargs):
132+ """Wrapper for a method that creates an image that caches the image.
133+
134+ This wrapper will save the image into a common store and create a
135+ copy for use by the hypervisor.
136+
137+ The underlying method should specify a kwarg of target representing
138+ where the image will be saved.
139+
140+ fname is used as the filename of the base image. The filename needs
141+ to be unique to a given image.
142+
143+ If cow is True, it will make a CoW image instead of a copy.
144+ """
145+ if not os.path.exists(target):
146+ base_dir = os.path.join(FLAGS.instances_path, '_base')
147+ if not os.path.exists(base_dir):
148+ os.mkdir(base_dir)
149+ base = os.path.join(base_dir, fname + ".vhd")
150+ if not os.path.exists(base):
151+ fn(target=base, *args, **kwargs)
152+
153+ LOG.debug("use_cow_image:%s", cow)
154+ if cow:
155+
156+ image_service = self._conn.query("Select * from Msvm_ImageManagementService")[0]
157+ (job, ret_val) = image_service.CreateDifferencingVirtualHardDisk(Path=target, ParentPath=base)
158+ LOG.debug("Creating difference disk: JobID=%s, Source=%s, Target=%s", job, base, target)
159+
160+ if ret_val == WMI_JOB_STATUS_STARTED:
161+ success = self._check_job_status(job)
162+ else:
163+ success = (ret_val == 0)
164+
165+ if not success:
166+ raise Exception(_('Failed to create Difference Disk from %s to '), base, target)
167+
168+ """ Testing out the built in job watch method but holding this code incase.
169+ job_wmi_path = "%s" % str(job_id)
170+ job_wmi_path = job_wmi_path.replace('\\\\','\\')
171+ job_wmi_path = job_wmi_path.replace('\\','/')
172+ job_wmi_path = job_wmi_path[3:-8]
173+ storage_job = wmi.WMI(moniker=job_wmi_path)
174+ while storage_job.JobState == WMI_JOB_STATE_RUNNING or storage_job.JobState == WMI_JOB_STATE_STARTING:
175+ LOG.debug("Difference disk progress(%s): %s ", storage_job.JobState, storage_job.PercentComplete)
176+ time.sleep(5)
177+ storage_job = wmi.WMI(moniker=job_wmi_path)
178+
179+ if storage_job.JobState != WMI_JOB_STATE_COMPLETED:
180+ LOG.error(_("Failed to create difference disk: %s %s"), storage_job.ErrorDescription, storage_job.ErrorCode)
181+ raise Exception(_("Failed to create difference disk: %s %s"), storage_job.ErrorDescription, storage_job.ErrorCode)
182+ """
183+ else:
184+ fn(target, *args, **kwargs)
185+
186+ # Trying to use code directly from vish/libvirt for familiarity/compatability
187+ def _fetch_image(self, target, image_id, user, project, size=None):
188+ """Grab image and optionally attempt to resize it"""
189+ images.fetch(image_id, target, user, project)
190+ if size:
191+ LOG.debug("Sizing is unsupported currently")
192+ #TODO add this - this is the funadmental start
193+ # image_service = self._conn.query("Select * from Msvm_ImageManagementService")[0]
194+ # return_value = ExpandVirtualHardDisk(Path=target, MaxInternalSize=)