Hi all,
I believe the final webrev is now available. I'm running the final
regression tests (so please excuse the two non-collapsed in deltas in the
webrev) however, they are available at (diff and full):
http://cr.opensolaris.org/~clayb/delete_service/webrev3.diff
http://cr.opensolaris.org/~clayb/delete_service/webrev3
Please let me know if I failed to address anything.
Thank you,
Clay
On Mon, 28 Sep 2009, Ethan Quach wrote:
>
>
> Clay Baenziger wrote:
>> Hi Ethan,
>> Comments in-line. New differential webrev at
>> http://cr.opensolaris.org/~clayb/delete_service/webrev3.ethan/
>>
>> Thank you,
>> Clay
>>
>> On Fri, 25 Sep 2009, Ethan Quach wrote:
>>
>>> Clay,
>>>
>>>
>>> I have some additional comments on the updated webrev ...
>>>
>>>
>>> usr/src/cmd/installadm/installadm.c
>>> -----------------------------------
>>> 946 - Don't we need to check to see if we just deleted the
>>> last service somewhere around here, and if so, disable our
>>> smf service? Or is this logic somewhere else that I'm missing?
>>
>> No, apparently sending a SIGTERM to Apache was causing the service to
>> restart and then stay in maintenance. I now, instead check if we're the
>> last service and set the service to maintenance and no-longer kill the
>> apache process (as the SMF stop method does that).
>
> okay.
>
>>
>>> usr/src/cmd/installadm/installadm_common.py
>>> -------------------------------------------
>>> 36 - What's the significance of using the name "Unix" here?
>>
>> None much. It was suggested in the code walk through by someone. However,
>> it has no meaning and perhaps should just be File_ as it just trivially
>> extends the file class.
>
> Okay, can you please go ahead and make this change then. My
> concern was that if our goal for this code is for it to approach
> something portable, then naming something that wasn't necessarily
> Unix specific with that name could cause confusion down the line.
>
>>> 65 - In this method, if newlines = False, and blanklines = True,
>>> what will get returned at 107 when processing a blankline in
>>> from a file? An empty string '' ??
>>
>> An empty string would be returned but from line 104 not 107. Why, are you
>> thinking a particular use should be warned against in the docstring?
>
> Sorry, that's what I meant to ask about, the earlier return at 105ish.
>
> Let me restate the comment then...
>
> At 107, it returns the empty string to denote to the caller that we're
> out of lines, but if we're returning the empty string at 105 for the
> case above, then won't the caller get confused?
>
> i.e. if we're processing a file with an empty line in the middle of
> the file somewhere, and its being processed with newlines = False and
> blanklines = True, won't this wad of code (readlines() + readline() )
> stop processing in the middle of the file?
>
>>>
>>> usr/src/cmd/installadm/delete-service.py
>>> ----------------------------------------
>>> 413 - I dislike how you have to visit an additional time just
>>> to check existence. I thought there existed some NO_IDX
>>> exception when searching a list. If so, you can then just
>>> wrap 415 in a try
>>
>> Hi Ethan, there is a ValueError thrown. I think we're getting into pretty
>> micro-style/optimization here. However, I can change the code from:
>>
>> To find out this is a value error, try:
>>>>> a=[1,2]
>>>>> a[3]
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in ?
>> IndexError: list index out of range
>>
>> (This is what vfstabObj.fields.MOUNT_POINT[idx] could in all fairness
>> raise)
>>
>>>>> a.index(3)
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in ?
>> ValueError: list.index(x): x not in list
>>
>> (This is what vfstabObj.fields.MOUNT_POINT.index(boot_archive) would raise)
>>
>> Thus the code now reads:
>>
>> # look for filesystem in /etc/vfstab
>> try:
>> # calculate index for mount point
>> idx = vfstabObj.fields.MOUNT_POINT.index(boot_archive)
>> try:
>> # remove line containing micro root
>> del(vfstabObj.fields.MOUNT_POINT[idx])
>> except IOError, e:
>> sys.stderr.write(str(e) + "\n")
>> # microroot was not found in /etc/vfstab
>> except (ValueError, IndexError):
>> sys.stderr.write (_("Microroot for service %s " +
>> "not in vfstab.\n") % service.serviceName)
>> return
>>
>>> try:
>>> idx = vfstabObj.fields.MOUNT_POINT.index(boot_archive)
>>>
>>> try:
>>> # remove line containing micro root
>>> del(vfstabObj.fields.MOUNT_POINT[idx])
>>> except IOError, e:
>>> sys.stderr.write(str(e) + "\n")
>>>
>>> except NO_INDEX_OR_WHATEVER_THE_EX_IS, e:
>>> sys.stderr.write (_("Microroot for service %s " +
>>> "not in vfstab.\n") % service.serviceName)
>>>
>>>
>>> (Ideally, I would have like to have seen the caller not
>>> need to handle the idx at all, but I won't push for that
>>> at this point.)
>>
>> Dude, I can't make it magically delete things, one has to tell it what you
>> want to delete. How else would one specify what to delete? This is a list
>> after all, not an associative array (aka dictionary) as otherwise the
>> DBFile would have to have knowledge of what columns contain unique data and
>> which can have repeated data.
>>
>
> That's part of the point. Why should the caller need to know if the
> vfstabObj is a list or an array? Secondly, your current implementation
> has the caller extracting something from the object, just to pass it
> back into the object. That something is the idx in this case, and
> there doesn't seem to be any value or meaning for the caller to
> ever have to handle that. So my hinted suggestion was to build a
> member function for the object to hide that detail. For example,
> the caller code could end up looking like this:
>
> try:
> vfstabObj.delentry_by_mntpnt(boot_archive)
>
> # or if we want to parameterize the field out ...
> # (this is probably not correct python syntax, but I know
> # its possible somehow.)
> # vfstabObj.delentry(com.VFSTAB.fields.MOUNT_POINT, boot_archive)
>
> except (ValueError, IndexError):
>
> except IOError, e:
>
> except Whatever Else:
>
>
> Is this over java-fying the code?
>
> Lastly, as I noted in the original comment, this is not something
> I am not pushing for this in this putback, but since you're asking
> I'm just clarifying what my comment was.
>
> Based on Jan's comment and your filing of 11537, the vfstab
> looks like it may be handled differently altogether in our AI
> server tools, correct?
>
>
>>
>>> 453 - This doesn't look correct. The manpage for in.tftpd
>>> does not say that 'homedir' is the argument to the -s
>>> option. In fact, based on the synopsis, it looks like
>>> 'homedir' can float.
>>>
>>> SYNOPSIS
>>> in.tftpd [-d] [-T rexmtval] [-s] [homedir]
>>>
>>>
>>> So it seems you have to parse fields.SERVER_ARGUMENTS,
>>> looking for the argument that's not an option, and not
>>> an option argument.
>>
>> Thank you for catching this! I've fixed it to take the last argument --
>> much easier to parse out too.
>
> Did you check whether or not the [homedir] argument can float?
> Based on the synopsis, [homedir] looks like it can be put anywhere
> in the command line, not necessarily always at the end. Can you
> verify whether or not this is the case?
>
>>
>>> 474-478 - I really think we should leave it up to the caller
>>> to check this, so that the interface of findTFTProot()
>>> is defined as always to return something, with the default
>>> being /tftpboot
>>>
>>> (Looking ahead at your code, the callers already do this
>>> checking)
>>
>> Actually this is broken both ways. The callers try to build a path off an
>> unset baseDir variable. I added a meaningful error for the user that we
>> can't do much deleting without a TFTProot (this egregious enough I'm
>> tempted to do a SystemExit, but right now I've added the following checks
>> after line 501:
>> else:
>> sys.stderr.write (_("Unable to remove the grub executable, boot "+
>> "archive, or menu.lst file\nwithout a valid "+
>> "tftp root directory.\n"))
>
>
> Okay, that's fine.
>
> Comment on new delete_service.py file:
> 471-473 - Can you update this error message to be more clear?
> I couldn't tell from the message that something doesn't exist.
> Here's a suggested rewrite of the comment
>
> "The tftp root directory (%s) found from the configuration
> file (%s) does not exist. Using default: %s\n"
>
>
> 482-483 - Same comment.
>
> "The tftp root directory (%s) does not exist.\n"
>
>>
>>
>>> 500-501, 688-689 - Umm, can you please make findTFTProot()
>>> cache its answer then. The chances of someone changing
>>> /etc/inetd.conf in between time is negligible afaic.
>>>
>>> And actually, if you do my previously suggested comment,
>>> you can remove the if()'s at 500 and 688.
>>
>> As the inetd class will be caching the data this is trivial in code
>> runtime. And not easily coded (as findTFTProot is a function not a class)
>> further 500-501, 688-689 are in different scopes (well one's a nested
>> function of the other but that would be very ugly to understand where those
>> vars are coming from to get it to persist). If you think this will save
>> more than 500ms off the runtime of this program I'll profile it to see but
>> this is trivial and very over-optimizing to concern ourselves with.
>
> Since you're not taking my original comment for 474-478 above,
> nevermind this comment.
>
>>
>>>
>>> usr/src/cmd/installadm/delete_client.py
>>> ---------------------------------------
>>> 41 - this comment isn't needed anymore.
>>
>> I've changed from:
>> "Parse and validate options when called as delete-client"
>> to:
>> "Parse and validate options"
>>
>> and for further concern I've changed from parse_client_options to
>> parse_options.
>
> Okay thanks.
>
>>
>> Please I'd like to stop working on nits and ensure the program works this
>> has been out for code review for greater than nearly a month.
>
> You've got a large amount of delta here for the differential though.
> You can't expect to make this much change again and not get an
> initial-like review for the parts that are freshly written.
>
>>
>>> 43 - is this comment still accurate?
>>
>> It is, but perhaps changing service to client would cause less confusion as
>> it returns a client_Data class
>
> That would be a good start.
>
>
> thanks,
> -ethan
>
>
>>
>>> usr/src/pkgdefs/SUNWinstalladm-tools/prototype_com
>>> --------------------------------------------------
>>> 45-48 - Is there a benefit for doing this symlinking? Why don't
>>> we just deliver two binaries, delete-service and
>>> delete-client?
>>
>> The symlinks are just to conform to how the other binaries appear in
>> /usr/lib/installadm. For python to be able to import it needs module names
>> to conform to [a-zA-Z0-9_]*.py and thus we need to at least deliver
>> delete_service.py for delete client to import. It seemed prudent to start
>> moving things that way thus the reason for doing delete_client.py.
>>
>>> thanks,
>>> -ethan
>>>
>>>
>>> Clay Baenziger wrote:
>>>> Hi again all,
>>>> I got a way to get webrev to work for me to do a differential
>>>> including delete_service.py (still known as delete-service.py in the
>>>> differentail webrev). See:
>>>> http://cr.opensolaris.org/~clayb/delete_service/webrev2.diff2/
>>>>
>>>> Thank you,
>>>> Clay
>>>>
>>>> On Wed, 23 Sep 2009, Clay Baenziger wrote:
>>>>
>>>>> Hi again all,
>>>>> Well the addition of a thousand lines of code and 50+ pages of
>>>>> comments I think I've got this re-spun for everyone's enjoyment, please
>>>>> see:
>>>>>
>>>>> http://cr.opensolaris.org/~clayb/delete_service/webrev2.diff/
>>>>> (Unfortunately I can't get webrev to track that delete-service.py became
>>>>> delete_service.py (so that it can be imported by delete_client))
>>>>>
>>>>> Or full webrev:
>>>>> http://cr.opensolaris.org/~clayb/delete_service/webrev2/
>>>>>
>>>>> The bug list has grown to include:
>>>>> 4526 delete-service is not deleting service as described in section
>>>>> 4.3.2
>>>>> ai_design_doc
>>>>> 6587 delete-service shouldn't remove the source image if there's
>>>>> other
>>>>> services actives 'linked' to the same source image
>>>>> 8666 create-service: prints out SMF messages no matter what's going
>>>>> on
>>>>> 8773 create-service followed quickly by delete-service hangs
>>>>> 10740 Need way to interact with SMF from Python for installadm
>>>>> components
>>>>> in Python
>>>>> 11292 delete-client: should remove SPARC clients too
>>>>> 11486 delete-service/delete-client: should check inetd.conf for tftp
>>>>> root
>>>>>
>>>>>
>>>>> To Drew:
>>>>> --------
>>>>> To address the ps(1) pain, I consolidated the function down and filed
>>>>> 11524 - Should look to using PSI (Python System
>>>>> Information) for Python process management
>>>>>
>>>>> I looked into Bill's bootadm work but I don't fit an "alternate root"
>>>>> environment and I'd still need to provide a lot of parsing anyways.
>>>>>
>>>>> To Sundar:
>>>>> ----------
>>>>> I think our phone call Thursday cleared up your questions?
>>>>>
>>>>> For those in the code walk-through:
>>>>> -----------------------------------
>>>>> I chose to append our findings of being able to have both a SPARC and
>>>>> X86 client to a bug on create-client rather than address finding all
>>>>> possible nooks for a client and spewing lots of not found messages to a
>>>>> user (or having to catch the messages in funky ways).
>>>>>
>>>>> Jack:
>>>>> -----
>>>>> Per the agreement between Drew's coding style suggestions, those of
>>>>> PEP8's hanging indents and Google's Python style guide I've followed
>>>>> PEP8/Google's Style guide, however, I hope next Tuesday we'll have time
>>>>> to come to a consensus on Python style there as this should expand past
>>>>> this one push, of course. Thank you for getting me to think about this
>>>>> so much!
>>>>>
>>>>> Thank you,
>>>>> Clay
>>>>>
>>>
>>>
>>>
>
>
On Mon, 28 Sep 2009, Jack Schwartz wrote:
> Hi Clay.
>
> I can commit to re-reviewing the parts which I commented on earlier and maybe
> a little more. This is almost like a whole new review and my time is limited.
> I spent a few hours today, and will spend a few more probably tomorrow.
>
> Is anyone reviewing the new installadm_common.py? I thought I saw that Drew
> can't do it. If you want me to, please explain the syntax for 74 - 93 of
> installadm_common.py.
>
> Thanks,
> Jack
>
> On 09/28/09 09:41, Clay Baenziger wrote:
>> Hi Jack,
>> I was wondering if you had an ETA when you'd be able to get me your
>> delete-service code review comments back. Ethan and I would really like to
>> get this pushed as things just keep backing up behind this.
>> Thank you,
>> Clay
>
>
On Mon, 28 Sep 2009, Evan Layton wrote:
> Hi Clay,
>
> Just a few more comments on the "C" code only...
>
> installadm.c
>
> line 899 - This needs to be changed as we discussed earlier today so
> that we give a bit more description about what this function does. Also we
> need to add a bit more description on what type of thing
> SERVICE_DELETE_SCRIPT does. for example maybe saying something like "the
> remaining clean-up is done by SERVICE_DELETE_SCRIPT" ( if that's at all
> accurate... ;-) ) would help.
>
> line 1168 The comment here is a bit misleading. What this really does here is
> if there are no service instances with a state set to "on" the we put the smf
> service into maintenance mode. We should state that this is what is happening
> instead of saying it disables something.
>
> Also this points out the fact that the state can either be on or off but
> there can be a third state where we've temporarily disabled a service
> instance but still want it to start up the next time the SMF service is
> started. This transient state is not dealt with in here but is definitely
> outside the scope of this fix and I believe this is now covered in bug 11604
> that you filed earlier.
>
> ai_utils.c
> line 166 - It might be helpful to state here why no data out of the handle is
> needed here instead of just stating that we don't need anything out of the
> handle here. Maybe something along the lines of saying that the handle is not
> needed for this call since we not destroying the property stored in the
> handle.
>
>
> libaiscf_backend.c
> line 82 - This isn't really "bound" to our handle but is stored in the
> handle. It may make more sense to say "Allocate and initialize a property
> group and store it in the handle".
>
> line 87 - Same thing but with the instance.
>
> line 90 - maybe "Make sure we have what's needed to run SMF" ?
>
> libaiscf_instance.c
> line 264, 316 - Closure should be closure so that it matches the actual
> parameter.
>
> libaiscf_service.c
> line 259 - should be "static PyObject *AIservice_print(PyObject *self) {"
> Also this doesn't actually print anything out does it? Seems
> like a confusing name for this function. Not a big deal I
> guess but it could cause confusion. (sorry I didn't notice
> this before...)
>
>
> -evan
>
> Clay Baenziger wrote:
>> Hi again all,
>> I got a way to get webrev to work for me to do a differential including
>> delete_service.py (still known as delete-service.py in the differentail
>> webrev). See:
>> http://cr.opensolaris.org/~clayb/delete_service/webrev2.diff2/
>>
>> Thank you,
>> Clay
>>
>> On Wed, 23 Sep 2009, Clay Baenziger wrote:
>>
>>> Hi again all,
>>> Well the addition of a thousand lines of code and 50+ pages of
>>> comments I think I've got this re-spun for everyone's enjoyment, please
>>> see:
>>>
>>> http://cr.opensolaris.org/~clayb/delete_service/webrev2.diff/
>>> (Unfortunately I can't get webrev to track that delete-service.py became
>>> delete_service.py (so that it can be imported by delete_client))
>>>
>>> Or full webrev:
>>> http://cr.opensolaris.org/~clayb/delete_service/webrev2/
>>>
>>> The bug list has grown to include:
>>> 4526 delete-service is not deleting service as described in section
>>> 4.3.2
>>> ai_design_doc
>>> 6587 delete-service shouldn't remove the source image if there's other
>>> services actives 'linked' to the same source image
>>> 8666 create-service: prints out SMF messages no matter what's going on
>>> 8773 create-service followed quickly by delete-service hangs
>>> 10740 Need way to interact with SMF from Python for installadm
>>> components
>>> in Python
>>> 11292 delete-client: should remove SPARC clients too
>>> 11486 delete-service/delete-client: should check inetd.conf for tftp
>>> root
>>>
>>>
>>> To Drew:
>>> --------
>>> To address the ps(1) pain, I consolidated the function down and filed
>>> 11524 - Should look to using PSI (Python System
>>> Information) for Python process management
>>>
>>> I looked into Bill's bootadm work but I don't fit an "alternate root"
>>> environment and I'd still need to provide a lot of parsing anyways.
>>>
>>> To Sundar:
>>> ----------
>>> I think our phone call Thursday cleared up your questions?
>>>
>>> For those in the code walk-through:
>>> -----------------------------------
>>> I chose to append our findings of being able to have both a SPARC and X86
>>> client to a bug on create-client rather than address finding all possible
>>> nooks for a client and spewing lots of not found messages to a user (or
>>> having to catch the messages in funky ways).
>>>
>>> Jack:
>>> -----
>>> Per the agreement between Drew's coding style suggestions, those of PEP8's
>>> hanging indents and Google's Python style guide I've followed
>>> PEP8/Google's Style guide, however, I hope next Tuesday we'll have time to
>>> come to a consensus on Python style there as this should expand past this
>>> one push, of course. Thank you for getting me to think about this so much!
>>>
>>> Thank you,
>>> Clay
>>>
>
>
On Mon, 28 Sep 2009, Sundar Yamunachari wrote:
> Clay Baenziger wrote:
>> Hi again all,
>> Well the addition of a thousand lines of code and 50+ pages of comments I
>> think I've got this re-spun for everyone's enjoyment, please see:
>>
>> http://cr.opensolaris.org/~clayb/delete_service/webrev2.diff/
>> (Unfortunately I can't get webrev to track that delete-service.py became
>> delete_service.py (so that it can be imported by delete_client))
>>
>> Or full webrev:
>> http://cr.opensolaris.org/~clayb/delete_service/webrev2/
>>
>> The bug list has grown to include:
>> 4526 delete-service is not deleting service as described in section 4.3.2
>> ai_design_doc
>> 6587 delete-service shouldn't remove the source image if there's other
>> services actives 'linked' to the same source image
>> 8666 create-service: prints out SMF messages no matter what's going on
>> 8773 create-service followed quickly by delete-service hangs
>> 10740 Need way to interact with SMF from Python for installadm components
>> in Python
>> 11292 delete-client: should remove SPARC clients too
>> 11486 delete-service/delete-client: should check inetd.conf for tftp root
>>
>>
>> To Drew:
>> --------
>> To address the ps(1) pain, I consolidated the function down and filed 11524
>> - Should look to using PSI (Python System
>> Information) for Python process management
>>
>> I looked into Bill's bootadm work but I don't fit an "alternate root"
>> environment and I'd still need to provide a lot of parsing anyways.
>>
>> To Sundar:
>> ----------
>> I think our phone call Thursday cleared up your questions?
>>
>> For those in the code walk-through:
>> -----------------------------------
>> I chose to append our findings of being able to have both a SPARC and X86
>> client to a bug on create-client rather than address finding all possible
>> nooks for a client and spewing lots of not found messages to a user (or
>> having to catch the messages in funky ways).
>>
>> Jack:
>> -----
>> Per the agreement between Drew's coding style suggestions, those of PEP8's
>> hanging indents and Google's Python style guide I've followed PEP8/Google's
>> Style guide, however, I hope next Tuesday we'll have time to come to a
>> consensus on Python style there as this should expand past this one push,
>> of course. Thank you for getting me to think about this so much!
>>
>> Thank you,
>> Clay
>> _______________________________________________
>> caiman-discuss mailing list
>> caiman-discuss at opensolaris.org
>> http://mail.opensolaris.org/mailman/listinfo/caiman-discuss
> Clay,
>
> *delete_service.py:*
> 542, 544: microroot --> boot archive
> 749: Why we need the python2.4 here? I don't like the hard-coded value here.
>
> *installadm_common.py:*
> 53, 65, 109: Suggestion: change the name of the booleans to make it clearer.
> comments ->skipComments, newlines->removeNewlines and
> blanklines->skipBlanklines
> 288, 302: What is the difference between __getitem__() and gte()?
> 641: enpty --> empty
> 740-791: function clients(net)
> The output of pntadm -P <net> may have some entries missing some values. For
> example these four entries are from ins3525-svr. Check whether your code
> handles all the four entries.
>
> # pntadm -p 10.6.35.0
>
> Client ID Flags Client IP Server IP Lease Expiration Macro Comment
>
> 010003BA866375 03 10.6.35.180 10.6.35.8 Forever 010003BA866375 line2-280r
>
> 0100144F0057A8 03 10.6.35.103 10.6.35.8 Forever 0100144F0057A8 --> No
> comment field
>
> 00 05 10.6.35.247 10.6.35.8 Zero line2-x4100-sp --> No macro assigned
>
> 010007E923F7A6 05 10.6.35.179 10.6.35.8 06/28/2004 --> No macro or
> comment
>
>
> *SUNWinstalladm-tools/prototype_com:*
> 46, 47: Why we need these definitions?
>
> Thanks,
> Sundar
>
>
On Wed, 30 Sep 2009, jeanm wrote:
> Clay Baenziger wrote:
>> Hi Jean,
>> Thank you for the review! My comments are in-line.
>> Thank you,
>> Clay
>>
>> On Mon, 28 Sep 2009, jeanm wrote:
>>
>>>
>>> I found time to do this when I thought I wouldn't. Using the following
>>> webrev:
>>> http://cr.opensolaris.org/~clayb/delete_service/webrev2. I haven't checked
>>> to see
>>> if others have commented on these items. Pardon me if they have.
>>>
>>> Also, if you just want to discuss this in the office instead of an email
>>> thread I'm fine with that.
>>> Sometimes it's easier.
>>>
>>> Jean
>>>
>>>
>>> usr/src/cmd/installadm/delete_client.py.html
>>>
>>> General:
>>> This is the delete-client file but there are references to delete-service
>>> throughout. That causes me to be confused
>>> since I know they are different and have different functionality. Is this
>>> a cut and paste issue? Or similar functionality
>>> between the two?
>>
>> I only see delete_service mentioned when the delete_service module is
>> called for various functions. This is a shared code approach as
>> delete_client is a subset of the functionality exported by delete_service.
> And line 26 which is a general overview of the file. The comment you just
> made might be nice somewhere since it does explain why
> delete-service is in the delete-client code.
>
>>
>>> line 78-81: Since you're hardcoding the first %s to installadm why bother
>>> with the %s in the first place? I actually
>>> don't think you even need the 2nd %s. This is run in delete-client. If
>>> prog is something other than that, this message
>>> would be extremely confusing.
>>
>> This is just to make it more modular as these commands will hopefully all
>> collapse down to installadm as soon as create-service becomes Python. Until
>> then this just prevents hard coding bits. Yes, prog should be delete-client
>> actually to mimick how delete-client reports errors today.
> This makes sense then. If eventually it will be just one function call with
> parameters then I'm fine with leaving it in for now.
>>
>> This is achieved using the /usr/lib/installadm/delete-client symlink which
>> points to /usr/lib/installadm/delete_client.py. The reason for printing the
>> program name is just since it has these two execution possibilities. The
>> reason for having the delete_client is so that the module is importable by
>> Python (modules needing to be [a-zA-Z0-9_].py.
>>
>>> line 43: Wouldn't it be more helpful to say a tuple representing....
>>
>> You want me to be helpful now, that's just too much! Thanks for the catch,
>> I've changed it to:
>>
>> Returns: A tuple of a class object representing client to delete
>> and an options object
> Thanks.
>>
>>> line 62: Why did you hang this off of options?
>>
>> This is an option the functions expect to be set. This comes from
>> delete_service being able to delete an image, so as the comment says:
>> "we do not deleteImage for a delete-client so set it False"
> So you're saying that the delete-service functionality might need this,
> correct? In which case I'm fine with it.
>>
>> Further, looking at line 89 (the only place options is really used) we see
>> that indeed deleteImage is used there, and we can correlate from line 60
>> (the comment) image deletion is hard coded off.
> But if this was really the only reason we would just return a boolean. If
> however as stated above, delete-service would use it then you have it right.
>>
>> Note: I swapped line 60 (the comment for line 62) and line 61. I
>> accidentally got them out of order.
>>
>>> usr/src/cmd/installadm/delete_service.py.html
>>>
>>> lines 837-840 : same comment as lines 78-81 in delete-client.py
>>
>> Same reasons as with delete_client
>>
>>> line 64: this really returns a tuple. Same comment as line 62 of
>>> delete_client.py
>>
>> Same fix as delete_client
>>
>>> General comment: I find that putting comments into the middle of a group
>>> of
>>> code that is line continued makes the code difficult to read.
>>> Ex.
>>>
>>> 377 files = [image_path,
>>> 378 # must strip the leading path separator from
>>> image_path as
>>> 379 # os.join won't concatenate two absolute paths
>>> 380 os.path.join('/var/ai/image-server/images/',
>>> 381 image_path.lstrip(os.sep))]
>>
>> Hrm, I know we talked about this. I find this breaks up the logic so I can
>> see the intention behind it. I see the list files consists of only two
>> elements:
>> image_path
>> os.path.join('var/ai/image-server/images/',image_path.strip(os.sep))
>>
>> Further, following better formatting allowed by PEP8 I think this should be
>> formatted as follows which more clearly shows that it's two separate
>> elements in the list:
>> files = [image_path,
>> # must strip the leading path separator from image_path as
>> # os.join won't concatenate two absolute paths
>> os.path.join('/var/ai/image-server/images/',
>> image_path.lstrip(os.sep))]
>>
>> Also, do you use an editor or viewer which does syntax highlighting? I just
>> realized since my vi is configured for syntax highlighting, comments are
>> lighter than code, so I don't even visually notice them -- unless I
>> question what the code's doing and this lessens the distraction immensely.
> No and the code review utility didn't either. In this particular case I'm
> fine with leaving this. Other cases it becomes much more distracting. Usually
> where you have multi line list comprehensions.
>>
>>> Another general comment. There are lots of hard coded paths. This makes
>>> changes
>>> to these paths in the future very difficult to maintain in the code.
>>
>> Yes, I'm not fond of them. This is tracked in 4402 (Pull fixed strings in
>> A/I server python code out to a separate module) which is a holder for
>> finding an elegant way to pull out these various paths. It seems we should
>> have a module we import for various install components and their paths but
>> perhaps there's better or different -- it's too big to design that here
>> though.
> Great. Thanks.
>>
>>> line 196:
>>> It would be cleaner to just do
>>> if not return_val
>>> return 1
>>> return return_val
>>>
>>> But you should be sure that return_val is None at the top. Certainly is
>>> easier to read and cleaner.
>>
>> This was accidentally left in from some tinkering I could've sworn I'd
>> gotten them.
>>
>> This is further incredibly inexcusable, as I'm returning -1, 0, 1 which is
>> asinine in the days of Python. It should have been something transparently
>> obvious to a developer and user (e.g. "failure", "okay", "human assistance
>> needed"). I've now ensured these returns are stripped from stop_service()
>> and remove_DHCP_macro().
> Thanks.
>>
>>> line 403-425: Seems like there should be a lot simpler way of just
>>> removing a line from vfstab.
>>> Is there?
>>
>> Um, this seems pretty short?
>>
>> We've gotta open the file and handle the file not existing, opening, etc.
>> (first except on IOError).
>>
>> Next, we've gotta look for the entry (which will throw a
>> ValueError/IndexError depending on where we fail - if we fail).
>>
>> Lastly, we need to remove the line and need to check that the write took
>> (second IOError exception).
>>
>> Am I missing how this could be streamlined though?
> Well this went with the comment much further down about parsing the files in
> general. The idea is that if you got rid of all of the code it would be
> simpler. However from your response below it appears that having this is good
> so I'll shut up. ;-)
>
>>
>>> line 455-456: Boy that looks unmaintainable. If there is a more
>>> maintainable way to do this I
>>> would suggest it. If not, you need a big old comment there.
>>
>> Thanks to Ethan's code review comments this was changed. Please see 457-458
>> from
>> http://cr.opensolaris.org/~clayb/delete_service/webrev3.ethan/usr/src/cmd/installadm/delete_service.py.html
>>
>>
>> However, this was just a simple regex looking for:
>> "<anything>-s <anything up to a space, stored as path><anything to EOL>"
>> and replaced that whole string with what was found and stored as path.
> The point was that a lot of people aren't that familiar with reg ex's. Very
> prone to maintenance mistakes so explaining what it's doing
> and maybe even how would be nice.
>>
>>> lines 556-559: Seems a little long for list comprehension. I believe we
>>> had discussed anything past about
>>> 2 lines should be considered for breaking up. Could this be done? It would
>>> make the code easier to read
>>> and probably easier to maintain.
>>
>> Sure, this was two lines but I was asked to expand fn to filename by
>> another reviewer. How does it work if just pulled out of the for loop. It
>> is three lines still but we get a much cleaner presentation (as it's only
>> three statements in three lines):
>>
>> # build a list of grub menus from baseDir
>> menus = [filename for filename in os.listdir(baseDir) if
>> # only select files which start with grub menu prefix
>> filename.startswith(grub_menu_prefix) and
>> # do not select the menu file the service uses
>> filename != os.path.basename(menuLst.file_name)]
> OK.
>>
>>> line 584: Realistically, could this be in any other field than mountpoint?
>>> If not, could this code be simplified?
>>
>> I'm not sure what code there is to simplify. Line 584 is a comment and the
>> next line of code seems trivial to the extreme (just seeing if a string is
>> in a list):
>>
>> (line 587)
>> if boot_archive in com.MNTTab().fields.MOUNT_POINT:
> Same response as above wrt to mountpoint in /etc/vfstab
>>
>>> line 612: why? It's not already able to be executed? Are we fixing
>>> something here that should be fixed elsewhere?
>>
>> That's the problem is that it's not executable, we're setting it so that we
>> can run it. To set the <tftpdir>/rm.<service name> script so we can run it,
>> we have to chmod it.
> OK. Seems like something would be wrong it it wasn't executable but it's nice
> you're fixing the situation since you can. Why abort if you can fix as you're
> doing.
>>
>> Yes, create-service should get rid of the rm.<service name> scripts. See
>> bug: 10853 (create-service:Should consider removing
>> /tftpboot/rm.<service|client> scripts). Until then it's an interface were
>> someone might stash something so let's honor it until we get rid of them.
>>
>> As an aside, in the meantime - partially thanks to the 30 create-service
>> bugs, the majority of this file is to give us a working foothold from which
>> to clean things up. See Drew's comments about how bizarre it is to have a
>> script which reverse engineers the entirety of an AI service.
>>
>>> lines 625-634: Since the point of this function is to remove the tftpboot
>>> files, why don't you just remove these files
>>> if the rmCmd hasn't? It certainly would be more efficient that appending
>>> them to files now and removing them later.
>>> And clearer as to the state of the system after this function is called.
>>> Plus, the header comments say the function removes them.
>>
>> Ah thanks I've fixed the comment. The intention is to not remove anything
>> except in the main function body, as this aids in debugging since it
>> provides a central list and order, as well as allowing breadcrumbs until
>> we've gathered all we can since we're piecing together what's left of a
>> service.
> I'd have to disagree. I'd love to see things removed in the appropriate
> functions. So then you would know if you return from function
> removeTFTPBootFiles that all the tftpboot files are gone. I'd be confused it
> they weren't.
>>
>> The comment now reads:
>> Handle file removal in /tftpboot by building a list of files to remove:
>> First, adds pxegrub.<directory pointed to by /tftpboot/<service
>> name> i.e. pxegrub.I86PC.OpenSolaris-1
>> Unmounts directory which is boot archive (will be something like
>> I86PC.OpenSolaris-4) and removes /etc/vfstab entry for mount point
>>
>> Calls /tftpboot/rm.<service name> which should remove:
>> /tftpboot/<service name>
>> /tftpboot/menu.lst.<service name>
>> (if the above aren't removed by the rm.<service name> script they
>> are added to the remove list)
>> Adds /tftpboot/rm.<service name>
>>
>> Returns: If unable to find tftp root - None
>> Success - A list of file paths to remove
>>
>>> Why not have check_wanboot_conf also make sure everything is cleaned up.
>>> Then you don't need the code at 696 ad 699 to
>>> add onto the fileToRemove list. Could we also then get rid of 714+? I
>>> think all that would be left is then explicit files which
>>> could then just be rm'd. In general this seems more complicated than it
>>> needs to be.
>>
>> We need to remove the files provided by the list filesToRemove which has
>> the paths returned by:
>> find_service_directory
>> find_image_path
> Can they be removed in the functions?
>>
>> As well as (for services):
>> check_wanboot_conf (for SPARC)
>> - or -
>> removeTFTPBootFiles (X86)
>>
> But if these actually removed the files then you wouldn't need them to be
> gone here.
>> So 714+ gets rid of these collections, not just check_wanboot_conf or
>> removeTFTPBootFiles. Further, 696 and 699 are not the same; one is for
>> SPARC and thus check_wanboot_conf, while the other is for X86 and thus
>> removeTFTPBootFiles.
>>
>> I'm perhaps missing something in your suggestion here?
> I think so. Right now you're checking to see if you need to remove a file and
> placing it in a list. The list is later parsed and the file removed. That's
> extra computation and complexity. Why not check to see if you need to remove
> the file and remove it? Unless the file is needed later it's much simpler.
>>
>>> usr/src/cmd/installadm/installadm_common.py
>>>
>>> I lied. I say Ethan's comment about Unix. I agree.
>>
>> I've changed UnixFile() to File_()
>>
>>> lines 393-494: do we really need to do this in this manner? For example
>>> VFSTab creates a database of the vfstab file. So far I've seen the
>>> mountpoint field looked at for the boot_archive. Seems like overkill for
>>> that. If we foresee needed more detailed parsability in the future I'm
>>> fine with it. Otherwise I wonder....
>>
>> Yup, we only use a few fields from each file but this is pretty simple now.
>> Many people felt this functionality would be good to have available for
>> general extensibility (and as the inetd.conf was a nit request which took
>> ten minutes to add (the time for me to man -s 4 inetd.conf and type) it
>> seems pretty trivial now (one just needs to give field names and a file
>> name).
>>
>> I'm not sure what you're asking here, other than is this easy? Yes
> The greater extensibility answer was appropriate for my question. Guess I
> wasn't clear. Sorry. It was a long code review.
>
> Jean
>
>>
>>> Jean
>>>
>>>
>>>
>>>
>>>
>
>