3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
19 from cmframework.apis import cmerror
22 class CMActivator(object):
23 ansible_bin = '/usr/local/bin/openstack-ansible'
24 admin_user_file = '/etc/admin_user'
27 self.plugin_client = None
29 with open(CMActivator.admin_user_file, 'r') as f:
30 self.admin_user = f.read()
34 # pylint: disable=no-self-use
35 def get_subscription_info(self):
36 """get the subscription filter
38 This API is used to get the re for matching the properties which the
39 activation plugin is concerned about.
43 A string representing the regular expression used to match the
44 properties which the activation plugin is concerned about.
48 CMError can be raised in-case of a failure.
50 raise cmerror.CMError('Not implemented')
52 # pylint: disable=no-self-use, unused-argument
53 def activate_set(self, props):
54 """activate a configuration data addition/update
58 props: A dictionary of name-value pairs representing the changed
63 CMError can be raised in-case of an error
65 raise cmerror.CMError('Not implemented')
67 # pylint: disable=no-self-use, unused-argument
68 def activate_delete(self, props):
69 """activate a configuration data deletion
73 props: A list of deleted property names.
77 CMError can be raised in-case of an error
79 raise cmerror.CMError('Not implemented')
81 # pylint: disable=no-self-use, unused-argument
82 def activate_full(self, target):
83 """perform a full activation
87 target: None if activating all nodes
88 Node name string if activating only one node
92 CMError can be raised in-case of an error
94 raise cmerror.CMError('Not implemented')
96 # pylint: disable=no-self-use
97 def get_plugin_client(self):
98 """get the plugin client object
100 This API can be used by the plugin to get the client object which the
101 plugin can use to access the configuration data. Notice that the data
102 accessed by this is what is stored in the backend. The changed data
103 is passed as argument to the different validate functions.
107 The plugin client object
109 return self.plugin_client
111 def run_playbook(self, playbook, target=None):
112 playbook_dir = os.path.dirname(playbook)
115 arguments.append('-b')
116 arguments.append('-u {}'.format(self.admin_user))
118 arguments.append('--limit {}'.format(target))
119 arguments.append(playbook)
121 cmd = '{} {}'.format(CMActivator.ansible_bin, ' '.join(arguments))
122 out, result = self._run_cmd_as_user(cmd, playbook_dir, self.admin_user)
124 raise cmerror.CMError('Playbook {} failed: {}'.format(playbook, out))
125 logging.debug('Playbook out: %s', out)
127 def _run_cmd_as_user(self, cmd, cwd, user):
128 pw_record = pwd.getpwnam(user)
129 user_name = pw_record.pw_name
130 user_home_dir = pw_record.pw_dir
131 user_uid = pw_record.pw_uid
132 user_gid = pw_record.pw_gid
133 env = os.environ.copy()
134 env['CONFIG_PHASE'] = 'postconfig'
135 env['HOME'] = user_home_dir
136 env['LOGNAME'] = user_name
138 env['USER'] = user_name
139 p = subprocess.Popen(cmd.split(), preexec_fn=self._demote(user_uid, user_gid),
140 cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
141 out, _ = p.communicate()
142 return (out, p.returncode)
144 def _demote(self, user_uid, user_gid):
152 class CMGlobalActivator(CMActivator):
154 super(CMGlobalActivator, self).__init__()
157 class CMLocalActivator(CMActivator):
159 super(CMLocalActivator, self).__init__()
162 def get_hostname(self):
165 This API is used to get the name of the node where activation is
176 def print_type(activator):
177 if isinstance(activator, CMLocalActivator):
178 print 'Local activator'
179 elif isinstance(activator, CMActivator):
184 activator = CMActivator()
185 localactivator = CMLocalActivator()
189 print_type(activator)
190 print_type(localactivator)
194 if __name__ == '__main__':