def signal_handler(self, sig, frame):
     Prompt.notice("\nCtrl-c captured.  Executing teardown function.")
     if not self.kill_captured:
         self.kill_captured = True
         self.cleanup()
         self.on_sig_kill()
     sys.exit(0)
    def validate(self):
        with open(self.options['config'], 'r') as f:
            self.config = json.load(f)
        self.config['ROOT_DIR'] = os.getcwd()
        missing = []
        for item in self.validation_config:
            key = item['key']
            required = item['required']
            key_found = key in self.config or key in os.environ

            if not self.config.get(key):
                self.config[key] = os.environ.get(key, "")
            if (not key_found and required) or (key_found and required
                                                and not self.config[key]):
                missing.append(item)
            elif not required and not self.config[key]:
                warning = f"Config missing optional field: {key} - {Colors.WARNING}{item['description']}"
                if item.get('default-message'):
                    warning += f" - {Colors.CYAN}{item['default-message']}"
                Prompt.notice(warning)
        if missing:
            missing_formatted = [
                f"{x['key']}: {x['description']}" for x in missing
            ]
            Prompt.error(
                f"The following keys are missing/empty from your env or config file: {missing_formatted}",
                close=True)

        # Prepares build files if provided
        super().docker_tmp_file_handler(self.config, self.TMP_BUILD_FILES)
 def __docker_build_tmp_files_cleanup(self, base_path, file_path,
                                      tmp_build):
     if os.path.isdir(file_path):
         dest = os.path.join(base_path,
                             f"{os.path.basename(file_path)}.zip")
     else:
         dest = os.path.join(base_path, os.path.basename(file_path))
     os.remove(dest)
     Prompt.notice(
         f"Removed build artifact for image: {tmp_build['image']} - {dest}")
 def __docker_build_tmp_files_copy(self, base_path, file_path, tmp_build,
                                   config, key):
     if os.path.isdir(file_path):
         dest = make_archive(
             os.path.join(base_path, os.path.basename(file_path)), 'zip',
             file_path)
         config[f"BUILD_FILE_{key}"] = f"{os.path.basename(file_path)}.zip"
     else:
         dest = os.path.join(base_path, os.path.basename(file_path))
         copyfile(file_path, dest)
         config[f"BUILD_FILE_{key}"] = os.path.basename(dest)
     Prompt.notice(
         f"Copied build file for image: {tmp_build['image']} - {dest}")
 def check_ports(self):
     Prompt.notice(
         f"Checking if ports are available for deployment: {self.REQUIRED_PORTS}"
     )
     import socket
     ports_in_use = []
     for port in self.REQUIRED_PORTS:
         with closing(socket.socket(socket.AF_INET,
                                    socket.SOCK_STREAM)) as sock:
             if sock.connect_ex(('127.0.0.1', port)) == 0:
                 ports_in_use.append(port)
     if ports_in_use:
         Prompt.error(
             f"Cannot deploy.  The following ports are in use: {ports_in_use}",
             close=True)
 def execute(self,
             cmd,
             env_dict,
             display_stdout=True,
             on_error_fn=None,
             show_env=False,
             display_stderr=True):
     env = os.environ.copy()
     normalized_dict = {}
     for key, value in env_dict.items():
         if isinstance(value, (list, dict)):
             value = json.dumps(value)
         if value is None:
             value = ""
         normalized_dict[key] = value
     env.update(normalized_dict)
     output = ""
     Prompt.notice(f"Executing command: {Colors.WARNING}{cmd}")
     if show_env:
         Prompt.notice(
             f"Environment Variables: {json.dumps(env_dict, indent=4, sort_keys=True)}"
         )
     args = dict(stdout=subprocess.PIPE, bufsize=0, env=env, shell=True)
     if not display_stderr:
         args.update(dict(stderr=subprocess.DEVNULL))
     with subprocess.Popen(cmd, **args) as proc:
         for line in proc.stdout:
             formatted = line.rstrip().decode('utf-8', 'ignore')
             output += formatted
             if display_stdout:
                 print(formatted)
     if proc.returncode != 0:
         if on_error_fn:
             on_error_fn()
         Prompt.error(
             f"[{cmd}] Failed [code:{proc.returncode}]- {proc.stderr}",
             close=True)
     return output
Esempio n. 7
0
 def on_complete(self):
     Prompt.notice(
         f"Next step: {Colors.CYAN}python run.py deploy --type docker-compose --config configuration.json"
     )