Hi Ethan,
        Thank you for your comments. My responses in-line.
                                                        Thank you,
                                                        Clay

On Mon, 28 Sep 2009, Ethan Quach wrote:

>>> 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.

This has been changed. The class is now known as File_()

>>> 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?

Yes, this is a very good realization. Thank you! I've modified readlines 
to perform the newline removal for now so that this problem is not hit.

> 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?

Yes, I think this is why Python is different than Java :)

I think this why Python implements the type() function. This is how the 
class is implemented modeling a list.

Certainly, we could at the cost of losing a lot of generalization and 
adding more code implement something which is very vfstab specific.

But, that's how I see it...

> 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.

Cool, thank you for clarifying. I was very confused how, in Python, we 
could implement something cleaner. I think as you well put it, the answer 
isn't a very Pythonic approach likely -- or at least not very general.

Perhaps a vfstab_obj.del.<field>("key to delete") would be a possible 
approach which would be extensible?

> 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?

I did and I can't do, for example, '/usr/sbin/in.tftpd /tftpboot -d'. 
Further, I check that what I get is an absolute path (not to be confused 
with rexmtval (which is a numeric value).

>> 
>>> 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"

Done

> 482-483 - Same comment.
>
> "The tftp root directory (%s) does not exist.\n"

Done

>> 
>> 
>>> 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.

That is true, just want to be done; we're getting close!

>> 
>>> 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.

Done

> thanks,
> -ethan

Reply via email to