/usr/lib/python3/dist-packages/google_compute_engine/metadata_scripts/script_executor.py is in python3-google-compute-engine 20180129+dfsg1-0ubuntu3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #!/usr/bin/python
# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Execute user provided metadata scripts."""
import os
import stat
import subprocess
from google_compute_engine import constants
class ScriptExecutor(object):
"""A class for executing user provided metadata scripts."""
def __init__(self, logger, script_type):
"""Constructor.
Args:
logger: logger object, used to write to SysLog and serial port.
script_type: string, the type of the script we are running.
"""
self.logger = logger
self.script_type = script_type
def _MakeExecutable(self, metadata_script):
"""Add executable permissions to a file.
Args:
metadata_script: string, the path to the executable file.
"""
mode = os.stat(metadata_script).st_mode
os.chmod(metadata_script, mode | stat.S_IEXEC)
def _RunScript(self, metadata_key, metadata_script):
"""Run a script and log the streamed script output.
Args:
metadata_key: string, the key specifing the metadata script.
metadata_script: string, the file location of an executable script.
"""
process = subprocess.Popen(
metadata_script, shell=True,
executable=constants.LOCALBASE + '/bin/bash',
stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
while True:
for line in iter(process.stdout.readline, b''):
message = line.decode('utf-8', 'replace').rstrip('\n')
if message:
self.logger.info('%s: %s', metadata_key, message)
if process.poll() is not None:
break
self.logger.info('%s: Return code %s.', metadata_key, process.returncode)
def RunScripts(self, script_dict):
"""Run the metadata scripts; execute a URL script first if one is provided.
Args:
script_dict: a dictionary mapping metadata keys to script files.
"""
metadata_types = ['%s-script-url', '%s-script']
metadata_keys = [key % self.script_type for key in metadata_types]
metadata_keys = [key for key in metadata_keys if script_dict.get(key)]
if not metadata_keys:
self.logger.info('No %s scripts found in metadata.', self.script_type)
for metadata_key in metadata_keys:
metadata_script = script_dict.get(metadata_key)
self._MakeExecutable(metadata_script)
self._RunScript(metadata_key, metadata_script)
|