Hi John.

I really appreciate your review...


On 03/22/11 03:00 PM, John Fischer wrote:
Jack,

You've done a whole lot of great work here. Thanks for cleaning up the XML verification parameters
and doing the pylint stuff.

Comments are below.

Sorry for the delay,

John



================================================================================
usr/src/cmd/ai-webserver/AI_database.py
================================================================================
Looks fine.
================================================================================
usr/src/cmd/ai-webserver/cgi_get_manifest.py
================================================================================
1. Should the following be changed?

194 servs_port = serv[PROP_TXT_RECORD].partition(':')[-1]

   To be like lines at:

    186                     if PROP_TXT_RECORD in serv.keys():
187 port = serv[PROP_TXT_RECORD].partition(':')[-1]

Or should the check be removed from line 186? If it should be removed then
   things need to change at line 213 and 214 of the new code.
I'll leave the check in at 186 and add it at 194, for two reasons:
1) The check was there in 186 before; all I did was change 'txt_record' to PROP_TXT_RECORD as it is elsewhere. 2) if for some reason the PROP_TXT_RECORD key is missing in serv at 194, the check at 202
    ( if not path...)
will catch the error as it already does for 186.
2. I would change line 224 from:

    224     if not servicename:

   To:

     if found_servicename:
Yup.  That's better...  Fixed.

3. I think you should probably add found_servicename to the exception output at
   lines 249-259.
OK.  I changed the end of the output from this:

    print 'criteria    =', criteria, '</ol>'
to
    print 'criteria    =', criteria
    print 'servicename found by port =', str(found_servicename), '</ol>'


================================================================================
usr/src/cmd/ai-webserver/delete_manifest.py
================================================================================
1. You might consider putting the "%s" in parentheses:

117 raise SystemExit(_("Error:\tCannot delete default manifest %s.") %
    118                          man_name)

Otherwise we might end up with a default manifest default.xml as the output
   which to me looks a little odd.

2. Also the webrev complains that the file is executable. That should probably
   be changed.

    executable file: mode 755
Changed to 0644 like the rest.

================================================================================
usr/src/cmd/ai-webserver/publish_manifest.py
================================================================================
1. Please put the imports in alphabetic order:

     30 import gettext
     31 import logging
     32 import lxml.etree
     33 import os.path
     34 import StringIO
     35 import errno
     36 import sys
     37 import pwd
     38 from stat import S_IRUSR, S_IWUSR
     39 from optparse import OptionParser
     40
     41 import osol_install.auto_install.AI_database as AIdb
     42 import osol_install.auto_install.verifyXML as verifyXML
     43 import osol_install.libaiscf as smf
44 from osol_install.auto_install.installadm_common import validate_service_name 45 from osol_install.auto_install.properties import set_default, get_service_dir 46 from solaris_install import Popen, CalledProcessError, _, AI_DATA, \
     47     KSH93_SHEBANG, PYTHON_SHEBANG

   According to former members of the team this is a pep8 requirement.
Done.

2. Parentheses are unnecessary:

    151     if (do_add):
() removed.

3. Should there be an PROP_IMAGE_PATH defined in installadm_common.py like
   there is for PROP_TXT_RECORD?  This would then be used from lines like:

    181         image_path = svc['image_path']
I now import PROP_IMAGE_PATH from ai_smf_service and use it instead.

4. Since criteria_file and set_as_default are not changing you should really just use the thing passed into the application so that it is easier to tell
   that these were passed in rather then generated within the code:

196 files = DataFiles(service_dir=service_dir, image_path=image_path, 197 database_path=os.path.join(service_dir, "AI.db"),
    198                       manifest_file=options.manifest_path,
    199                       manifest_name=options.manifest_name,
    200                       criteria_dict=criteria_dict,
    201                       criteria_file=criteria_file,
    202                       service_name=options.service_name,
    203                       set_as_default=set_as_default)
Done!
5. Please use shutil.copyfile() instead of the Popen method you are using within the _copy_file() function (shutil.copyfile('/tmp/original', '/tmp/copy')).
Great idea. Done!

6. This:

    646     if root is not None:

   can be changed to simply:

       if root:
Yup.  Changed.

7. Also the _copy_file() is not needed if you use shutil.copyfile() as the
only other thing within _copy_file() is the chown/chmod which could be done
   for all cases after the script copy else case around line 667 or 668.
I'd like to leave _copy_file() in place, as shutil.copyfile still needs to be enveloped in a try/except, and the chmod and chown together with the copy are a significant group of statements.

8. This:

    717     if errors is not None:

   Can be changed to simply:

       if errors:
Yup, changed.

9. The same for line 788. These are then consistent with lines 1393 and 1404.
Changed.

10. The same for line 1461.
Changed.
================================================================================
usr/src/cmd/ai-webserver/set_criteria.py
================================================================================
Looks good.
================================================================================
usr/src/cmd/ai-webserver/verifyXML.py
================================================================================
Looks good.
================================================================================
usr/src/cmd/installadm/Makefile
================================================================================
Looks good.
================================================================================
usr/src/cmd/installadm/delete_service.py
================================================================================
1. line 640 you disable pylint message W0612 for the unused files variable but
   never re-enable the warning.  This will cause pylint to ignore unused
   variables the rest of the file.  So add:

       # pylint: enable-msg=W0612

   after the for loop.
No need: "pylint disable" honors the scope/nesting-level it is in, so it will affect only the remainder of the "else" clause it is in (which is the loop itself).
================================================================================
usr/src/cmd/installadm/installadm.py
================================================================================
1. Seems kind of arbitrary at this point to have multiple from/import
statements from the same file and then have a single from/import for other
   things:

     35 from osol_install.auto_install import create_client
     36 from osol_install.auto_install import create_service
     37 from osol_install.auto_install import delete_client
     38 from osol_install.auto_install import delete_manifest
     39 from osol_install.auto_install import delete_service
     40 from osol_install.auto_install import list as ai_list
     41 from osol_install.auto_install import publish_manifest
     42 from osol_install.auto_install import set_criteria
     43 from osol_install.auto_install import set_service

   Verses:

     44 from osol_install.auto_install.ai_smf_service import \
     45     PROP_STATUS, STATUS_OFF, InstalladmAISmfServicesError, \
     46     check_for_enabled_services, enable_install_service, \
     47     get_pg_props, is_pg, set_pg_props
     48 from osol_install.auto_install.installadm_common import \
     49     CHECK_SETUP_SCRIPT, SERVICE_DISABLE, SETUP_SERVICE_SCRIPT, \
     50     validate_service_name

   I know you're just following what's already there.
I believe you are the second person to comment on this... It doesn't look consistent, but what is really happening is that the single line "from xxx import yyy" statements import files, whereas the "from xxx import aaa,bbb,ccc" statements import defs from a particular file. In order to make the difference of importing files and defs within a file more pronounced, I will change the
    from xxx import yyy
to
    import xxx.yyy as yyy

example:
    from osol_install.auto_install import create_client
becomes
    import osol_install.auto_install.create_client as create_client

2. why use Pipe(/usr/bin/cat manifest) instead of:

       with open(manifest) as man_fp:
       manifest_data = man_fp.read()
    print manifest_data
Actually, I heeded your note further below, to use shutil.copyfile instead....

On a somewhat related note, the CAT definition in installadm.py is leftover cruft from before I put export in its own file, so I will remove that definition.

3. Could use the not version for:

    269     if (options.service_name is None):

   Becomes:

       if not options.service_name:

   In either case loose the parentheses.

4. Similar comment for:

    274     if ((options.mname is None) and (options.pname is None)):

   becomes:

       if not options.mname and not options.pname:

5. Similar comment for:

    279     elif (options.mname is not None):

   becomes:

       elif options.mname:
Changed all of these in the whole file!

6. Also loose the parentheses around:

    286         if (options.mname == "default"):
Changed.

7. Could just check for value for:

    295         if options.output_name is not None:

   becomes

       if options.output_name:

8. Why not simply use shutil.copyfile() instead of Popen(/usr/bin/cat manifest)
   at lines 295-312?
Thanks for the suggestion. This makes for (IMHO) a *really* elegant solution, which, except for the try/except, reduces to three lines... Get a load of this:
def do_export(cmd_options=None):
    ''' XXX Will merge with William's do_export.'''

    options = parse_options(cmd_options)
    if not options.output_name:
        options.output_name = "/dev/tty"

    # Find the file in the directory and cat it out.
    try:
        shutil.copyfile(options.mname,options.output_name)
    except IOError as err:
        print >> sys.stderr,
            "Error exporting manifest: %s: %s" % (
            err.strerror, err.filename)
        sys.exit(err.errno)

Isn't it beautiful?
================================================================================
usr/src/cmd/installadm/list.py
================================================================================
1. Change to a simple check:

    965                         if criteria is not None:

   becomes:

       if criteria:
Fixed.

2. You can loose the parentheses:

   1031         if (cwidth > 0):
Yup.  Changed.
3. Change to  a simple check:

   1050     if default_mfest is not None:

   becomes:

       if default_mfest:
Done.
================================================================================
usr/src/cmd/installadm/properties.py
================================================================================
1. I think we go back and forth in how we build paths within our group.
Sometimes we use os.path.join and other times we do what you are doing below:

86 manifest_path = service_dir + "/" + AI_DATA + "/" + manifest_name

You should probably change it as you use os.path.abspath() at lines 52 and
   73.
The application is slightly different so abspath isn't really correct. However, os.path.join is used elsewhere and makes for code more elegant than the original. Changed to:

manifest_path = os.path.join(service_dir, AI_DATA, manifest_name)
2. You should probably use the DEFAULT_MANIFEST_PROP for the following raise:

    108         raise KeyError(_("default-manifest property is missing "
    109                          "from service %s" % service_name))
Changed to:
raise KeyError(_("\"%(prop)s\" property is missing "
     "from service %(serv)s") %
     {"prop": DEFAULT_MANIFEST_PROP,
       "serv": service_name})
================================================================================
usr/src/cmd/installadm/set_service.py
================================================================================
1. You should import DEFAULT_MANIFEST_PROP from properties then use it in the
   list assignment at line 37:

     37 SERVICE_PROPS = ["default-manifest"]
Changed to
    SERVICE_PROPS = [DEFAULT_MANIFEST_PROP]

2. Please change:

     79     if options.propval is None:

   to:

       if not options.propval:
Done.

3. The parsing of the propval option does not seem consistent with the
   usage statement:

     44         'set-service\t-o|--option <prop>=<value> ... <svcname>\n'
     45         '\t\tprop=value can be:\n'
     46         '\t\t\tglobal-menu=true|false\n'
     47         '\t\t\tname=<new_svcname>\n'
     48         '\t\t\talias=<alias_name>\n'
     49         '\t\t\tdefault-manifest=<manifest/script>'

   The usage statement seems to indicate that the --option can be multiple
   options (i.e., -o global-menu=true -o alias=somethingelse).
This is true, but the other items are on the way.

For now, I'll leave the other option statements but just comment them out.

4. Also I am not quite following the logic here.  When and/or how does
   SERVICE_PROPS get updated?
SERVICE_PROPS is a list of valid properties that can be passed to set-service. As handling for new properties get added, this list gets updated (by the programmer).
================================================================================
usr/src/cmd/installadm/setup-service.sh
================================================================================
Looks good.
================================================================================
usr/src/lib/install_common/__init__.py
================================================================================
1. Please turn pylint message W0212 back on after line 302.

    299             # pylint: disable-msg=W0212
300 popen.stdout, popen.stderr = popen._log(logger, log_bufsize, 301 stdout_loglevel, 302 stderr_loglevel)
pylint disable statements honor their scope so re-enabling is not necessary here. (See previous comments.)
================================================================================
usr/src/pkg/manifests/install-installadm.mf ================================================================================ 1. Not real keen on the name space management within /usr/sbin for AI stuff:

112 link path=/usr/sbin/publish_manifest target=/usr/lib/python2.6/vendor-packages/osol_install/auto_install/publish_manifest.py

   perhaps something like ai_publish_manifest.  publish_manifest seems too
   generic and that it should work for other manifest containing stuff.
OK. Changed here to ai_publish_manifest, and in setup-service.sh which references it.

    Thanks,
    Jack

On 03/17/11 04:52 PM, Jack Schwartz wrote:
Hi everyone.

Here is the AI server part of the Derived Manifests project.

http://cr.opensolaris.org/~schwartz/110317.1/webrev/

Please review by Weds 3/23 COB, and please let me know you plan on reviewing.

John F., I would like you in particular to review this stuff as the changes of default manifest management are right up your alley.

If anyone wants a 1-1 to go over this stuff please let me know.

There will be one more small code review forthcoming regarding unit tests for this stuff, but I didn't want to hold this up for it. That said, I have good results having tested by running many installadm commands manually.

Read on if you're curious about what this wad brings to our product:

1) Gets rid of a hard-wired default file called default.xml. It now allows any manifest in a service's manifest pool to be designated as the default. Any criteria belonging to a manifest designated as a default are ignored. Any manifest not containing criteria and not designated the default is noted as inactive.

2) There is a new installadm export command

3) There is a new installadm update-manifest command

4) Refactored duplicate code which got the correct service directory, into a single routine.

5) Removed cruft from publish_manifest

6) All files I touched are mostly if not completely pep8 compliant. (There are some temporary XXX which mark placeholders.)

    Thanks for your time.
    Jack


_______________________________________________
caiman-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/caiman-discuss


_______________________________________________
caiman-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/caiman-discuss

Reply via email to