|
1 # Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. |
|
2 # |
|
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
4 # not use this file except in compliance with the License. You may obtain |
|
5 # a copy of the License at |
|
6 # |
|
7 # http://www.apache.org/licenses/LICENSE-2.0 |
|
8 # |
|
9 # Unless required by applicable law or agreed to in writing, software |
|
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
12 # License for the specific language governing permissions and limitations |
|
13 # under the License. |
|
14 |
|
15 import itertools |
|
16 import os |
|
17 import shutil |
|
18 import subprocess |
|
19 |
|
20 from cloudbaseinit.metadata.services.osconfigdrive import base |
|
21 from oslo_config import cfg |
|
22 from oslo_log import log as oslo_logging |
|
23 |
|
24 opts = [ |
|
25 cfg.StrOpt('tar', default='/usr/bin/tar', |
|
26 help='path to "tar", used to extract ISO ConfigDrive ' |
|
27 'files'), |
|
28 ] |
|
29 CONF = cfg.CONF |
|
30 CONF.register_opts(opts) |
|
31 |
|
32 LOG = oslo_logging.getLogger(__name__) |
|
33 |
|
34 |
|
35 class SolarisConfigDriveManager(base.BaseConfigDriveManager): |
|
36 |
|
37 def __init__(self): |
|
38 super(SolarisConfigDriveManager, self).__init__() |
|
39 |
|
40 def _config_drive_iso_cdrom(self): |
|
41 """ Currently we support iso_cdrom because this is the closest "set" to |
|
42 what we can currently get into the zone. We cannot push a file into |
|
43 the zone without several complicated steps that would be prone to |
|
44 breakage. So we are bringing in the ISO as a device in the zone. This |
|
45 device can then be mounted. The way we present the device to the zone |
|
46 is a read only cdrom like device so we will mount it as a "cdrom". |
|
47 """ |
|
48 LOG.debug("self.target_path = %s" % self.target_path) |
|
49 mountdir = '/root/cbi_cdrom' |
|
50 try: |
|
51 # The device is currently hard coded to c1d1p0 |
|
52 mounted = False |
|
53 if not os.path.exists(mountdir): |
|
54 os.mkdir(mountdir, 0500) |
|
55 |
|
56 subprocess.check_call(['/usr/sbin/mount', '-F', 'hsfs', |
|
57 '/dev/dsk/c1d1p0', mountdir]) |
|
58 |
|
59 mounted = True |
|
60 chkfile = os.path.join(mountdir, 'openstack/latest/meta_data.json') |
|
61 if os.path.exists(chkfile): |
|
62 os.rmdir(self.target_path) |
|
63 os.mkdir(self.target_path, 0500) |
|
64 copycmd = ['/usr/bin/cp', '-rp'] |
|
65 for d in os.listdir(mountdir): |
|
66 copycmd.append(mountdir + '/' + d) |
|
67 |
|
68 copycmd.append(self.target_path) |
|
69 subprocess.check_call(copycmd) |
|
70 else: |
|
71 return False |
|
72 except Exception as ex: |
|
73 LOG.error("Get config drive data failed: %s" % ex) |
|
74 return False |
|
75 finally: |
|
76 if mounted: |
|
77 subprocess.call(['/usr/sbin/umount', mountdir]) |
|
78 os.rmdir(mountdir) |
|
79 # Set the property to complete the mount/copy/umount process and |
|
80 # release the BUILD status in the controller. |
|
81 subprocess.call(['/usr/sbin/svccfg', '-s', |
|
82 'cloudbase-init:default', 'setprop', |
|
83 'configdrive/copydone', '=', 'true']) |
|
84 |
|
85 return True |
|
86 |
|
87 def _config_drive_iso_hdd(self): |
|
88 """ Currently not supported |
|
89 """ |
|
90 LOG.error("iso/hdd is currently not supported") |
|
91 return False |
|
92 |
|
93 def _config_drive_iso_partition(self): |
|
94 """ Currently not supported |
|
95 """ |
|
96 LOG.error("iso/partition is currently not supported") |
|
97 return False |
|
98 |
|
99 def _config_drive_vfat_cdrom(self): |
|
100 """ Currently not supported |
|
101 """ |
|
102 LOG.error("vfat/cdrom is currently not supported") |
|
103 return False |
|
104 |
|
105 def _config_drive_vfat_hdd(self): |
|
106 """ Currently not supported |
|
107 """ |
|
108 LOG.error("vfat/hdd is currently not supported") |
|
109 return False |
|
110 |
|
111 def _config_drive_vfat_partition(self): |
|
112 """ Currently not supported |
|
113 """ |
|
114 LOG.error("vfat/partition is currently not supported") |
|
115 return False |
|
116 |
|
117 def get_config_drive_files(self, searched_types=None, |
|
118 searched_locations=None): |
|
119 # The problem we face is that the type and locations are not really |
|
120 # relevant because we do not literally inject the config drive file |
|
121 # into the zone. We provide an iso as a device to the zone which can |
|
122 # then be mounted as a cdrom (readonly device) and then the data |
|
123 # extracted from there. So looping through like this isn't really |
|
124 # going to buy much, but we get simply write those methods as not |
|
125 # supported yet. |
|
126 # |
|
127 # A lot of this will change once we can truly inject files into the |
|
128 # zone. |
|
129 for cd_type, cd_location in itertools.product(searched_types, |
|
130 searched_locations): |
|
131 LOG.info('Looking for Config Drive %(type)s in %(location)s', |
|
132 {"type": cd_type, "location": cd_location}) |
|
133 find_drive = getattr(self, "_config_drive_" + cd_type + '_' + |
|
134 cd_location) |
|
135 if find_drive(): |
|
136 return True |
|
137 |
|
138 return False |