-
Notifications
You must be signed in to change notification settings - Fork 33
Add session ops utility with some facilitator functions (v2) #98
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
Add session ops utility with some facilitator functions (v2) #98
Conversation
c3ef185
to
4baec9a
Compare
The CI problem detected here is not related to these changes. Not sure how it wasn't detected in earlier pull requests but I will push one to fix it next. |
4baec9a
to
7e7fcfb
Compare
7e7fcfb
to
cd03ecb
Compare
All CI problems fixed and PR can now be fully reviewed. |
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.
Hello @pevogam, I gave it another try after this long time and my feeling is still the same. Although it simplifies certain workflows I don't think it fits aexpect library. I can imagine it as another library that would generate command strings that would be then consumed by aexpect (or other library that allows shell-like interface).
My main problem is the size, the higher-level aim with security checks that are present in many places but in another they are missing (eg. stat(a, "/tmp/a", fmt="%; echo this could as well be formatting your hard drive; ")
.
I can create a repo for you and make you an admin of that, if you are interested, but I don't like the idea of having this in the core aexpect (note ideally I'd extract and publish the remote.py
separately as well, but it's already there...)
Anyway @clebergnu, @lmr please take a look at this and if you decide it belongs here, feel free to give it a try.
By this I mean something like: import aexpect
from aexpect_ops import *
session = aexpect.ShellSession("sh")
session.cmd(stat("/tmp/a"))
session.cmd(copy("/tmp/a", "/tmp/b"))
... (and I know it wouldn't allow the same flexibility, but should suffice the usual use cases) |
Hi @ldoktor,
You might be able to conclude that from the current selection of commands but there are commands that would require only
For sure it might have some limitations that we all expect to be pointed out during review and patched up before merging. I think you could notice that this pull request combines lots of different code from different authors in our team and previously added in different times when they were actually needed. So some unification is definitely to ask but I don't think will be hard to accomplish and this is what reviews are for - to discover maintainers' minimum uniform interface requirements (and leave some divergence that will be unavoidable aside).
Why would the
Another point I want to add here is that we find lots of contributors on the Avocado and Avocado VT side reimplementing a lot of these functions on top of a session again and again which confirms the need to have single reusable source that everybody could instead simply spend their time extending and saving the rest of their costs. As these utilities depend only on aexpect and all they require is a session I don't think it makes sense to keep them in Avocado or Avocado VT repos whcih specialize in something else. Regarding a separate aexpect repo, can you elaborate more on what are the benefits from keeping current aexpect to the minimal code base and functionality it currently has? I would assume reduced maintenance cost and contributor activity is one of them but how would this compare to the cost of managing a separate repo and integrating the two mentioned above? The aexpect repo has not been very active in the last years but this could be viewed both as something good and something not so good (example of the second being contributors that did not want to use it because they thought the project has been abandoned at least in their replies to me). So all in all I would be glad to hear your reasoning regarding keeping an already small project like aexpect bare bone and core-only since at least in my opinion it would rather make sense to split into multiple repos any projects that are much larger than this so that the costs from the splitting are outweighed by the benefits of separate maintenance. |
I haven't seen such commands in this PR and therefore I mentioned that solution. For that kind of usage one would indeed had to depend directly on session usage.
I didn't noticed different authors but i do see different levels of automatic transformation of input params (which probably better describes what I was trying to say before. Some functions transform the flags and trying to be safe, some are not). It's hard to decide but in case we can not guarantee safety I would prefer not trying to be too smart as it might give people false impression the utility handles security for them. It does not and the underlying session uses raw bash and should be only used by people with some level of knowledge of the commands they are trying to execute.
Although I mentioned separate repo, it doesn't have to be that way. Avocado also hosts optional plugins inside the main repo and they can be brought by installing "avocado-framework-plugin-$NAME". Something like that would be nice for aexpect. My reason is that I'm using (and promoting) aexpect as stable and simple utility for automation. Some developers at RH already caught it up and are using it for rebooting machines over serial console, or other simple tasks. I'm also using it in other projects but the cleverer it gets the bigger and potentially more dangerous it gets. I consider aexpect something like cat. It performs well and allows basic operations. One could use tail for similar tasks and even more, but it is more complex and potentially dangerous. And then you have visual studio, which also can perform file operation, allows all kinds of extra features, but is heavy-weight and aimed for different usecases. Now the question is, is aexpect growing to be closer to tail or to vs? In my ideal world we'd have probably just 1 repo, but 3 target packages "aexpect", "aexpect-remote" and "aexpect-ops". Would this work for you?
And I am honestly sad about that. I have pinged people from avocado-vt to move up the priority of your PR to finally move avocado-vt to aexpect-remote.
I mentioned it earlier, basically size and security. Core aexpect is very stable, proven to work in many applications and it's API is clearly "dangerous". By adding upper layers people might get false impression of it to be higher-level safe tool, which it is not or it would take a long time to ensure and keep testing the security of it's layer. |
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.
Hi @pevogam, thanks for taking the time to compile and submit those utilities.
I won't try to get into each of the points discussed so far, but I'll try to optimize the discussion by talking about the most important ones IMO.
First, about whether this module fits well enough in the aexpect repo. My take is that it does extend aexpect in ways that are useful to some people and use cases. IMO, as long as the code matches the project's quality standards, including passing review on its technical merits, and does not add maintenance burden, it deserves to go in. A project's scope shouldn't be so set in stone, but should respond to what its users need from it.
Second, the organization of aexpect's first level "aexpect" directory never seemed like a "core" module to me. In fact, this is the location from where all API users actually import code from. I can't find a difference between from aexpect import remote
and from aexpect import ops
.
Finally, a new topic related to maintenance: it would be great if tests could be added. I understand these are simple wrappers, but as shown in the issue found during review, users and maintainers would benefit from having some coverage there.
OK, I understand the point that we already have another "uglier" modules in there. I hope I'll find some time to come-up with a simple to use way to separate them (ideally multiple pip packages generated out of a single source-tree) but until then let's get this in. I mean it is useful, it is way cleaner than remote and Plamen (and others) spent already way too much on updating it.
Yep, selftests are always welcome, although even the core aexpect contains only a bare minimum selftests. |
cd03ecb
to
723a176
Compare
Hi @clebergnu and @ldoktor, thank you both for spending some of your valuable time on this. I have updated the pull request with all of your comments. I realize and fully agree the code is not of the best quality and I apologize if I am wasting your precious brain cycles on this. My approach and proposal on how to proceed here is rather simple: we try to satisfy your requirements for some minimum quality in order for the code to become available for others and then we can have any or lots of further improvements to make it more proper and satisfactory depending on demand, i.e. we can always redirect devs that would otherwise reinvent the wheel to solve their own needs as contributors here. In this way it can also be of less effort for you and we can have the highest rates of availability and opportunity for further development with the minimum needed amount of effort. On my side I will make sure to add some follow up contributions regarding this module as potential subpackage that would address larger refactoring requests and am always available to help with maintenance if you so desire. |
723a176
to
7e8c316
Compare
A quick comment regarding the unit tests: I assume this would imply some mocking and basic command checks (even though I am not sure how much it makes sense since it is not as good as functional tests) but I can do so in the "larger refactoring" part mentioned above. |
As for me the selftests would be nice but not mandatory at this point. Mocking could consist of simply passing a mock object and checking the output values (ensuring quotation is enforced, arguments are transformed, expected calls are being performed and data are being processed correctly) |
7e8c316
to
0b0f8d1
Compare
This is what I would expect via mocking too but
|
ddb0300
to
42d7aaf
Compare
I tried pushing on most recent master branch to trigger the CI again (didn't trigger within 6 hour timeout upon previous push) but it seems it still won't start. I will however run our functional tests or a good portion of them with the current changes just in case. |
bd4ca18
to
68456c8
Compare
68456c8
to
dadf545
Compare
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.
Hi @pevogam, thank you so much for the library.
I read the discussion so far, and here are my 2 cents about your code:
-
I generally like the idea of having these shell functions (or operations) as a library, as they are widely used in a variety of situations. Having them neatly packaged is a good idea.
As @clebergnu mentioned, as long as we meet the necessary criteria for inclusion (as far as I can see the code generally is clean and documented), it makes for a good inclusion. -
Creating an extra separate library to interact with aexpect might be too much granularity, as this is fairly small and will be mostly concentrated in the client library. We could think of an
aexpect-extensions
library if we ever get too many extra functions, but that doesn't seem very likely at the moment. -
As far as code organization style goes, all these functions take session as the first parameter. Have you considered making the functions an object that inherits from
session
? That's something like:
from aexpect.remote.ops import ShellOpsSession
session = ShellOpsSession("sh")
session.stat(path="/tmp/a")
session.copy(src="/tmp/a", dst="/tmp/b")
That saves a bit of typing and it seems like a reasonable layering of functionality.
Of course if @clebergnu and @ldoktor disagree, please let me know if I'm off here.
Once again, thanks for your contribution!
It is added as a main module since the utilities folder is reserved only for utilities used by the core aexpect code or aexpect client. The only detected linter problem was in an import done solely to satisfy sphinx documentation links which can be reconsidered in the future. The session ops module is orgnized according to complexity and is initially meant to be a complete selection of standard utilities for file operations. However, there is lots of additional refactoring and standardization to be desired and all current functions are only contributed as-is based on the needs of their original authors. Signed-off-by: Plamen Dimitrov <[email protected]>
dadf545
to
69f90d6
Compare
Hi @lmr,
Thanks both for chiming in with views on this, I agree that the current functionality is quite skinny when it comes to wrapping logic around the shell command strings but it could easily grow into some extended and extra useful logic too.
Yes, I am all in for separating if this becomes big enough later on but just like you I think that at the moment creating separate project infrastructure is a bit of an overkill.
I can see three problems with this:
|
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 still not happy about this not being a separate module, but it looks good and others are fine having it in-tree, so I think it's ready for inclusion. Maybe one thing to consider is the strip
in the cat
method. I do understand why it's there, but maybe it'd be safer to leave it on the user. Anyway let's not block this anymore and include this first implementation, we can tweak it later, if necessary.
Well it re-runs with the same base commit, anyway passes local "make check" so let me merge this. |
Hi @ldoktor and thanks all for all the reviews here,
Hmm but as I wrote above the situation with the |
Add a small library of frequent operations performed in aexpect sessions.
v1: Initial pull request, later split into manageable parts.
v2: Main session ops module contribution and selection of reusable session functions, rebased on most recent aexpect tag.