-
Notifications
You must be signed in to change notification settings - Fork 6
Replace manual process handling by local_cmd() #359
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
base: master
Are you sure you want to change the base?
Conversation
31da723 to
33bd187
Compare
|
I didn't manage to test everything because I don't know yet how to setup some tests. |
Can you list the ones you could test and the ones you couldn't? We could likely either help you run the remaining ones, or have them run on the CI hosts from your branch. |
Sure, I did:
I think we need to test the following:
|
|
Ok, so the first one and the third one are not covered by the main CI runs, they're in installation/upgrade tests that @ydirson is much knowledgeable about. The |
|
Update:
|
You should be able to use it to launch an automated install of a nested host
This one requires 2 hosts to be compared, it should be possible to run using any 2 nested hosts (eg. the one you installed by hand, and one installed with |
conftest.py
Outdated
| # TODO: put that in lib/netutils ? | ||
| wait_for(lambda: commands.local_cmd(['nc', '-zw5', host_vm.ip, '22'], check=False), |
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, a reusable func in netutils for this, and one for ping, look like a good idea
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.
Done.
I did have an issue with a kind of recursive import with wrap_ip, so move the import inside calling function.
9d42bbb to
9bfd3cc
Compare
9bfd3cc to
49fbbca
Compare
And change a bit local_cmd() interface to behave like ssh(); introdice simple_output argument. Signed-off-by: Emmanuel Varagnat <emmanuel.varagnat@vates.tech>
Specific error messages are no longer available with this refactoring. Signed-off-by: Emmanuel Varagnat <emmanuel.varagnat@vates.tech>
49fbbca to
27b9248
Compare
Signed-off-by: Emmanuel Varagnat <emmanuel.varagnat@vates.tech>
27b9248 to
233a249
Compare
| assert False, "unexpected type" | ||
|
|
||
| def scp(hostname_or_ip, src, dest, check=True, suppress_fingerprint_warnings=True, local_dest=False): | ||
| from lib.netutil import wrap_ip |
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 suppose there's a reason for not importing at the top level, but such exception should be documented with a comment.
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 to avoid cycling import. Or I should have put the new function in something different than netutils.
Or maybe you prefer that the local import be done in netutils ? It should not make any diffrence.
I will add a comment anyway.
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.
Comment added
| Returns path to signed image. | ||
| """ | ||
| assert self._owner_cert is not None | ||
| assert self._owner_cert.key is not None |
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'm not sure how this change relates to the rest of the commit
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 here to please type checking since I added type checking information for local_cmd()
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.
Thanks. Probably something to mention in the commit message, as it's not obvious.
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.
Done
ydirson
left a comment
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.
There is also an "introdice" typo in the first commit message
lib/host.py
Outdated
| wait_for(lambda: not os.system(f"ping -c1 {self.hostname_or_ip} > /dev/null 2>&1"), | ||
| wait_for(lambda: commands.local_cmd(['ping', '-c1', self.hostname_or_ip], check=False), | ||
| "Wait for host up", timeout_secs=10 * 60, retry_delay_secs=10) | ||
| wait_for(lambda: not os.system(f"nc -zw5 {self.hostname_or_ip} 22"), | ||
| wait_for(lambda: commands.local_cmd(['nc', '-zw5', self.hostname_or_ip, '22'], check=False), |
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.
That part wrongly interprets LocalCommandResult as a bool, and gets fixed later in the port-knock patch.
| process = subprocess.Popen( | ||
| [fsdiff, "--reference-host", f"{hosts[0]}", "--test-host", f"{hosts[1]}", "--json-output"], | ||
| stdout=subprocess.PIPE, stderr=subprocess.PIPE | ||
| ) | ||
| stdout, _ = process.communicate() | ||
|
|
||
| if process.returncode != 0: | ||
| print(stdout.decode()) | ||
|
|
||
| assert process.returncode == 0 | ||
| res = local_cmd([fsdiff, "--reference-host", f"{hosts[0]}", | ||
| "--test-host", f"{hosts[1]}", | ||
| "--json-output"], simple_output=False) | ||
| assert res.returncode == 0 |
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.
Doesn't this change the behavior, when we were only showing stdout when a non-expected diff occurs?
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.
Absolutely !
Fixed
| if simple_output: | ||
| return output.strip() | ||
| return LocalCommandResult(res.returncode, output) |
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.
Making the default simple_output=True actually changes the default behavior of the function. A separate commit for this change would make it easier for review.
| def wait_for_port_knock(host, port, ping=True): | ||
| if ping: | ||
| wait_for(lambda: local_cmd(['ping', '-c1', host], check=False, simple_output=False).returncode == 0, | ||
| "Wait for host up", timeout_secs=10 * 60, retry_delay_secs=10) | ||
| wait_for(lambda: local_cmd(['nc', '-zw5', host, str(port)], check=False, simple_output=False).returncode == 0, | ||
| "Wait for ssh up on host", timeout_secs=10 * 60, retry_delay_secs=5) | ||
|
|
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.
That's not what's usually been known as "port knocking" (ie. sequence of packets to different ports to cause a firewall to open a port).
Also the fact we only ever use it for ssh is still reflected in the "Wait for ssh up on host" string, but we're losing information from places (eg. "Wait for ssh up on nested host").
Maybe just call it wait_for_ssh, and pass a descriptive string as parameter for the the logs?
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.
It was initially called wait_for_ssh() 😉
|
|
||
| def scp(hostname_or_ip, src, dest, check=True, suppress_fingerprint_warnings=True, local_dest=False): | ||
| from lib.netutil import wrap_ip | ||
|
|
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 do we need this import inside a function? This seems unrelated, and is usually frowned upon.
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.
To avoid cyclic import. Same comment here #359 (comment)
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.
Comment added
| from pkgfixtures import formatted_and_mounted_ext4_disk, sr_disk_wiped | ||
| from pkgfixtures import formatted_and_mounted_ext4_disk, sr_disk_wiped # noqa |
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 is this "noqa" for? Might be good to bundle with a comment explaining it.
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 did not understand the big comment which looks like a big warning so I left the code.
But the reason for the noqa is that a linter is telling that these imports are not used.
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.
And actually they're used, but in an automagical way by pytest, so indeed the linter is confused. I agree with Yann: let's add a comment to explain why "noqa" so that we don't ask the question again in the future.
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.
Done
| if is_uuid(ref): | ||
| if is_uuid(ref): # noqa |
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 is this "noqa" for? Might be good to bundle with a comment explaining it.
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.
To please a linter, because it tells that that double if is no needed because we return refin both cases, and that could be expressed with a or and a single return.
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.
Fixed. noqa was removed and test changed
No description provided.