forked from qt-creator/qt-creator
Deviceshell: Base64 not found fallback
If no base64 is installed on the target, the shell script cannot work. Previously this would lead to the shell functions being unavailable. This change adds a fallback path. In case no base64 is found, the shell will create a process for each run request instead. This is much slower than the shell script, but acceptable as a fallback. Change-Id: I70591d7e610c4e1c3c258a8e4bef354221d05cb9 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -85,9 +85,10 @@ static Q_LOGGING_CATEGORY(dockerDeviceLog, "qtc.docker.device", QtWarningMsg);
|
||||
class ContainerShell : public Utils::DeviceShell
|
||||
{
|
||||
public:
|
||||
ContainerShell(DockerSettings *settings, const QString &containerId)
|
||||
ContainerShell(DockerSettings *settings, const QString &containerId, const FilePath &devicePath)
|
||||
: m_settings(settings)
|
||||
, m_containerId(containerId)
|
||||
, m_devicePath(devicePath)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -97,9 +98,17 @@ private:
|
||||
shellProcess->setCommand({m_settings->dockerBinaryPath.filePath(), {"container", "start", "-i", "-a", m_containerId}});
|
||||
}
|
||||
|
||||
CommandLine createFallbackCommand(const CommandLine &cmdLine)
|
||||
{
|
||||
CommandLine result = cmdLine;
|
||||
result.setExecutable(cmdLine.executable().onDevice(m_devicePath));
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
DockerSettings *m_settings;
|
||||
QString m_containerId;
|
||||
FilePath m_devicePath;
|
||||
};
|
||||
|
||||
class DockerDevicePrivate : public QObject
|
||||
@@ -118,6 +127,7 @@ public:
|
||||
|
||||
void updateContainerAccess();
|
||||
|
||||
bool createContainer();
|
||||
void startContainer();
|
||||
void stopCurrentContainer();
|
||||
void fetchSystemEnviroment();
|
||||
@@ -199,11 +209,12 @@ DockerProcessImpl::DockerProcessImpl(DockerDevicePrivate *device)
|
||||
QByteArray output = m_process.readAllStandardOutput();
|
||||
qsizetype idx = output.indexOf('\n');
|
||||
QByteArray firstLine = output.left(idx);
|
||||
QByteArray rest = output.mid(idx+1);
|
||||
qCDebug(dockerDeviceLog) << "Process first line received:" << m_process.commandLine() << firstLine;
|
||||
QByteArray rest = output.mid(idx + 1);
|
||||
qCDebug(dockerDeviceLog)
|
||||
<< "Process first line received:" << m_process.commandLine() << firstLine;
|
||||
if (firstLine.startsWith("__qtc")) {
|
||||
bool ok = false;
|
||||
m_remotePID = firstLine.mid(5, firstLine.size() -5 -5).toLongLong(&ok);
|
||||
m_remotePID = firstLine.mid(5, firstLine.size() - 5 - 5).toLongLong(&ok);
|
||||
|
||||
if (ok)
|
||||
emit started(m_remotePID);
|
||||
@@ -223,10 +234,10 @@ DockerProcessImpl::DockerProcessImpl(DockerDevicePrivate *device)
|
||||
});
|
||||
|
||||
connect(&m_process, &QtcProcess::done, this, [this] {
|
||||
qCDebug(dockerDeviceLog) << "Process exited:" << m_process.commandLine() << "with code:" << m_process.resultData().m_exitCode;
|
||||
qCDebug(dockerDeviceLog) << "Process exited:" << m_process.commandLine()
|
||||
<< "with code:" << m_process.resultData().m_exitCode;
|
||||
emit done(m_process.resultData());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
DockerProcessImpl::~DockerProcessImpl()
|
||||
@@ -391,19 +402,23 @@ static QString getLocalIPv4Address()
|
||||
return QString();
|
||||
}
|
||||
|
||||
void DockerDevicePrivate::startContainer()
|
||||
bool DockerDevicePrivate::createContainer()
|
||||
{
|
||||
if (!m_settings)
|
||||
return;
|
||||
return false;
|
||||
|
||||
const QString display = HostOsInfo::isLinuxHost() ? QString(":0")
|
||||
: QString(getLocalIPv4Address() + ":0.0");
|
||||
CommandLine dockerCreate{m_settings->dockerBinaryPath.filePath(), {"create",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e", QString("DISPLAY=%1").arg(display),
|
||||
"-e", "XAUTHORITY=/.Xauthority",
|
||||
"--net", "host"}};
|
||||
CommandLine dockerCreate{m_settings->dockerBinaryPath.filePath(),
|
||||
{"create",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
QString("DISPLAY=%1").arg(display),
|
||||
"-e",
|
||||
"XAUTHORITY=/.Xauthority",
|
||||
"--net",
|
||||
"host"}};
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
// no getuid() and getgid() on Windows.
|
||||
@@ -423,7 +438,7 @@ void DockerDevicePrivate::startContainer()
|
||||
|
||||
dockerCreate.addArgs({"--entrypoint", "/bin/sh", m_data.repoAndTag()});
|
||||
|
||||
LOG("RUNNING: " << dockerCreate.toUserOutput());
|
||||
qCDebug(dockerDeviceLog) << "RUNNING: " << dockerCreate.toUserOutput();
|
||||
QtcProcess createProcess;
|
||||
createProcess.setCommand(dockerCreate);
|
||||
createProcess.runBlocking();
|
||||
@@ -432,16 +447,29 @@ void DockerDevicePrivate::startContainer()
|
||||
qCWarning(dockerDeviceLog) << "Failed creating docker container:";
|
||||
qCWarning(dockerDeviceLog) << "Exit Code:" << createProcess.exitCode();
|
||||
qCWarning(dockerDeviceLog) << createProcess.allOutput();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_container = createProcess.cleanedStdOut().trimmed();
|
||||
if (m_container.isEmpty())
|
||||
return;
|
||||
LOG("Container via process: " << m_container);
|
||||
return false;
|
||||
|
||||
m_shell = std::make_unique<ContainerShell>(m_settings, m_container);
|
||||
connect(m_shell.get(), &DeviceShell::done, this, [this] (const ProcessResultData &resultData) {
|
||||
LOG("ContainerId: " << m_container);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DockerDevicePrivate::startContainer()
|
||||
{
|
||||
if (!createContainer())
|
||||
return;
|
||||
|
||||
m_shell = std::make_unique<ContainerShell>(m_settings,
|
||||
m_container,
|
||||
FilePath::fromString(
|
||||
QString("device://%1/")
|
||||
.arg(this->q->id().toString())));
|
||||
|
||||
connect(m_shell.get(), &DeviceShell::done, this, [this](const ProcessResultData &resultData) {
|
||||
if (resultData.m_error != QProcess::UnknownError)
|
||||
return;
|
||||
|
||||
@@ -977,7 +1005,7 @@ void DockerDevice::aboutToBeRemoved() const
|
||||
|
||||
void DockerDevicePrivate::fetchSystemEnviroment()
|
||||
{
|
||||
if (m_shell) {
|
||||
if (m_shell && m_shell->state() == DeviceShell::State::Succeeded) {
|
||||
const QByteArray output = outputForRunInShell({"env", {}});
|
||||
const QString out = QString::fromUtf8(output.data(), output.size());
|
||||
m_cachedEnviroment = Environment(out.split('\n', Qt::SkipEmptyParts), q->osType());
|
||||
|
||||
Reference in New Issue
Block a user