Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upConvert Windows builders to use DynamicServoFactory #426
Conversation
|
Thanks for tackling this! |
| @@ -31,6 +31,7 @@ def __add__(self, other): | |||
|
|
|||
| build_windows = build_common + Environment({ | |||
| 'CARGO_HOME': '/home/Administrator/.cargo', | |||
| 'HOME': r'C:\buildbot\slave\windows\build', | |||
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 5, 2016
Member
This seems like an odd choice of $HOME. Why do we need to set it, and why this value?
This comment has been minimized.
This comment has been minimized.
UK992
Jul 5, 2016
Author
Contributor
this set home directory before bash login, so it not needed to add cd command before every command.
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 5, 2016
Member
That's a reasonable hack, but please leave a comment with that explanation for future reference.
| @@ -76,3 +76,12 @@ arm64: | |||
| - ./mach build --rel --target=aarch64-unknown-linux-gnu | |||
| - bash ./etc/ci/lockfile_changed.sh | |||
| - bash ./etc/ci/manifest_changed.sh | |||
|
|
|||
| windows: | |||
| - ./mach build -d -v | |||
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 5, 2016
Member
Let's do ./mach build --dev for consistency. Also, please rename to windows-dev as well.
This comment has been minimized.
This comment has been minimized.
| step_kwargs['command'] = command | ||
|
|
||
| # Add bash -l before every command on Windows builders | ||
| bash_args = ["bash", "-l"] if is_windows() else [] |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
UK992
Jul 5, 2016
Author
Contributor
i leave -c, to avoid quoting every command, i've tested with appveyor and it work that way too.
| @@ -216,6 +235,10 @@ def __init__(self, builder_name, environment): | |||
| ]) | |||
|
|
|||
|
|
|||
| def is_windows(): | |||
| return platform.system() == "Windows" | |||
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 5, 2016
Member
This doesn't work because this code runs on the Buildbot master (Linux). We need to somehow interrogate the builder properties and use that throughout the build. I don't know exactly how to do that.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
UK992
Jul 5, 2016
Author
Contributor
with new approaches not detect windows builder based on builder name
| if is_windows(): | ||
| pkill_command = ["powershell", "kill", "-n", "servo"] | ||
| else: | ||
| pkill_command = ["pkill", "-x", "servo"] |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 5, 2016
Member
Would be nice to factor this out into a little helper function:
def make_pkill_command(target):
...
make_pkill_command("servo")
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 5, 2016
Member
Another option is a script in etc/ci, which neatly steps around the "how to detect Windows" problem.
| if is_windows(): | ||
| step_env = copy.deepcopy(envs.upload_nightly_windows) | ||
| else: | ||
| step_env = copy.deepcopy(envs.upload_nightly) |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 5, 2016
Member
We should just do step_env += envs.upload_nightly and get rid of envs.upload_nightly_windows - would have mentioned this on the earlier PR if it wasn't right before release :)
| @@ -1,6 +1,7 @@ | |||
| import copy | |||
| import os.path | |||
| import re | |||
| import platform | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| @@ -58,31 +59,37 @@ class DynamicServoFactory(ServoFactory): | |||
|
|
|||
| def __init__(self, builder_name, environment): | |||
| self.environment = environment | |||
| is_windows = True if re.match('windows(.*)', builder_name) else False | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| @@ -215,6 +228,12 @@ def __init__(self, builder_name, environment): | |||
| "etc/ci/buildbot_steps.yml") | |||
| ]) | |||
|
|
|||
| def make_pkill_command(target, is_windows): | |||
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 5, 2016
Member
Similarly, I think this makes sense as a class method - please mind the duplication for now :)
This comment has been minimized.
This comment has been minimized.
UK992
Jul 5, 2016
•
Author
Contributor
i don't quite understand, should i add this function to classes DynamicServoYAMLFactory and DynamicServoFactory?
EDIT: i added function to both classes, but i think this is not what you mean. I can restore back to previous state, if needed.
|
I will finish reviewing this either later today or tomorrow. |
c553573
to
c2080f9
| @@ -58,31 +58,38 @@ class DynamicServoFactory(ServoFactory): | |||
|
|
|||
| def __init__(self, builder_name, environment): | |||
| self.environment = environment | |||
| self.is_windows = True if re.match('windows(.*)', | |||
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 6, 2016
Member
We can do self.is_windows = re.match(...) is not None directly instead. Also, no need for the parentheses around the .*.
This comment has been minimized.
This comment has been minimized.
|
|
||
| # util.BuildFactory is an old-style class so we cannot use super() | ||
| # but must hardcode the superclass here | ||
| ServoFactory.__init__(self, pkill_step + dynamic_steps) | ||
|
|
||
| def make_step(self, command): | ||
| def make_step(self, command, is_windows): |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 6, 2016
Member
We can just read from self.is_windows instead of using an extra argument.
This comment has been minimized.
This comment has been minimized.
|
|
||
| step_kwargs['env'] = step_env | ||
| return step_class(**step_kwargs) | ||
|
|
||
| def make_pkill_command(self, target, is_windows): |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| try: | ||
| config_dir = os.path.dirname(os.path.realpath(__file__)) | ||
| yaml_path = os.path.join(config_dir, 'steps.yml') | ||
| with open(yaml_path) as steps_file: | ||
| builder_steps = yaml.safe_load(steps_file) | ||
| commands = builder_steps[builder_name] | ||
| dynamic_steps = [self.make_step(command) for command in commands] | ||
| dynamic_steps = [self.make_step(command, self.is_windows) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| decodeRC={0: SUCCESS, 1: SUCCESS})] | ||
| pkill_step = [steps.ShellCommand( | ||
| command=self.make_pkill_command("servo"), | ||
| decodeRC={0: SUCCESS, 1: SUCCESS} |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jul 6, 2016
Member
Does this decodeRC apply for the powershell command as well? I think it would be better if the make_pkill_command function returned a steps.ShellCommand directly instead of just the command array.
This comment has been minimized.
This comment has been minimized.
UK992
Jul 6, 2016
Author
Contributor
yes it does, if powershell kill doesnt find process, exit with code 1
This comment has been minimized.
This comment has been minimized.
| try: | ||
| config_dir = os.path.dirname(os.path.realpath(__file__)) | ||
| yaml_path = os.path.join(config_dir, 'steps.yml') | ||
| with open(yaml_path) as steps_file: | ||
| builder_steps = yaml.safe_load(steps_file) | ||
| commands = builder_steps[builder_name] | ||
| dynamic_steps = [self.make_step(command) for command in commands] | ||
| dynamic_steps = [self.make_step(command) | ||
| for command in commands] |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
|
||
| step_kwargs['env'] = step_env | ||
| return step_class(**step_kwargs) | ||
|
|
||
| def make_pkill_command(self, target): |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
LGTM to me after squash. Nice thinking with using a regex on the builder name to determine |
|
Squashed! |
|
@bors-servo r+ |
|
|
Convert Windows builders to use DynamicServoFactory I'm not sure if this is the right approaches, but i try. For process kill i used ```powershell kill```, which works from bash and cmd, but needs admin privileges like any other process kill command. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/saltfs/426) <!-- Reviewable:end -->
|
|
UK992 commentedJul 5, 2016
•
edited by larsbergstrom
I'm not sure if this is the right approaches, but i try.
For process kill i used
powershell kill, which works from bash and cmd, but needs admin privileges like any other process kill command.This change is