Hi Ginnie,

I took a look at the ICT webrev, focusing on the non-test files.

In general, looking good, but I have some comments/suggestions for you
below...

General:

- Getting the BE

  I know I sent you this originally, but on further thought the searching for
  the BE in could probably be 'slightly' faster if we stop when we've found
  the first (and only occurrence) by adding the max_count parameter to
  get_descendants():

    self.boot_env = self.target.get_descendants(class_type=BE, max_count=1)[0]

  I'm also wondering if there would be some value to this part of the code
  being shared between all checkpoints, not just in your ICT code, although
  that's probably the main consumer of it...

- Use of subprocess.check_call()

  It probably makes sense for us to use the new solaris_install.Popen that
  Keith has provided rather than check_call() for a couple of reasons but the
  main one being how things are logged.

  Alternatively, maybe we also need a solaris_install.check_call()?

- Other shared code

  There is some shared code in the ICTs, especially in the __init__() and
  start of the execute() methods - the progress estimation code is also common
  at the moment - and in the case of short ICTs it might be shared too.

  As such it might be useful to have a shared common class for ICTs, that did
  the following:

  - Define an __init__ that set up the doc, target and BE references.

    BTW, you should be able to get a reference to the DOC in the __init__()
    since the engine creates it only once, well before this is called.

  - Define a parse_doc() method that gets the above information from the DOC
    and fills it in for you, and this would be called at the start of the
    execute() method.

    This would also help with the repeated code as mentioned above for
    fetching the BE.

apply_sysconfig.py:

- lines 96-99:

  96         os.environ[Common.SVCCFG_DTD] = os.path.join(self.target_dir,
  97                                         Common.SVC_BUNDLE)
  98         os.environ[Common.SVCCFG_REPOSITORY] = 
os.path.join(self.target_dir,
  99                                                        Common.SVC_REPO)

  I think that these lines should probably be done inside the dry-run since
  they are potentially changing the environment for subsequent checkpoints
  (although I do realise that it's unlikely they will use it, but you never
  know).

- lines 101-102:

 101         self.sc_profile_dst = os.path.join(self.target_dir,
 102                                            Common.PROFILE_DEST)

  I don't think that sc_profile_dst needs to be an instance attribute, so you
  could probably omit the 'self.' here.

boot_archive.py:

- lines 90-94:

  90         if not dry_run:
  91             # Run bootadm
  92             cmd = [Common.BOOTADM, 'update-archive', '-R ',
  93                    self.target_dir, '2>&1']
  94             subprocess.check_call(cmd)

  (I know we mentioned this before in separate emails, but just want to ensure
  it's recorded here too)

  The space after the '-R' is a bug, and will fail.

  I don't think we should use '2>&1' since it is useful to get the error
  messages logged, which would happen if solaris_install.Popen is used.

cleanup_live_cd.py:

- Several locations:

  Its a nit really but there is a space between the string and .join call,
  which I feel is misleading:

    " " .join(cmd)

  I think it would be clearer to have no space after the string.

- lines 155-157:

 155             cmd = '(Common.CD %s && find . -type f -print | \
 156                    Common.CPIO -pmu %s > /dev/null 2>& 1) && Common.RM -rf
%s' \
 157                    % (savedir, self.target_dir, savedir)

  I think that the command here is very broken, since the values Common.XX are
  not interpreted but remain as they are in the command, giving you something
  like:

     (Common.CD /a/save && find . -type f -print | \
      Common.CPIO -pmu /a > /dev/null 2>& 1) && Common.RM -rf /a

  as opposed to the expected

     (cd /a/save && find . -type f -print | \
      cpio -pmu /a > /dev/null 2>& 1) && rm -rf /a

  So it should probably read as:

     cmd = '(%s %s && find . -type f -print | \
            %s -pmu %s > /dev/null 2>& 1) && %s -rf %s' \
            % (Common.CD, savedir, Common.CPIO,
               self.target_dir, Common.RM, savedir)

- lines 191-197:

 191         # Restore the original IPS default and
 192         # set purging the IPS download cache to "False"
 193         cmd = [Common.PKG, '-R', self.target_dir, 'set-property',
 194                'flush-content-cache-on-success', 'False']
 195         self.logger.debug("executing: %s" % " " .join(cmd))
 196         if not dry_run:
 197             subprocess.check_call(cmd)

  As mentioned in a separate thread, this code should probably be moved to a
  separate checkpoint since it's also needed by AI, which doesn't use this
  CleanupLiveCD checkpoint.

common.py:

- line 58:

  I reckon the "RM" command should be "/usr/bin/rm" not "rm", to be more
  consistent with other commands also in here.

create_snapshot.py:

- No comments

device_config.py:

- line 97:

  97             cmd = [Common.DEVFSADM, '-R ', self.target_dir, ' 2>&1']

  The space after the -R should be removed, and the '2>&1' also if you change
  to using Popen.

generate_sc_profile.py:

- lines 185-192, and 201-206:

 185                 with open(self.sc_profile_src, "r+") as fh:
 186                     for line in fh:
 187                         if Common.KBD_DEFAULT in line and \
 188                            self.keyboard_layout != Common.KBD_DEFAULT:
 189                             line = line.replace(Common.KBD_DEFAULT,
 190                                                 self.keyboard_layout)
 191                         new_sc_profile.append(line)
 192                 fh.close()
 ...
 201         if self.keyboard_layout == '':
 202             self.logger.debug('Keyboard layout has not been identified')
 203             self.logger.debug('It will be configured to %s.'%
Common.KBD_DEFAULT)
 204         else:
 205             self.logger.debug('Detected [%s] keyboard layout'
 206                               % self.keyboard_layout)

  According to the debug statement at line 201, it would appear to be possible
  that the keyboard_layout could be blank '', and should default to
  KBD_DEFAULT if it is.

  But, the above code doesn't take this into account and will replace the
  default in the profile with ''...

  I think the lines 201-206 should be before the looping code or even in the
  end of the _get_keyboard_layout() method, and if it sees the keyboard_layout
  as being '', then set it to Common.KBD_DEFAULT.

- lines 184-199:

  If self.keyboard_layout != Common.KBD_DEFAULT in the code, then this whole
  try/except is essentially the equivalent of a:

     shutil.copy2(self.sc_profile_src, self.sc_profile_dst)

  as such, I wonder if we could have the if statement check this condition
  first, if so, then call shutil.copy2(), otherwise process it in more detail
  as in the try/catch.

initialize_smf.py:

- lines 104-115:

 104         self.sys_profile_dict = {Common.GEN_LTD_NET_XML:
 105                                   os.path.join(self.target_dir,
 106                                   Common.GENERIC_XML),
 107                                   Common.NS_DNS_XML:
 108                                   os.path.join(self.target_dir,
 109                                   Common.NAME_SVC_XML),
 110                                   Common.INETD_XML:
 111                                   os.path.join(self.target_dir,
 112                                   Common.INETD_SVCS_XML),
 113                                   os.path.basename(Common.SC_PROFILE):
 114                                   os.path.join(self.target_dir,
 115                                   Common.PROFILE_SITE)}

  It's a nit really, but I wonder could this be better formatted to make it
  more readable? e.g.:

      self.sys_profile_dict = {
        Common.GEN_LTD_NET_XML:
                os.path.join(self.target_dir, Common.GENERIC_XML),
        Common.NS_DNS_XML:
                os.path.join(self.target_dir, Common.NAME_SVC_XML),
        Common.INETD_XML:
                os.path.join(self.target_dir, Common.INETD_SVCS_XML),
        os.path.basename(Common.SC_PROFILE):
                os.path.join(self.target_dir, Common.PROFILE_SITE)}

- line 127:

 127                 os.unlink(value)

  Again, we've said this in another thread, but just to bring together, we
  should be checking whether the file exists first before we try unlink it,
  otherwise it could fail when it doesn't need to.

Thanks,

Darren.


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

Reply via email to