Ferreteria/v0.6/clade/IO/Aspect/Connx/run/Starter/Remote/SSH2/@fx/DoCommand
< Ferreteria | v0.6 | clade | IO | Aspect | Connx | run/Starter | Remote | SSH2
Jump to navigation
Jump to search
History
- 2026-01-09 THINKING: It doesn't really make sense to pass in a Stream here, since
ssh2_exec()creates one.- Also,
$oItWenthas twoStrobjects for receiving data -- one for regular replies, one for errors. - So: we could either create an
ItWentpodling that encapsulates reply & error streams, or...- ...we could just
PullBytes()from the returned stream, and stuff them into the replyQStr. - ...ohbutwait! That must be what
$oItWent = $oStream->PullBytes()does, except we need to create & set up$oStream.
- ...we could just
- Also,
- 2026-01-17 disabled, with the note "This is actually an OVERRIDE -- and the parent properly creates a Process..." -- but it turns out I was confused
- 2026-01-20 Re-enabled, because Process only executes locally -- so either the command needs to be wrapped, or we need to execute it with ssh2.
- I guess we need different versions of SSH depending on which way we want to do things. Note that the ssh2 library functions cannot wrap more than once, i.e. you can't use this class to build a chain of ssh connections (A connecting to B and then connecting to C).
- 2026-03-06 Currently works for schema-list-retrieval, but EoF() reporting fails for schema-export. See 2026/03/06 for work in progress.
- 2026-03-16 Moved the
Canalsloop to its own function inRunner:DoInOutLoop().
Code: Current
as of 2026-03-17 (might or might not be working reliably):
#
public function DoCommand(CLineIface $oCmd) : OpCmdIface {
$oCmd->QORunner()->SetIt($this);
$this->Open(); // make sure connection is open (sets RNative())
$oHints = $oCmd->Hints();
$sEndHint = $oHints->GetItNz('eos',NULL);
$useEmpty = ($sEndHint === 'empty'); // TODO: class constant
$oOpCmd = $this->OOpCmd();
$oOpCmd->Clear();
$oProcLecture = $this->StreamFromCommmand($oCmd);
$oProcLecture->UseEoS(!$useEmpty);
$this->LectureStream($oProcLecture);
if (is_object($oProcLecture)) {
$oCanals = CanalsClass::FromVoid();
$qoCmdListen = $oCmd->QOListener(); // stream to receive data
if ($qoCmdListen->HasIt()) {
$oCodeListen = $qoCmdListen->GetIt();
$oCanalRecv = ConveyClass::FromPair($oProcLecture,$oCodeListen);
$oCanals->AddIt($oCanalRecv);
} else {
stream_set_blocking($rRecv, TRUE); // wait for entire output when reading
$oItWent = $oLecture->PullBytes();
#echo '** OUTCOME: '.CRLF.$oItWent->VIEW_AsBlock();
}
$this->OCanals($oCanals); // make the Canals object publicly available
$oOpConvey = NULL;
}
$this->Shut(); // done with connection for now
return $oOpCmd;
}
Code: Removed
2026-03-17
Commented out yesterday, from just under $oOpConvey = NULL:
#
#$doLoop = $oCmd->DoWait();
// 2026-03-16 Caller is now responsible for this.
$doLoop = $oCmd->HasIt();
$oCanals->Open();
while ($doLoop) {
$isGoing = $this->IsRunning();
if ($isGoing) {
$oOpNew = $oCanals->ConveyCheck();
if (is_object($oOpConvey)) {
$oOpNew->Assimilate($oOpConvey);
}
$oOpConvey = $oOpNew;
$this->OnIterate();
}
$doLoop = $isGoing;
}
$oCanals->Shut();
if (is_object($oOpConvey)) {
$oOpCmd->Assimilate($oOpConvey); // TODO 2026-02-22 review this logic. Maybe CopyFrom() instead?
}
$oOpCmd->SetOkay(TRUE); // 2026-03-05 not sure what error conditions might exist here; for now, assume ok
On 2026-03-03, just before rewrite using Canals object (I renamed it instead of commenting it out):
#
// 2026-03-03 old version, before rewriting to use Canals:
public function DoCommandV1(CLineIface $oCmd) : OpCmdIface {
$this->Open(); // make sure connection is open
$rStrm = $this->RNative();
$rRecv = ssh2_exec($rStrm, $oCmd->AsString());
#$doWait = $oCmd->DoWait();
$doWait = $oCmd->HasIt();
// 2026-02-25 TODO: implement some way to access the streams from outside when $doWait is FALSE
$oLecture = StreamClass::FromNative($rRecv);
#$rErrs = ssh2_fetch_stream($rRecv, SSH2_STREAM_STDERR); // 2026/02/06 there are complications with this, apparently; see docs for ssh2_exec()
$qoListen = $oCmd->QOListener(); // stream to receive data
if ($qoListen->HasIt()) {
$oListen = $qoListen->GetIt();
$oConvey = new ConveyClass;
stream_set_blocking($rRecv, TRUE); // wait for entire output when reading - TESTING
$oItWent = $oConvey->ConveyNow($oLecture,$oListen);
} else {
stream_set_blocking($rRecv, TRUE); // wait for entire output when reading
$oItWent = $oLecture->PullBytes();
#echo '** OUTCOME: '.CRLF.$oItWent->VIEW_AsBlock();
}
$oProcOp = $this->OOpCmd();
$oProcOp->CopyFrom($oItWent);
$this->Shut(); // done with connection for now
return $oProcOp;
}