-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Basic Windows support #35
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for taking on the first pass of adding Windows support to the worker agent. This is a great first step towards an important feature. It seems like this is a partial implementation, which is fine.
The biggest blocker to shipping this code is setting expectations for those using it. Specifically, if we don't yet support isolation of OS users then that limitation and its associated risks need to be made clear
EDIT: Sorry, I missed that this was targeting the feature_windows
branch. I presume that we will have OS user impersonation when we merge this feature branch into mainline
. On that basis, we can disregard my concern above.
src/deadline_worker_agent/aws_credentials/queue_boto3_session.py
Outdated
Show resolved
Hide resolved
b0b3bad
to
815735f
Compare
src/deadline_worker_agent/installer/worker.toml.windows.example
Outdated
Show resolved
Hide resolved
src/deadline_worker_agent/installer/worker.toml.windows.example
Outdated
Show resolved
Hide resolved
f4a4ae4
to
e5862ae
Compare
2316e7a
to
e6a880f
Compare
771280c
to
7bf56bf
Compare
@@ -821,9 +853,10 @@ def test_uses_worker_settings( | |||
assert config.capabilities is mock_worker_settings.capabilities | |||
assert config.impersonation.inactive == (not mock_worker_settings.impersonation) | |||
if expected_config_posix_job_user: | |||
posix_user: PosixSessionUser = request.getfixturevalue(expected_config_posix_job_user) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was somewhat confused by this change. Could we instead switch to obtaining the os_user
fixture from normally (as an argument to the test method) and remove the usage of expected_config_posix_job_user
entirely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only approach I found that worked for using a fixture in a parameterize call, but I'm pretty much a python novice so I'll keep experimenting for a little longer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it's a parameterized test, I can't find a cleaner way to get at the fixture as of now. I have added a TODO to revisit whether this can be simplified when we add impersonation on Windows (which is in progress right now).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did it not work to add the os_user
fixture as an argument to the test function along-side the parameterized arguments?
7fc8386
to
f67f6ae
Compare
@@ -28,8 +29,12 @@ def _run_cmd_as(*, user: PosixSessionUser, cmd: list[str]) -> None: | |||
|
|||
def _setup_parent_dir(*, dir_path: Path, owner: SessionUser | None = None) -> None: | |||
if owner is None: | |||
create_perms: int = stat.S_IRWXU | |||
dir_path.mkdir(mode=create_perms, exist_ok=True) | |||
if os.name == "posix": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should there be a try catch here for the possible CalledProcessError?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks.
@@ -20,6 +21,7 @@ | |||
DEFAULT_CONFIG_PATH: dict[str, Path] = { | |||
"darwin": Path("/etc/amazon/deadline/worker.toml"), | |||
"linux": Path("/etc/amazon/deadline/worker.toml"), | |||
"win32": Path(os.path.expandvars(r"%PROGRAMDATA%/Amazon/Deadline/Config/worker.toml")), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you look at how to avoid relying on an environment variable for this path? A brief look suggests SHGetFolderPath is what to use, but I don't see PROGRAMDATA in the enum list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because users can change the environment variables, but not the system API calls. Reducing reliance on env variables makes things more robust.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! :)
But without meaning to be overly argumentative, isn't there a counter argument that a user may change an env var for good reason and would want our code to respect their change?
ade5a04
to
cf7bc6f
Compare
cf7bc6f
to
fc3d58f
Compare
Signed-off-by: Graeme McHale <[email protected]>
fc3d58f
to
f4b0db6
Compare
|
||
subprocess.run( | ||
[ | ||
"icacls", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the job attachments code, they were able to remove the subprocess calls to icacls by using pywin32. IMO we should do the same thing here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree. Consistency would be nice, as would skipping the overhead of using subprocess.
For the record, the reason that I went with this approach in the first place is that I figured Windows IT Admin curious about our code what find it easier to interpret icacls
calls and may be unfamiliar with pywin32.
@@ -20,6 +21,7 @@ | |||
DEFAULT_CONFIG_PATH: dict[str, Path] = { | |||
"darwin": Path("/etc/amazon/deadline/worker.toml"), | |||
"linux": Path("/etc/amazon/deadline/worker.toml"), | |||
"win32": Path(os.path.expandvars(r"%PROGRAMDATA%/Amazon/Deadline/Config/worker.toml")), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because users can change the environment variables, but not the system API calls. Reducing reliance on env variables makes things more robust.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me.
A few small remaining nit-picks but they are not critical for merging
@pytest.fixture | ||
def set_windows_permissions(self) -> MagicMock: | ||
return MagicMock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixture does not appear to be used. It looks like you may have intended to use this on lines 63-68, but ended up using a local mock instead.
@@ -821,9 +853,10 @@ def test_uses_worker_settings( | |||
assert config.capabilities is mock_worker_settings.capabilities | |||
assert config.impersonation.inactive == (not mock_worker_settings.impersonation) | |||
if expected_config_posix_job_user: | |||
posix_user: PosixSessionUser = request.getfixturevalue(expected_config_posix_job_user) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did it not work to add the os_user
fixture as an argument to the test function along-side the parameterized arguments?
from deadline_worker_agent.set_windows_permissions import set_user_restricted_path_permissions | ||
|
||
|
||
class TestSetWindowsPermissions(unittest.TestCase): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Since we use pytest, we don't need to derive from unittest.TestCase
, although pytest allows this for compatibility to make migrating to pytest easier.
class TestSetWindowsPermissions(unittest.TestCase): | |
class TestSetWindowsPermissions: |
Signed-off-by: Josh Usiskin <[email protected]>
What was the problem/requirement? (What/Why)
The DLC worker agent did not start on Windows, and numerous unit tests did not pass.
What was the solution? (How)
Numerous small changes related to removing
NotImplemented
exceptions, using more appropriate file paths etc.User impersonation is not intended to work in this branch at this time, and several of the changes relate to ensuring tests pass when impersonation is not used.
As of 11/6/23 this is targeted at a feature branch, not mainline.
What is the impact of this change?
The worker agent starts, then receives and executes jobs on Windows.
How was this change tested?
Submitting jobs to gamma and ensuring they are picked up and executed by a Windows worker.
Was this change documented?
No currently.
Is this a breaking change?
It is not intended to be.