|
1 #!/usr/bin/python |
|
2 # |
|
3 # CDDL HEADER START |
|
4 # |
|
5 # The contents of this file are subject to the terms of the |
|
6 # Common Development and Distribution License (the "License"). |
|
7 # You may not use this file except in compliance with the License. |
|
8 # |
|
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
10 # or http://www.opensolaris.org/os/licensing. |
|
11 # See the License for the specific language governing permissions |
|
12 # and limitations under the License. |
|
13 # |
|
14 # When distributing Covered Code, include this CDDL HEADER in each |
|
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
16 # If applicable, add the following below this CDDL HEADER, with the |
|
17 # fields enclosed by brackets "[]" replaced with your own identifying |
|
18 # information: Portions Copyright [yyyy] [name of copyright owner] |
|
19 # |
|
20 # CDDL HEADER END |
|
21 # |
|
22 |
|
23 # |
|
24 # Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. |
|
25 # |
|
26 |
|
27 """ target_selection_zone.py - Select Install Target(s) |
|
28 """ |
|
29 |
|
30 import copy |
|
31 import platform |
|
32 |
|
33 from solaris_install import ApplicationData |
|
34 from solaris_install.engine import InstallEngine |
|
35 from solaris_install.target import Target |
|
36 from solaris_install.target.controller import DEFAULT_LOGICAL_NAME |
|
37 from solaris_install.target.instantiation_zone import ALT_POOL_DATASET |
|
38 from solaris_install.target.logical import Logical, BE, Filesystem |
|
39 from solaris_install.auto_install.checkpoints.target_selection import \ |
|
40 TargetSelection, SelectionError |
|
41 |
|
42 |
|
43 class TargetSelectionZone(TargetSelection): |
|
44 """ TargetSelectionZone - Checkpoint to select install target. |
|
45 |
|
46 This checkpoint selects the install target(s) for a zone based on |
|
47 the information provided as the zone's alternate pool dataset and the |
|
48 target information provided in the AI Manifest. |
|
49 |
|
50 If it's not possible to determine a selection, then a SelectionError |
|
51 exception will be raised, causing the installation to fail. |
|
52 """ |
|
53 |
|
54 def __init__(self, name, be_mountpoint="/a"): |
|
55 super(TargetSelection, self).__init__(name) |
|
56 |
|
57 # instance attributes |
|
58 self.be_mountpoint = be_mountpoint |
|
59 self.doc = InstallEngine.get_instance().data_object_cache |
|
60 |
|
61 # set the zone's alternate pool dataset |
|
62 self.selected_dataset = None |
|
63 |
|
64 # set the platform |
|
65 self.arch = platform.processor() |
|
66 |
|
67 def select_targets(self, from_manifest): |
|
68 '''Logic to select the targets for a zone. |
|
69 |
|
70 Given the alternate pool dataset, and the targets from the |
|
71 manifest, make the selections. |
|
72 |
|
73 If no suitable selection can be made, then the SelectionError |
|
74 exception will be raised. This should only be the cause if the |
|
75 selected alternate pool dataset does not exist. |
|
76 |
|
77 Returns a new set of Targets that can be insterted into the |
|
78 Data Object Cache for TargetInstantiationZone to use. |
|
79 |
|
80 ''' |
|
81 |
|
82 # The selected alternate pool dataset must be set |
|
83 if self.selected_dataset is None: |
|
84 raise SelectionError("No dataset selected as alternate pool " |
|
85 "dataset.") |
|
86 |
|
87 # Verify selected dataset exists |
|
88 fs = Filesystem(self.selected_dataset) |
|
89 if not fs.exists: |
|
90 raise SelectionError("Dataset (%s) does not exist." % \ |
|
91 self.selected_dataset) |
|
92 |
|
93 if from_manifest: |
|
94 self.logger.debug("from_manifest =\n%s\n" % \ |
|
95 (str(from_manifest[0]))) |
|
96 else: |
|
97 self.logger.debug("from_manifest is empty\n") |
|
98 |
|
99 |
|
100 # Instantiate desired target, logical, and zpool objects. |
|
101 target = Target(Target.DESIRED) |
|
102 logical = Logical(DEFAULT_LOGICAL_NAME) |
|
103 logical.noswap = True |
|
104 logical.nodump = True |
|
105 zpool = logical.add_zpool(self.selected_dataset) |
|
106 |
|
107 for manifest_target in from_manifest: |
|
108 # Copy filesystem children into desired zpool |
|
109 for fs in manifest_target.get_descendants(class_type=Filesystem): |
|
110 zpool.insert_children(copy.deepcopy(fs)) |
|
111 |
|
112 # Copy BE children into desired zpool |
|
113 for be in manifest_target.get_descendants(class_type=BE): |
|
114 zpool.insert_children(copy.deepcopy(be)) |
|
115 |
|
116 # Check if we have a BE object under zpool. |
|
117 # If not, create one. |
|
118 be_list = zpool.get_children(class_type=BE) |
|
119 if not be_list: |
|
120 # Instantiate new BE object and insert it into zpool. |
|
121 be = BE() |
|
122 zpool.insert_children(be) |
|
123 else: |
|
124 # Zpool will have only one BE object. |
|
125 be = be_list[0] |
|
126 |
|
127 # Set BE's mountpoint to the mountpoint we need |
|
128 # to mount it at to do the installation. |
|
129 be.mountpoint = self.be_mountpoint |
|
130 |
|
131 # Insert desired logical object into the desired target object. |
|
132 target.insert_children(logical) |
|
133 |
|
134 # Insert desired target object into the DOC. |
|
135 self.doc.persistent.insert_children(target) |
|
136 |
|
137 |
|
138 def parse_doc(self): |
|
139 """ Method for locating objects in the data object cache (DOC) for |
|
140 use by the checkpoint. |
|
141 |
|
142 Will return a Data Object reference for the Targets from the |
|
143 manifest. |
|
144 """ |
|
145 |
|
146 from_manifest = self.doc.find_path( |
|
147 "//[@solaris_install.auto_install.ai_instance.AIInstance?2]" |
|
148 "//[@solaris_install.target.Target?2]") |
|
149 |
|
150 app_data = self.doc.persistent.get_first_child( \ |
|
151 class_type=ApplicationData) |
|
152 if app_data: |
|
153 self.selected_dataset = app_data.data_dict.get(ALT_POOL_DATASET) |
|
154 |
|
155 return from_manifest |
|
156 |
|
157 # Implement AbstractCheckpoint methods. |
|
158 def get_progress_estimate(self): |
|
159 """Returns an estimate of the time this checkpoint will take |
|
160 """ |
|
161 return 3 |
|
162 |
|
163 def execute(self, dry_run=False): |
|
164 """ Primary execution method used by the Checkpoint parent class |
|
165 to select the targets during an install. |
|
166 """ |
|
167 self.logger.debug("=== Executing Target Selection Zone Checkpoint ==") |
|
168 |
|
169 from_manifest = self.parse_doc() |
|
170 |
|
171 self.select_targets(from_manifest) |