[zones-discuss] Zone boot/reboot hooks

2008-06-15 Thread Tim Spriggs
Hi,

I want to file an RFE but I thought I should discuss a little before 
I do: I would like a way to run a script in the global zone when a 
non-global zone boots. My use case is:

I'm a developer for NexentaCP and I would like to make an autobuilder 
using zones. In particular I want to have a zone that will always come 
back in the same state on reboot so that I have minimal packages 
installed and everything gets pulled as defined by source package 
dependencies. The process might look like:

(global zone)
zone_hook(pre-boot, ...)
   - a script/action occurs for the zone
zone_boot(...)

(non-global zone)
init  (the autobuilder will have a svc that builds packages and reports 
status to a server)
reboot  (perhaps with specific args that the hook script can grab)

(global zone)
zone_halt(...)
zone_hook(post-halt, ...)


I think it would make sense to configure the hooks via a zonecfg section:
---
add hook
set type=[pre-boot | post-boot | pre-halt | post-halt]
set action=script
set path=/path/to/zone_hook.sh
end
---

In my particular use-case I would have a pre-boot hook that rolled the 
zone filesystem to a particular snapshot. This way the zone would always 
come back in the same state:
---
add hook
set type=pre-boot
set action=script
set path=/path/to/zone_scripts/pre-boot.sh
end
---

For a decent interface we would need to pass information to the scripts 
about the zone name, boot args, previous state, ... which might be done 
through the environment? An example script might hackishly look like:
---
#!/bin/sh

# Check for fs reset condition
echo $ZONE_BOOT_ARGS | grep -w 'reset_zone_fs=yes'  /dev/null
if [ $? != 0 ]; then
  exit 0
fi

# get fs to reset
path=`zonecfg -z $ZONE_NAME info zonepath | cut -d: -f2`
zfs_dataset=`zfs list -H -t filesystem -o mountpoint,name | grep 
^$path | awk '{print $2}'`

# If no fs then exit with an error status
if [ X$zfs_dataset = X ]; then
  echo Danger Will Robinson... Danger:
  exit -1
fi

# make sure the snapshot exists and rollback
zfs list -H -o name -t snapshot -r $zfs_dataset | grep @snapshot_name$  
/dev/null
if [ $? != 0 ]; then
  echo Error: required snapshot does not exist
  exit -1
fi
zfs rollback [EMAIL PROTECTED]

exit 0
---


Comments/criticisms/flying chunkules appreciated.

-Tim
___
zones-discuss mailing list
zones-discuss@opensolaris.org


Re: [zones-discuss] Making zoneadm more like the other adms...

2008-06-15 Thread Tony Ambrozie
Your code changes for both zoneadm and zonecfg would preserve the current
zonexxx -z zonename for backwards compatibility purposes, is that correct?

Thank you,


On Mon, Jun 9, 2008 at 11:51 AM, Darren Reed [EMAIL PROTECTED] wrote:

 Someone mentioned zonecfg was the cause of some similar awkwardness...

 So here's a patch attached for that.

 Darren



 --- usr/src/cmd/zonecfg/zonecfg.c ---

 Index: usr/src/cmd/zonecfg/zonecfg.c
 *** /biscuit/onnv/usr/src/cmd/zonecfg/zonecfg.c Mon Mar 24 17:30:38 2008
 --- /biscuit/onnv_20080608/usr/src/cmd/zonecfg/zonecfg.cMon Jun  9
 11:47:41 2008
 ***
 *** 1071,1076 
 --- 1071,1077 
execname, cmd_to_str(CMD_HELP));
(void) fprintf(fp, \t%s -z zone\t\t\t(%s)\n,
execname, gettext(interactive));
 +   (void) fprintf(fp, \t%s command zone\n, execname);
(void) fprintf(fp, \t%s -z zone command\n, execname);
(void) fprintf(fp, \t%s -z zone -f command-file\n,
execname);
 ***
 *** 6653,6689 
return (execbasename);
  }

 ! int
 ! main(int argc, char *argv[])
  {
 !   int err, arg;
 !   struct stat st;
 !
 !   /* This must be before anything goes to stdout. */
 !   setbuf(stdout, NULL);
 !
 !   saw_error = B_FALSE;
 !   cmd_file_mode = B_FALSE;
 !   execname = get_execbasename(argv[0]);
 !
 !   (void) setlocale(LC_ALL, );
 !   (void) textdomain(TEXT_DOMAIN);
 !
 !   if (getzoneid() != GLOBAL_ZONEID) {
 !   zerr(gettext(%s can only be run from the global zone.),
 !   execname);
 !   exit(Z_ERR);
 !   }
 !
 !   if (argc  2) {
 !   usage(B_FALSE, HELP_USAGE | HELP_SUBCMDS);
exit(Z_USAGE);
}
 !   if (strcmp(argv[1], cmd_to_str(CMD_HELP)) == 0) {
 !   (void) one_command_at_a_time(argc - 1, (argv[1]));
 !   exit(Z_OK);
 !   }

while ((arg = getopt(argc, argv, ?f:R:z:)) != EOF) {
switch (arg) {
case '?':
 --- 6654,6679 
return (execbasename);
  }

 ! static void
 ! set_zonename(char *zonename)
  {
 !   if (strcmp(zonename, GLOBAL_ZONENAME) == 0) {
 !   global_zone = B_TRUE;
 !   } else if (zonecfg_validate_zonename(zonename) != Z_OK) {
 !   zone_perror(zonename, Z_BOGUS_ZONE_NAME, B_TRUE);
 !   usage(B_FALSE, HELP_SYNTAX);
exit(Z_USAGE);
}
 !   (void) strlcpy(zone, zonename, sizeof (zone));
 !   (void) strlcpy(revert_zone, zonename, sizeof (zone));
 ! }

 + static void
 + get_clioptions(int argc, char *argv[])
 + {
 +   struct stat st;
 +   int arg;
 +
while ((arg = getopt(argc, argv, ?f:R:z:)) != EOF) {
switch (arg) {
case '?':
 ***
 *** 6712,6726 
zonecfg_set_root(optarg);
break;
case 'z':
 !   if (strcmp(optarg, GLOBAL_ZONENAME) == 0) {
 !   global_zone = B_TRUE;
 !   } else if (zonecfg_validate_zonename(optarg) !=
 Z_OK) {
 !   zone_perror(optarg, Z_BOGUS_ZONE_NAME,
 B_TRUE);
 !   usage(B_FALSE, HELP_SYNTAX);
 !   exit(Z_USAGE);
 !   }
 !   (void) strlcpy(zone, optarg, sizeof (zone));
 !   (void) strlcpy(revert_zone, optarg, sizeof (zone));
break;
default:
usage(B_FALSE, HELP_USAGE);
 --- 6702,6708 
zonecfg_set_root(optarg);
break;
case 'z':
 !   set_zonename(optarg);
break;
default:
usage(B_FALSE, HELP_USAGE);
 ***
 *** 6727,6733 
 --- 6709,6761 
exit(Z_USAGE);
}
}
 + }

 + int
 + main(int argc, char *argv[])
 + {
 +   int err;
 +
 +   /* This must be before anything goes to stdout. */
 +   setbuf(stdout, NULL);
 +
 +   saw_error = B_FALSE;
 +   cmd_file_mode = B_FALSE;
 +   execname = get_execbasename(argv[0]);
 +
 +   (void) setlocale(LC_ALL, );
 +   (void) textdomain(TEXT_DOMAIN);
 +
 +   if (getzoneid() != GLOBAL_ZONEID) {
 +   zerr(gettext(%s can only be run from the global zone.),
 +   execname);
 +   exit(Z_ERR);
 +   }
 +
 +   if (argc  2) {
 +   usage(B_FALSE, HELP_USAGE | HELP_SUBCMDS);
 +   exit(Z_USAGE);
 +   }
 +   if (strcmp(argv[1], cmd_to_str(CMD_HELP)) == 0) {
 +   (void) one_command_at_a_time(argc - 1, (argv[1]));
 +   exit(Z_OK);
 +   }
 +
 +   if 

Re: [zones-discuss] Making zoneadm more like the other adms...

2008-06-15 Thread Darren Reed
Tony Ambrozie wrote:

 Your code changes for both zoneadm and zonecfg would preserve the 
 current zonexxx -z zonename for backwards compatibility purposes, is 
 that correct?


Correct.  There are some command line options that the changes I've
made don't support, such as using -R.  That's quite deliberate.

The aim of the changes was to address the common use cases of the
commands and make their use more intuitive when viewed with the
other commands in OpenSolaris.

Darren


 Thank you,


 On Mon, Jun 9, 2008 at 11:51 AM, Darren Reed [EMAIL PROTECTED] 
 mailto:[EMAIL PROTECTED] wrote:

 Someone mentioned zonecfg was the cause of some similar awkwardness...

 So here's a patch attached for that.

 Darren



 --- usr/src/cmd/zonecfg/zonecfg.c ---

 Index: usr/src/cmd/zonecfg/zonecfg.c
 *** /biscuit/onnv/usr/src/cmd/zonecfg/zonecfg.c Mon Mar 24
 17:30:38 2008
 --- /biscuit/onnv_20080608/usr/src/cmd/zonecfg/zonecfg.c  
  Mon Jun  9 11:47:41 2008
 ***
 *** 1071,1076 
 --- 1071,1077 
execname, cmd_to_str(CMD_HELP));
(void) fprintf(fp, \t%s -z zone\t\t\t(%s)\n,
execname, gettext(interactive));
 +   (void) fprintf(fp, \t%s command zone\n,
 execname);
(void) fprintf(fp, \t%s -z zone command\n,
 execname);
(void) fprintf(fp, \t%s -z zone -f
 command-file\n,
execname);
 ***
 *** 6653,6689 
return (execbasename);
  }

 ! int
 ! main(int argc, char *argv[])
  {
 !   int err, arg;
 !   struct stat st;
 !
 !   /* This must be before anything goes to stdout. */
 !   setbuf(stdout, NULL);
 !
 !   saw_error = B_FALSE;
 !   cmd_file_mode = B_FALSE;
 !   execname = get_execbasename(argv[0]);
 !
 !   (void) setlocale(LC_ALL, );
 !   (void) textdomain(TEXT_DOMAIN);
 !
 !   if (getzoneid() != GLOBAL_ZONEID) {
 !   zerr(gettext(%s can only be run from the global
 zone.),
 !   execname);
 !   exit(Z_ERR);
 !   }
 !
 !   if (argc  2) {
 !   usage(B_FALSE, HELP_USAGE | HELP_SUBCMDS);
exit(Z_USAGE);
}
 !   if (strcmp(argv[1], cmd_to_str(CMD_HELP)) == 0) {
 !   (void) one_command_at_a_time(argc - 1, (argv[1]));
 !   exit(Z_OK);
 !   }

while ((arg = getopt(argc, argv, ?f:R:z:)) != EOF) {
switch (arg) {
case '?':
 --- 6654,6679 
return (execbasename);
  }

 ! static void
 ! set_zonename(char *zonename)
  {
 !   if (strcmp(zonename, GLOBAL_ZONENAME) == 0) {
 !   global_zone = B_TRUE;
 !   } else if (zonecfg_validate_zonename(zonename) != Z_OK) {
 !   zone_perror(zonename, Z_BOGUS_ZONE_NAME, B_TRUE);
 !   usage(B_FALSE, HELP_SYNTAX);
exit(Z_USAGE);
}
 !   (void) strlcpy(zone, zonename, sizeof (zone));
 !   (void) strlcpy(revert_zone, zonename, sizeof (zone));
 ! }

 + static void
 + get_clioptions(int argc, char *argv[])
 + {
 +   struct stat st;
 +   int arg;
 +
while ((arg = getopt(argc, argv, ?f:R:z:)) != EOF) {
switch (arg) {
case '?':
 ***
 *** 6712,6726 
zonecfg_set_root(optarg);
break;
case 'z':
 !   if (strcmp(optarg, GLOBAL_ZONENAME) == 0) {
 !   global_zone = B_TRUE;
 !   } else if
 (zonecfg_validate_zonename(optarg) != Z_OK) {
 !   zone_perror(optarg,
 Z_BOGUS_ZONE_NAME, B_TRUE);
 !   usage(B_FALSE, HELP_SYNTAX);
 !   exit(Z_USAGE);
 !   }
 !   (void) strlcpy(zone, optarg, sizeof (zone));
 !   (void) strlcpy(revert_zone, optarg, sizeof
 (zone));
break;
default:
usage(B_FALSE, HELP_USAGE);
 --- 6702,6708 
zonecfg_set_root(optarg);
break;
case 'z':
 !   set_zonename(optarg);
break;
default:
usage(B_FALSE, HELP_USAGE);
 ***
 *** 6727,6733 
 --- 6709,6761 
exit(Z_USAGE);
}
}
 + }

 + int