user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH 09/26] lei: support `daemon-env' for modifying long-lived env
  2020-12-18 12:09  7% [PATCH 00/26] lei: basic UI + IPC work Eric Wong
@ 2020-12-18 12:09  6% ` Eric Wong
  0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2020-12-18 12:09 UTC (permalink / raw)
  To: meta

While lei(1) socket connections can set environment variables
for its running context, it may not completely remove some of
them.  The background daemon just inherits whatever env the
client spawning it had.  This command ensures the persistent env
can be modified as needed.

Similar to env(1), this supports "-u", "-" (--clear), and
"-0"/"-z" switches.  It may be useful to unset or change
or even completely clear the environment independently
of what a socket client feeds us.

"-i" is omitted since "--ignore-environment" seems like a bad
name for a persistent daemon as opposed to a one-shot command.
"-" and --clear (like clearenv(3)) will completely clobber
the environment.

"Lonesome dash" support is added to our option/help parsing
for the "-" shortcut to "--clear".
Getopt::Long doesn't seem to support specs like "clear|" or
"stdin|", but only "", so we do a little pre/post-processing
to merge the cases.
---
 lib/PublicInbox/LeiDaemon.pm | 55 ++++++++++++++++++++++++++++++++----
 t/lei.t                      | 31 ++++++++++++++++++++
 2 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/lib/PublicInbox/LeiDaemon.pm b/lib/PublicInbox/LeiDaemon.pm
index 1f170f1d..56f4aa7d 100644
--- a/lib/PublicInbox/LeiDaemon.pm
+++ b/lib/PublicInbox/LeiDaemon.pm
@@ -60,7 +60,7 @@ our %CMD = ( # sorted in order of importance/use:
 
 'plonk' => [ '--thread|--from=IDENT',
 	'exclude mail matching From: or thread from non-Message-ID searches',
-	qw(thread|t stdin| from|f=s mid=s oid=s) ],
+	qw(stdin| thread|t from|f=s mid=s oid=s) ],
 'mark' => [ 'MESSAGE_FLAGS...',
 	'set/unset flags on message(s) from stdin',
 	qw(stdin| oid=s exact by-mid|mid:s) ],
@@ -103,6 +103,8 @@ our %CMD = ( # sorted in order of importance/use:
 	qw(quiet|q) ],
 'daemon-stop' => [ '', 'stop the lei-daemon' ],
 'daemon-pid' => [ '', 'show the PID of the lei-daemon' ],
+'daemon-env' => [ '[NAME=VALUE...]', 'set, unset, or show daemon environment',
+	qw(clear| unset|u=s@ z|0) ],
 'help' => [ '[SUBCOMMAND]', 'show help' ],
 
 # XXX do we need this?
@@ -175,6 +177,16 @@ my %OPTDESC = (
 
 'by-mid|mid:s' => [ 'MID', 'match only by Message-ID, ignoring contents' ],
 'jobs:i' => 'set parallelism level',
+
+# xargs, env, use "-0", git(1) uses "-z".  Should we support z|0 everywhere?
+'z' => 'use NUL \\0 instead of newline (CR) to delimit lines',
+'z|0' => 'use NUL \\0 instead of newline (CR) to delimit lines',
+
+# note: no "--ignore-environment" / "-i" support like env(1) since that
+# is one-shot and this is for a persistent daemon:
+'clear|' => 'clear the daemon environment',
+'unset|u=s@' => ['NAME',
+	'unset matching NAME, may be specified multiple times'],
 ); # %OPTDESC
 
 sub x_it ($$) { # pronounced "exit"
@@ -257,7 +269,11 @@ sub _help ($;$) {
 				join(', ', @allow) . " or $last";
 		}
 		my $lhs = join(', ', @s, @l) . join('', @vals);
-		$lhs =~ s/\A--/    --/; # pad if no short options
+		if ($x =~ /\|\z/) { # "stdin|" or "clear|"
+			$lhs =~ s/\A--/- , --/;
+		} else {
+			$lhs =~ s/\A--/    --/; # pad if no short options
+		}
 		$lpad = length($lhs) if length($lhs) > $lpad;
 		push @opt_desc, $lhs, $desc;
 	}
@@ -289,9 +305,20 @@ sub optparse ($$$) {
 	my $opt = $client->{opt} = {};
 	my $info = $CMD{$cmd} // [ '[...]', '(undocumented command)' ];
 	my ($proto, $desc, @spec) = @$info;
-	$glp->getoptionsfromarray($argv, $opt, @spec, qw(help|h)) or
+	push @spec, qw(help|h);
+	my $lone_dash;
+	if ($spec[0] =~ s/\|\z//s) { # "stdin|" or "clear|" allows "-" alias
+		$lone_dash = $spec[0];
+		$opt->{$spec[0]} = \(my $var);
+		push @spec, '' => \$var;
+	}
+	$glp->getoptionsfromarray($argv, $opt, @spec) or
 		return _help($client, "bad arguments or options for $cmd");
 	return _help($client) if $opt->{help};
+
+	# "-" aliases "stdin" or "clear"
+	$opt->{$lone_dash} = ${$opt->{$lone_dash}} if defined $lone_dash;
+
 	my $i = 0;
 	my $POS_ARG = '[A-Z][A-Z0-9_]+';
 	my ($err, $inf);
@@ -461,12 +488,28 @@ E: leistore.dir=$cur already initialized and it is not $dir
 	return qerr($client, $exists);
 }
 
-sub lei_daemon_pid {
-	emit($_[0], 1, "$$\n");
-}
+sub lei_daemon_pid { emit($_[0], 1, "$$\n") }
 
 sub lei_daemon_stop { $quit->(0) }
 
+sub lei_daemon_env {
+	my ($client, @argv) = @_;
+	my $opt = $client->{opt};
+	if (defined $opt->{clear}) {
+		%ENV = ();
+	} elsif (my $u = $opt->{unset}) {
+		delete @ENV{@$u};
+	}
+	if (@argv) {
+		%ENV = (%ENV, map { split(/=/, $_, 2) } @argv);
+	} elsif (!defined($opt->{clear}) && !$opt->{unset}) {
+		my $eor = $opt->{z} ? "\0" : "\n";
+		my $buf = '';
+		while (my ($k, $v) = each %ENV) { $buf .= "$k=$v$eor" }
+		emit($client, 1, $buf)
+	}
+}
+
 sub lei_help { _help($_[0]) }
 
 sub reap_exec { # dwaitpid callback
diff --git a/t/lei.t b/t/lei.t
index 507c7164..53268908 100644
--- a/t/lei.t
+++ b/t/lei.t
@@ -20,6 +20,7 @@ delete local $ENV{XDG_DATA_HOME};
 delete local $ENV{XDG_CONFIG_HOME};
 local $ENV{XDG_RUNTIME_DIR} = "$home/xdg_run";
 local $ENV{HOME} = $home;
+local $ENV{FOO} = 'BAR';
 mkdir "$home/xdg_run", 0700 or BAIL_OUT "mkdir: $!";
 
 my $test_lei_common = sub {
@@ -104,6 +105,36 @@ SKIP: {
 	chomp(my $pid_again = $out);
 	is($pid, $pid_again, 'daemon-pid idempotent');
 
+	$out = '';
+	ok(run_script([qw(lei daemon-env -0)], undef, $opt), 'show env');
+	is($err, '', 'no errors in env dump');
+	my @env = split(/\0/, $out);
+	is(scalar grep(/\AHOME=\Q$home\E\z/, @env), 1, 'env has HOME');
+	is(scalar grep(/\AFOO=BAR\z/, @env), 1, 'env has FOO=BAR');
+	is(scalar grep(/\AXDG_RUNTIME_DIR=/, @env), 1, 'has XDG_RUNTIME_DIR');
+
+	$out = '';
+	ok(run_script([qw(lei daemon-env -u FOO)], undef, $opt), 'unset');
+	is($out.$err, '', 'no output for unset');
+	ok(run_script([qw(lei daemon-env -0)], undef, $opt), 'show again');
+	is($err, '', 'no errors in env dump');
+	@env = split(/\0/, $out);
+	is(scalar grep(/\AFOO=BAR\z/, @env), 0, 'env unset FOO');
+
+	$out = '';
+	ok(run_script([qw(lei daemon-env -u FOO -u HOME -u XDG_RUNTIME_DIR)],
+			undef, $opt), 'unset multiple');
+	is($out.$err, '', 'no errors output for unset');
+	ok(run_script([qw(lei daemon-env -0)], undef, $opt), 'show again');
+	is($err, '', 'no errors in env dump');
+	@env = split(/\0/, $out);
+	is(scalar grep(/\A(?:HOME|XDG_RUNTIME_DIR)=\z/, @env), 0, 'env unset@');
+	$out = '';
+	ok(run_script([qw(lei daemon-env -)], undef, $opt), 'clear env');
+	is($out.$err, '', 'no output');
+	ok(run_script([qw(lei daemon-env)], undef, $opt), 'env is empty');
+	is($out, '', 'env cleared');
+
 	ok(run_script([qw(lei daemon-stop)], undef, $opt), 'daemon-stop');
 	is($out, '', 'no output from daemon-stop');
 	is($err, '', 'no error from daemon-stop');

^ permalink raw reply related	[relevance 6%]

* [PATCH 00/26] lei: basic UI + IPC work
@ 2020-12-18 12:09  7% Eric Wong
  2020-12-18 12:09  6% ` [PATCH 09/26] lei: support `daemon-env' for modifying long-lived env Eric Wong
  0 siblings, 1 reply; 2+ results
From: Eric Wong @ 2020-12-18 12:09 UTC (permalink / raw)
  To: meta

Some work on the storage side, but MiscIdx still needs work to
handle existing publicinboxes, extinboxes (over HTTP(S)), and
other config things.

PATCH 22/26 - bash completion sorta works, but filename
completions get broken.  Not sure why and help would be
greatly appreciated (along with help for other shells).
I don't know bash-specific stuff well at all, even; and
less about other non-POSIX shells.

Somewhat nice UI things (at least to my delirious sleep-deprived
state):

* -$DIGIT option parsing works (e.g. "git log -10"),
  "kill -9"

* help-based CLI arg/prototype checking seems working
  and hopefully cuts down on long-term maintenance work
  while promoting UI consistency

* having IO::FDPass hides startup time, 20-30ms isn't
  really noticeable for humans on interactive terminals,
  but still not ideal for loops.

* lei.sh + "make symlink-install"

And some internal improvements:

* several simplifications to existing Search code,
  ->xdb_shards_flat will come in handy

* generic OnDestroy - long overdue

Eric Wong (26):
  lei: FD-passing and IPC basics
  lei: proposed command-listing and options
  lei_store: local storage for Local Email Interface
  tests: more common JSON module loading
  lei: use spawn (vfork + execve) for lazy start
  lei: refine help/option parsing, implement "init"
  t/lei-oneshot: standalone oneshot (non-socket) test
  lei: ensure we run a restrictive umask
  lei: support `daemon-env' for modifying long-lived env
  lei_store: simplify git_epoch_max, slightly
  search: simplify initialization, add ->xdb_shards_flat
  rename LeiDaemon package to PublicInbox::LEI
  lei: support pass-through for `lei config'
  lei: help: show actual paths being operated on
  lei: rename $client => $self and bless
  lei: micro-optimize startup time
  lei_store: relax GIT_COMMITTER_IDENT check
  lei_store: keyword extraction from mbox and Maildir
  on_destroy: generic localized END
  lei: restore default __DIE__ handler for event loop
  lei: drop $SIG{__DIE__}, add oneshot fallbacks
  lei: start working on bash completion
  build: add lei.sh + "make symlink-install" target
  lei: support for -$DIGIT and -$SIG CLI switches
  lei: revise output routines
  lei: extinbox: start implementing in config file

 MANIFEST                               |  11 +
 Makefile.PL                            |  11 +
 contrib/completion/lei-completion.bash |  11 +
 lei.sh                                 |   7 +
 lib/PublicInbox/Daemon.pm              |   6 +-
 lib/PublicInbox/ExtSearch.pm           |  10 +-
 lib/PublicInbox/ExtSearchIdx.pm        |  35 +-
 lib/PublicInbox/Import.pm              |   4 +
 lib/PublicInbox/LEI.pm                 | 776 +++++++++++++++++++++++++
 lib/PublicInbox/LeiExtinbox.pm         |  52 ++
 lib/PublicInbox/LeiSearch.pm           |  39 ++
 lib/PublicInbox/LeiStore.pm            | 227 ++++++++
 lib/PublicInbox/ManifestJsGz.pm        |   2 +-
 lib/PublicInbox/OnDestroy.pm           |  16 +
 lib/PublicInbox/OverIdx.pm             |  10 +
 lib/PublicInbox/Search.pm              |  65 +--
 lib/PublicInbox/SearchIdx.pm           |  62 +-
 lib/PublicInbox/SearchIdxShard.pm      |  33 ++
 lib/PublicInbox/TestCommon.pm          |   7 +-
 lib/PublicInbox/V2Writable.pm          |  10 +-
 script/lei                             |  76 +++
 t/extsearch.t                          |   3 +-
 t/lei-oneshot.t                        |  25 +
 t/lei.t                                | 306 ++++++++++
 t/lei_store.t                          |  88 +++
 t/on_destroy.t                         |  25 +
 t/www_listing.t                        |   8 +-
 27 files changed, 1843 insertions(+), 82 deletions(-)
 create mode 100644 contrib/completion/lei-completion.bash
 create mode 100755 lei.sh
 create mode 100644 lib/PublicInbox/LEI.pm
 create mode 100644 lib/PublicInbox/LeiExtinbox.pm
 create mode 100644 lib/PublicInbox/LeiSearch.pm
 create mode 100644 lib/PublicInbox/LeiStore.pm
 create mode 100644 lib/PublicInbox/OnDestroy.pm
 create mode 100755 script/lei
 create mode 100644 t/lei-oneshot.t
 create mode 100644 t/lei.t
 create mode 100644 t/lei_store.t
 create mode 100644 t/on_destroy.t

^ permalink raw reply	[relevance 7%]

Results 1-2 of 2 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2020-12-18 12:09  7% [PATCH 00/26] lei: basic UI + IPC work Eric Wong
2020-12-18 12:09  6% ` [PATCH 09/26] lei: support `daemon-env' for modifying long-lived env Eric Wong

Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).