diff options
author | Jordan R Abrahams-Whitehead <ajordanr@google.com> | 2023-06-30 21:48:23 +0000 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-07-07 14:12:21 +0000 |
commit | b512a4b3d22fe924647233824f5d2dca43ec5f2b (patch) | |
tree | 98fb89940e5b010e854cc08aa44c8799d1608268 | |
parent | aaa2a2a2ec82e674bb8f916f5b5e47cc154fa0e9 (diff) | |
download | toolchain-utils-b512a4b3d22fe924647233824f5d2dca43ec5f2b.tar.gz |
cros_utils: Clean command_executor in email_sender
In an attempt to free ourselves from command_executor, this commit
replaces command_executor with subrprocess, which has both a nicer
interface and also doesn't rely on broken scripts.
This is part of a general clean up process to help us not use
remote_access.sh
BUG=b:289058911
TEST=run_tests_for cros_utils/*
Change-Id: I18199ba3ad2bb4eb33412d02fb303cd5196b6017
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/4659483
Reviewed-by: George Burgess <gbiv@chromium.org>
Tested-by: George Burgess <gbiv@chromium.org>
Commit-Queue: George Burgess <gbiv@chromium.org>
-rwxr-xr-x | cros_utils/email_sender.py | 86 |
1 files changed, 41 insertions, 45 deletions
diff --git a/cros_utils/email_sender.py b/cros_utils/email_sender.py index ccf4c1b4..b47c3beb 100755 --- a/cros_utils/email_sender.py +++ b/cros_utils/email_sender.py @@ -1,6 +1,4 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- - # Copyright 2019 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -19,10 +17,9 @@ import getpass import json import os import smtplib +import subprocess import tempfile -from cros_utils import command_executer - X20_PATH = "/google/data/rw/teams/c-compiler-chrome/prod_emails" @@ -31,7 +28,7 @@ X20_PATH = "/google/data/rw/teams/c-compiler-chrome/prod_emails" def AtomicallyWriteFile(file_path): temp_path = file_path + ".in_progress" try: - with open(temp_path, "w") as f: + with open(temp_path, "w", encoding="utf-8") as f: yield f os.rename(temp_path, file_path) except: @@ -39,10 +36,10 @@ def AtomicallyWriteFile(file_path): raise -class EmailSender(object): +class EmailSender: """Utility class to send email through SMTP or SendGMR.""" - class Attachment(object): + class Attachment: """Small class to keep track of attachment info.""" def __init__(self, name, content): @@ -61,27 +58,29 @@ class EmailSender(object): """Enqueues an email in our x20 outbox. These emails ultimately get sent by the machinery in - //depot/google3/googleclient/chrome/chromeos_toolchain/mailer/mail.go. This - kind of sending is intended for accounts that don't have smtp or gmr access - (e.g., role accounts), but can be used by anyone with x20 access. + //depot/google3/googleclient/chrome/chromeos_toolchain/mailer/mail.go. + This kind of sending is intended for accounts that don't have smtp or + gmr access (e.g., role accounts), but can be used by anyone with x20 + access. - All emails are sent from `mdb.c-compiler-chrome+${identifier}@google.com`. + All emails are sent from + `mdb.c-compiler-chrome+${identifier}@google.com`. Args: - subject: email subject. Must be nonempty. - identifier: email identifier, or the text that lands after the `+` in the - "From" email address. Must be nonempty. - well_known_recipients: a list of well-known recipients for the email. - These are translated into addresses by our mailer. - Current potential values for this are ('detective', - 'cwp-team', 'cros-team', 'mage'). Either this or - direct_recipients must be a nonempty list. - direct_recipients: @google.com emails to send addresses to. Either this - or well_known_recipients must be a nonempty list. - text_body: a 'text/plain' email body to send. Either this or html_body - must be a nonempty string. Both may be specified - html_body: a 'text/html' email body to send. Either this or text_body - must be a nonempty string. Both may be specified + subject: email subject. Must be nonempty. + identifier: email identifier, or the text that lands after the + `+` in the "From" email address. Must be nonempty. + well_known_recipients: a list of well-known recipients for the + email. These are translated into addresses by our mailer. + Current potential values for this are ('detective', + 'cwp-team', 'cros-team', 'mage'). Either this or + direct_recipients must be a nonempty list. + direct_recipients: @google.com emails to send addresses to. Either + this or well_known_recipients must be a nonempty list. + text_body: a 'text/plain' email body to send. Either this or + html_body must be a nonempty string. Both may be specified + html_body: a 'text/html' email body to send. Either this or + text_body must be a nonempty string. Both may be specified """ # `str`s act a lot like tuples/lists. Ensure that we're not accidentally # iterating over one of those (or anything else that's sketchy, for that @@ -241,8 +240,6 @@ class EmailSender(object): attachments, ): """Send email via sendgmr program.""" - ce = command_executer.GetCommandExecuter(log_level="none") - if not email_from: email_from = getpass.getuser() + "@google.com" @@ -260,30 +257,29 @@ class EmailSender(object): f.flush() to_be_deleted.append(f.name) - # Fix single-quotes inside the subject. In bash, to escape a single quote - # (e.g 'don't') you need to replace it with '\'' (e.g. 'don'\''t'). To - # make Python read the backslash as a backslash rather than an escape - # character, you need to double it. So... + # Fix single-quotes inside the subject. In bash, to escape a single + # quote (e.g 'don't') you need to replace it with '\'' (e.g. + # 'don'\''t'). To make Python read the backslash as a backslash + # rather than an escape character, you need to double it. So... subject = subject.replace("'", "'\\''") + command = [ + "sendgmr", + f"--to={to_list}", + f"--from={email_from}", + f"--subject={subject}", + ] if msg_type == "html": - command = ( - "sendgmr --to='%s' --from='%s' --subject='%s' " - "--html_file='%s' --body_file=/dev/null" - % (to_list, email_from, subject, f.name) - ) + command += [f"--html_file={f.name}", "--body_file=/dev/null"] else: - command = ( - "sendgmr --to='%s' --from='%s' --subject='%s' " - "--body_file='%s'" % (to_list, email_from, subject, f.name) - ) + command.append(f"--body_file={f.name}") if email_cc: cc_list = ",".join(email_cc) - command += " --cc='%s'" % cc_list + command.append(f"--cc={cc_list}") if email_bcc: bcc_list = ",".join(email_bcc) - command += " --bcc='%s'" % bcc_list + command.append(f"--bcc={bcc_list}") if attachments: attachment_files = [] @@ -302,12 +298,12 @@ class EmailSender(object): f.flush() attachment_files.append(f.name) files = ",".join(attachment_files) - command += " --attachment_files='%s'" % files + command.append(f"--attachment_files={files}") to_be_deleted += attachment_files # Send the message via our own GMR server. - status = ce.RunCommand(command) - return status + completed_process = subprocess.run(command, check=False) + return completed_process.returncode finally: for f in to_be_deleted: |