Skip to content

Commit

Permalink
Add support for installing images from CIFS network share
Browse files Browse the repository at this point in the history
Closes maxnet#96
  • Loading branch information
maxnet committed Aug 6, 2014
1 parent ccacd8f commit a3376fb
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 40 deletions.
189 changes: 153 additions & 36 deletions BerrybootGUI2.0/adddialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,6 @@ AddDialog::AddDialog(Installer *i, QWidget *parent) :
if (_i->hasSettings())
{
setProxy();
QSettings *s = _i->settings();
s->beginGroup("repo");
if (s->contains("url"))
_reposerver = s->value("url").toByteArray();
s->endGroup();
}

/* Detect if we are running on a rPi or some ARMv7 device
Expand Down Expand Up @@ -167,10 +162,17 @@ void AddDialog::downloadList()
QDir dir;
dir.mkdir(_cachedir);
}*/
_download = new DownloadThread(_reposerver);
connect(_download, SIGNAL(finished()), this, SLOT(downloadComplete()));
connect(_qpd, SIGNAL(canceled()), this, SLOT(cancelDownload()));
_download->start();
if (_reposerver.startsWith("cifs:") || _reposerver.startsWith("nfs:"))
{
generateListFromShare(_reposerver, _repouser, _repopass);
}
else
{
_download = new DownloadThread(_reposerver);
connect(_download, SIGNAL(finished()), this, SLOT(downloadComplete()));
connect(_qpd, SIGNAL(canceled()), this, SLOT(cancelDownload()));
_download->start();
}
}

void AddDialog::downloadComplete()
Expand Down Expand Up @@ -234,7 +236,11 @@ bool AddDialog::verifyData()
OpenSSL_add_all_algorithms();
_openSSLinitialized = true;
}
QByteArray data_uncompressed = qUncompress(_data);
QByteArray data_uncompressed;
if (_reposerver.endsWith(".smime"))
data_uncompressed = _data;
else
data_uncompressed = qUncompress(_data);
QString certfilename;

if (QFile::exists("/boot/berryboot.crt"))
Expand Down Expand Up @@ -349,7 +355,7 @@ void AddDialog::processData()
QFont f = osList->font();
f.setPointSize(16);
osList->setFont(f);
connect(osList, SIGNAL(currentRowChanged(int)), this, SLOT(on_osList_currentRowChanged(int)));
connect(osList, SIGNAL(itemSelectionChanged()), this, SLOT(onSelectionChanged()));

ui->groupTabs->addTab(osList, group);
}
Expand Down Expand Up @@ -470,7 +476,7 @@ void AddDialog::selfUpdate(const QString &updateurl, const QString &sha1)
setEnabled(true);
}

void AddDialog::on_osList_currentRowChanged(int)
void AddDialog::onSelectionChanged()
{
ui->buttonBox->button(ui->buttonBox->Ok)->setEnabled(true);
}
Expand All @@ -489,36 +495,50 @@ void AddDialog::accept()
QListWidget *osList = qobject_cast<QListWidget *>(ui->groupTabs->currentWidget());
if (!osList->currentItem())
return;
QString imagesection = osList->currentItem()->data(Qt::UserRole).toString();
_ini->beginGroup(imagesection);
QString url = _ini->value("url").toString();
QString alternateUrl;
QString sha1 = _ini->value("sha1").toString();
QString filename = _ini->value("name").toString() + ".img" + _ini->value("memsplit", "").toString();
filename.replace(" ", "_");
double size = _ini->value("size").toDouble() + 10000000; /* Add 10 MB extra for overhead */
double availablespace = _i->availableDiskSpace();

/* If mirrors are available, select a random one */
QStringList mirrors;
QStringList keys = _ini->childKeys();
foreach (QString key, keys)
{
if (key.startsWith("mirror"))

QString url, alternateUrl, sha1, filename;
double size, availablespace = _i->availableDiskSpace();

if (_ini)
{
QString imagesection = osList->currentItem()->data(Qt::UserRole).toString();
_ini->beginGroup(imagesection);
url = _ini->value("url").toString();
sha1 = _ini->value("sha1").toString();
filename = _ini->value("name").toString() + ".img" + _ini->value("memsplit", "").toString();
filename.replace(" ", "_");
size = _ini->value("size").toDouble() + 10000000; /* Add 10 MB extra for overhead */

/* If mirrors are available, select a random one */
QStringList mirrors;
QStringList keys = _ini->childKeys();
foreach (QString key, keys)
{
mirrors.append(_ini->value(key).toString());
if (key.startsWith("mirror"))
{
mirrors.append(_ini->value(key).toString());
}
}
if (!mirrors.isEmpty())
{
/* Try a random mirror first, and the main site if downloading from mirror fails */
alternateUrl = url;
qsrand(QTime::currentTime().msec());
url = mirrors.at(qrand() % mirrors.count());
}

_ini->endGroup();
}
if (!mirrors.isEmpty())
else
{
/* Try a random mirror first, and the main site if downloading from mirror fails */
alternateUrl = url;
qsrand(QTime::currentTime().msec());
url = mirrors.at(qrand() % mirrors.count());
/* File on network share */
filename = osList->currentItem()->data(Qt::UserRole).toString();
QFileInfo fi(filename);
size = fi.size() + 10000000; /* Add 10 MB extra for overhead */
url = "file://"+filename;
filename = fi.fileName();
}

_ini->endGroup();

if (size > availablespace)
{
QMessageBox::critical(this, tr("Low disk space"), tr("Not enough disk space available to install this OS"), QMessageBox::Close);
Expand Down Expand Up @@ -563,5 +583,102 @@ void AddDialog::setProxy()
DownloadThread::setProxy("");
}
s->endGroup();

s->beginGroup("repo");
if (s->contains("url"))
{
_reposerver = s->value("url").toByteArray();
_repouser = s->value("user").toByteArray();
_repopass = QByteArray::fromBase64(s->value("password").toByteArray());
}
else
{
_reposerver = DEFAULT_REPO_SERVER;
_repouser = _repopass = "";
}
s->endGroup();
}

void AddDialog::generateListFromShare(const QByteArray &url, QByteArray username, QByteArray password)
{
QApplication::processEvents();
QByteArray shareType, share;

if (url.startsWith("cifs:"))
{
shareType = "cifs";
share = url.mid(5);
if (username.isEmpty())
username = "guest";
}
else if (url.startsWith("nfs:"))
{
shareType = "nfs";
share = url.mid(4);
}
else
{
return;
}

_i->loadFilesystemModule(shareType);

QDir dir("/share");
if (dir.exists())
{
QProcess::execute("umount /share");
}
else
{
dir.mkdir("/share");
}

QStringList args;
args << "-t" << shareType << share << "/share";

if (!username.isEmpty())
{
args << "-o" << "username="+username;
if (!password.isEmpty())
args << "-o" << "password="+password;
}
if (QProcess::execute("mount", args) != 0)
{
dir.rmdir("/share");
QMessageBox::critical(this, tr("Mount error"), tr("Error mounting network share %1").arg(QString(share)), QMessageBox::Ok);
}
else
{
_ini = NULL;
ui->groupTabs->clear();

/* Create tab */
QListWidget *osList = new QListWidget();
osList->setIconSize(QSize(128,128));
osList->setSpacing(2);
QFont f = osList->font();
f.setPointSize(16);
osList->setFont(f);
connect(osList, SIGNAL(itemSelectionChanged()), this, SLOT(onSelectionChanged()));
ui->groupTabs->addTab(osList, tr("Network share"));

QStringList namefilters;
namefilters << "*.img*";

QFileInfoList list = dir.entryInfoList(namefilters, QDir::Files, QDir::Name);
foreach (QFileInfo fi, list)
{
QString name = fi.fileName().replace('_',' ');
QString sizeinmb = QString::number(fi.size()/1024/1024);
QListWidgetItem *item = new QListWidgetItem(name+" ("+sizeinmb+" MB)", osList);
item->setData(Qt::UserRole, fi.absoluteFilePath() );
}
}

if (_qpd)
{
_qpd->hide();
_qpd->deleteLater();
_qpd = NULL;
}
}
9 changes: 7 additions & 2 deletions BerrybootGUI2.0/adddialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public slots:
Installer *_i;
QString _cachedir, _device, _kernelversion;
QSettings *_ini;
QByteArray _reposerver;
QByteArray _reposerver, _repouser, _repopass;
DownloadThread *_download;

static bool _openSSLinitialized;
Expand All @@ -70,6 +70,11 @@ public slots:
*/
void processData();

/*
* Generate the list from files in a CIFS or NFS network share
*/
void generateListFromShare(const QByteArray &share, QByteArray username = "", QByteArray password = "");

/*
* Return SHA1 hash of file
*/
Expand All @@ -96,7 +101,7 @@ protected slots:
void cancelDownload();

private slots:
void on_osList_currentRowChanged(int currentRow);
void onSelectionChanged();
void onProxySettings();
void on_groupTabs_currentChanged(int index);
};
Expand Down
6 changes: 6 additions & 0 deletions BerrybootGUI2.0/bootmenudialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@
<iconset resource="icons.qrc">
<normaloff>:/icons/exit.png</normaloff>:/icons/exit.png</iconset>
</property>
<property name="iconSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
</widget>
</item>
</layout>
Expand Down
15 changes: 15 additions & 0 deletions BerrybootGUI2.0/installer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,21 @@ void Installer::loadSoundModule(const QByteArray &channel)
}
}

void Installer::loadFilesystemModule(const QByteArray &fs)
{
/* Only load module if fs is not already supported */
QFile f("/proc/filesystems");
f.open(f.ReadOnly);
QByteArray fsSupported = f.readAll();
f.close();

if (!fsSupported.contains(fs))
{
prepareDrivers();
QProcess::execute("/sbin/modprobe "+fs);
}
}

void Installer::startWifi()
{
loadDrivers();
Expand Down
1 change: 1 addition & 0 deletions BerrybootGUI2.0/installer.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class Installer : public QObject
void loadDrivers();
void loadCryptoModules();
void loadSoundModule(const QByteArray &channel);
void loadFilesystemModule(const QByteArray &fs);
void startWifi();

void setKeyboardLayout(const QString &layout);
Expand Down
25 changes: 24 additions & 1 deletion BerrybootGUI2.0/networksettingsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ NetworkSettingsDialog::NetworkSettingsDialog(Installer *i, QWidget *parent) :
ui->proxyhostEdit->setText(s->value("hostname").toString());
ui->proxyportEdit->setText(QString::number(s->value("port", 8080).toInt()));
ui->proxyuserEdit->setText(s->value("user").toString());
ui->proxypassEdit->setText(s->value("password").toString());
ui->proxypassEdit->setText(QByteArray::fromBase64(s->value("password").toByteArray()));
s->endGroup();

/* Repo tab */
s->beginGroup("repo");
ui->repoEdit->setText(s->value("url").toString());
ui->repoUserEdit->setText(s->value("user").toString());
ui->repoPassEdit->setText(QByteArray::fromBase64(s->value("password").toByteArray()));
s->endGroup();
}

Expand Down Expand Up @@ -196,6 +203,22 @@ void NetworkSettingsDialog::accept()
s->setValue("password", ui->proxypassEdit->text().toAscii().toBase64());
}

s->endGroup();

s->beginGroup("repo");
if (ui->repoEdit->text().isEmpty())
s->remove("url");
else
s->setValue("url", ui->repoEdit->text() );
if (ui->repoUserEdit->text().isEmpty())
s->remove("user");
else
s->setValue("user", ui->repoUserEdit->text() );
if (ui->repoPassEdit->text().isEmpty())
s->remove("password");
else
s->setValue("password", ui->repoPassEdit->text().toAscii().toBase64());

s->endGroup();
s->sync();

Expand Down
Loading

0 comments on commit a3376fb

Please sign in to comment.