Ferreteria/v0.6/clade/IO/Aspect/Connx/Runner/Remote/SSH2/@fx/DoCommand

From Woozle Writes Code
< Ferreteria‎ | v0.6‎ | clade‎ | IO‎ | Aspect‎ | Connx‎ | Runner‎ | 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, $oItWent has two Str objects for receiving data -- one for regular replies, one for errors.
    • So: we could either create an ItWent podling that encapsulates reply & error streams, or...
      ...we could just PullBytes() from the returned stream, and stuff them into the reply QStr.
      ...ohbutwait! That must be what $oItWent = $oStream->PullBytes() does, except we need to create & set up $oStream.
  • 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.

Code

as of 2026-03-06 (might or might not be working reliably):

#
    public function DoCommand(CLineIface $oCmd) : OpCmdIface {
        $this->Open();  // make sure connection is open (sets RNative())

        $oOpCmd = $this->OOpCmd();
        $oOpCmd->Clear();

        $oProcLecture = $this->StreamFromCommmand($oCmd);
        $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();
            }

            $oUpd = UpdateClass::FromStreams($oProcLecture,$oCodeListen);
            $qoUpd = $oCanalRecv->QOUpdater();
            $qoUpd->SetIt($oUpd);

            $oOpConvey = NULL;
            $doLoop = $oCmd->DoWait();
            $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

        }
        $this->Shut(); // done with connection for now

        return $oOpCmd;
    }