From 9abf5e115a99b20c51861f7ddbcd13e30cd5195b Mon Sep 17 00:00:00 2001 From: Steven Powell Date: Fri, 2 Dec 2022 11:48:49 -0800 Subject: [PATCH] init commit --- README.md | 53 ++++-- advancedview.cpp | 308 ++++++++++++++++++++++++++++++ advancedview.h | 77 ++++++++ basicview.cpp | 119 ++++++++++++ basicview.h | 58 ++++++ cluster.cpp | 114 ++++++++++++ cluster.h | 89 +++++++++ commandrunner.cpp | 257 +++++++++++++++++++++++++ commandrunner.h | 79 ++++++++ errormessage.cpp | 80 ++++++++ errormessage.h | 43 +++++ hyperkit.cpp | 73 ++++++++ hyperkit.h | 41 ++++ images/minikube.icns | Bin 0 -> 119220 bytes images/minikube.png | Bin 0 -> 34174 bytes logger.cpp | 42 +++++ logger.h | 34 ++++ main.cpp | 58 ++++++ minikube.pro | 45 +++++ minikube.qrc | 5 + operator.cpp | 434 +++++++++++++++++++++++++++++++++++++++++++ operator.h | 90 +++++++++ progresswindow.cpp | 81 ++++++++ progresswindow.h | 54 ++++++ releases.json | 5 + tray.cpp | 132 +++++++++++++ tray.h | 61 ++++++ updater.cpp | 133 +++++++++++++ updater.h | 39 ++++ window.cpp | 152 +++++++++++++++ window.h | 96 ++++++++++ 31 files changed, 2837 insertions(+), 15 deletions(-) create mode 100644 advancedview.cpp create mode 100644 advancedview.h create mode 100644 basicview.cpp create mode 100644 basicview.h create mode 100644 cluster.cpp create mode 100644 cluster.h create mode 100644 commandrunner.cpp create mode 100644 commandrunner.h create mode 100644 errormessage.cpp create mode 100644 errormessage.h create mode 100644 hyperkit.cpp create mode 100644 hyperkit.h create mode 100644 images/minikube.icns create mode 100644 images/minikube.png create mode 100644 logger.cpp create mode 100644 logger.h create mode 100644 main.cpp create mode 100644 minikube.pro create mode 100644 minikube.qrc create mode 100644 operator.cpp create mode 100644 operator.h create mode 100644 progresswindow.cpp create mode 100644 progresswindow.h create mode 100644 releases.json create mode 100644 tray.cpp create mode 100644 tray.h create mode 100644 updater.cpp create mode 100644 updater.h create mode 100644 window.cpp create mode 100644 window.h diff --git a/README.md b/README.md index 5bf9c1f..4c757a1 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,48 @@ -# Kubernetes Template Project +# minikube GUI -The Kubernetes Template Project is a template for starting new projects in the GitHub organizations owned by Kubernetes. All Kubernetes projects, at minimum, must have the following files: +## Usage -- a `README.md` outlining the project goals, sponsoring sig, and community contact information -- an `OWNERS` with the project leads listed as approvers ([docs on `OWNERS` files][owners]) -- a `CONTRIBUTING.md` outlining how to contribute to the project -- an unmodified copy of `code-of-conduct.md` from this repo, which outlines community behavior and the consequences of breaking the code -- a `LICENSE` which must be Apache 2.0 for code projects, or [Creative Commons 4.0] for documentation repositories, without any custom content -- a `SECURITY_CONTACTS` with the contact points for the Product Security Team - to reach out to for triaging and handling of incoming issues. They must agree to abide by the - [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy) - and will be removed and replaced if they violate that agreement. +### Prerequisites + +- minikube setup and available on your path, follow the [Getting Start doc](https://minikube.sigs.k8s.io/docs/start/) if not already done + +### Running + +#### From binary (end-user) + +View our documentation for downloading and running the GUI: [Setting Up minikube GUI](https://minikube.sigs.k8s.io/docs/tutorials/setup_minikube_gui/) + +#### From Qt Creator + +Open in [Qt Creator](https://doc.qt.io/qtcreator/) via: + +```shell +qtcreator minikube.pro +``` + +#### From Command Line + +```console +$ qmake +$ make +... +$ ./minikube +``` ## Community, discussion, contribution, and support -Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/). +minikube GUI is a Kubernetes [#sig-cluster-lifecycle](https://github.com/kubernetes/community/tree/master/sig-cluster-lifecycle) project. + +* [**#minikube on Kubernetes Slack**](https://kubernetes.slack.com) - Live chat with minikube developers! +* [minikube-users mailing list](https://groups.google.com/g/minikube-users) +* [minikube-dev mailing list](https://groups.google.com/g/minikube-dev) -You can reach the maintainers of this project at: +* [Contributing](https://minikube.sigs.k8s.io/docs/contrib/) +* [Development Roadmap](https://minikube.sigs.k8s.io/docs/contrib/roadmap/) -- [Slack](https://slack.k8s.io/) -- [Mailing List](https://groups.google.com/a/kubernetes.io/g/dev) +Join our meetings: +* [Bi-weekly office hours, Mondays @ 11am PST](https://tinyurl.com/minikube-oh) +* [Triage Party](https://minikube.sigs.k8s.io/docs/contrib/triage/) ### Code of conduct diff --git a/advancedview.cpp b/advancedview.cpp new file mode 100644 index 0000000..0b60c7d --- /dev/null +++ b/advancedview.cpp @@ -0,0 +1,308 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "advancedview.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +AdvancedView::AdvancedView(QIcon icon) +{ + m_icon = icon; + + advancedView = new QWidget(); + advancedView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + + ClusterList clusters; + m_clusterModel = new ClusterModel(clusters); + + clusterListView = new QTableView(); + clusterListView->setModel(m_clusterModel); + clusterListView->setSelectionMode(QAbstractItemView::SingleSelection); + clusterListView->setSelectionBehavior(QAbstractItemView::SelectRows); + clusterListView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + clusterListView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + clusterListView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents); + clusterListView->horizontalHeader()->setSectionResizeMode(3, QHeaderView::ResizeToContents); + clusterListView->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeToContents); + clusterListView->horizontalHeader()->setSectionResizeMode(5, QHeaderView::ResizeToContents); + clusterListView->horizontalHeader()->setSectionResizeMode(6, QHeaderView::ResizeToContents); + setSelectedClusterName("default"); + + startButton = new QPushButton(tr("Start")); + stopButton = new QPushButton(tr("Stop")); + pauseButton = new QPushButton(tr("Pause")); + deleteButton = new QPushButton(tr("Delete")); + refreshButton = new QPushButton(tr("Refresh")); + createButton = new QPushButton(tr("Create")); + dockerEnvButton = new QPushButton(tr("docker-env")); + sshButton = new QPushButton(tr("SSH")); + dashboardButton = new QPushButton(tr("Dashboard")); + basicButton = new QPushButton(tr("Basic View")); + + disableButtons(); + + QHBoxLayout *topButtonLayout = new QHBoxLayout; + topButtonLayout->addWidget(createButton); + topButtonLayout->addWidget(refreshButton); + topButtonLayout->addWidget(basicButton); + topButtonLayout->addSpacing(340); + + QHBoxLayout *bottomButtonLayout = new QHBoxLayout; + bottomButtonLayout->addWidget(startButton); + bottomButtonLayout->addWidget(stopButton); + bottomButtonLayout->addWidget(pauseButton); + bottomButtonLayout->addWidget(deleteButton); + bottomButtonLayout->addWidget(dockerEnvButton); + bottomButtonLayout->addWidget(sshButton); + bottomButtonLayout->addWidget(dashboardButton); + + QVBoxLayout *clusterLayout = new QVBoxLayout; + clusterLayout->addLayout(topButtonLayout); + clusterLayout->addWidget(clusterListView); + clusterLayout->addLayout(bottomButtonLayout); + advancedView->setLayout(clusterLayout); + + QFont *loadingFont = new QFont(); + loadingFont->setPointSize(30); + loading = new QLabel("Loading..."); + loading->setFont(*loadingFont); + loading->setParent(clusterListView); + loading->setHidden(true); + + connect(startButton, &QAbstractButton::clicked, this, &AdvancedView::start); + connect(stopButton, &QAbstractButton::clicked, this, &AdvancedView::stop); + connect(pauseButton, &QAbstractButton::clicked, this, &AdvancedView::pause); + connect(deleteButton, &QAbstractButton::clicked, this, &AdvancedView::delete_); + connect(refreshButton, &QAbstractButton::clicked, this, &AdvancedView::refresh); + connect(createButton, &QAbstractButton::clicked, this, &AdvancedView::askName); + connect(dockerEnvButton, &QAbstractButton::clicked, this, &AdvancedView::dockerEnv); + connect(sshButton, &QAbstractButton::clicked, this, &AdvancedView::ssh); + connect(dashboardButton, &QAbstractButton::clicked, this, &AdvancedView::dashboard); + connect(basicButton, &QAbstractButton::clicked, this, &AdvancedView::basic); +} + +static QString getPauseLabel(bool isPaused) +{ + if (isPaused) { + return "Unpause"; + } + return "Pause"; +} + +static QString getStartLabel(bool isRunning) +{ + if (isRunning) { + return "Restart"; + } + return "Start"; +} + +void AdvancedView::update(Cluster cluster) +{ + basicButton->setEnabled(true); + createButton->setEnabled(true); + refreshButton->setEnabled(true); + bool exists = !cluster.isEmpty(); + bool isRunning = cluster.status() == "Running"; + bool isPaused = cluster.status() == "Paused"; + startButton->setEnabled(exists); + stopButton->setEnabled(isRunning || isPaused); + pauseButton->setEnabled(isRunning || isPaused); + deleteButton->setEnabled(exists); + dashboardButton->setEnabled(isRunning); +#if __linux__ || __APPLE__ + dockerEnvButton->setEnabled(isRunning); + sshButton->setEnabled(exists); +#else + dockerEnvButton->setEnabled(false); + sshButton->setEnabled(false); +#endif + pauseButton->setText(getPauseLabel(isPaused)); + startButton->setText(getStartLabel(isRunning)); + QString startToolTip = ""; + if (isRunning) { + startToolTip = "Restart an already running minikube instance to pickup config changes."; + } + startButton->setToolTip(startToolTip); +} + +void AdvancedView::setSelectedClusterName(QString cluster) +{ + QAbstractItemModel *model = clusterListView->model(); + QModelIndex start = model->index(0, 0); + QModelIndexList index = model->match(start, Qt::DisplayRole, cluster); + if (index.size() == 0) { + return; + } + clusterListView->setCurrentIndex(index[0]); +} + +QString AdvancedView::selectedClusterName() +{ + QModelIndex index = clusterListView->currentIndex(); + QVariant variant = index.siblingAtColumn(0).data(Qt::DisplayRole); + if (variant.isNull()) { + return QString(); + } + return variant.toString(); +} + +void AdvancedView::updateClustersTable(ClusterList clusterList) +{ + QString cluster = selectedClusterName(); + m_clusterModel->setClusters(clusterList); + setSelectedClusterName(cluster); +} + +static int getCenter(int widgetSize, int parentSize) +{ + return parentSize / 2 - widgetSize / 2; +} + +void AdvancedView::showLoading() +{ + clusterListView->setEnabled(false); + loading->setHidden(false); + loading->raise(); + int width = getCenter(loading->width(), clusterListView->width()); + int height = getCenter(loading->height(), clusterListView->height()); + loading->move(width, height); +} + +void AdvancedView::hideLoading() +{ + loading->setHidden(true); + clusterListView->setEnabled(true); +} + +static QString profile = "minikube"; +static int cpus = 2; +static int memory = 2400; +static QString driver = ""; +static QString containerRuntime = ""; +static QString k8sVersion = ""; + +void AdvancedView::askName() +{ + QDialog dialog; + dialog.setWindowTitle(tr("Create minikube Cluster")); + dialog.setWindowIcon(m_icon); + dialog.setModal(true); + + QFormLayout form(&dialog); + QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); + QLineEdit profileField(profile, &dialog); + form.addRow(new QLabel(tr("Profile")), &profileField); + buttonBox.addButton(QString(tr("Use Default Values")), QDialogButtonBox::AcceptRole); + connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + buttonBox.addButton(QString(tr("Set Custom Values")), QDialogButtonBox::RejectRole); + connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + form.addRow(&buttonBox); + + int code = dialog.exec(); + profile = profileField.text(); + if (code == QDialog::Accepted) { + QStringList args = { "-p", profile }; + emit createCluster(args); + } else if (code == QDialog::Rejected) { + askCustom(); + } +} + +void AdvancedView::askCustom() +{ + QDialog dialog; + dialog.setWindowTitle(tr("Set Cluster Values")); + dialog.setWindowIcon(m_icon); + dialog.setModal(true); + + QFormLayout form(&dialog); + QComboBox *driverComboBox = new QComboBox; + driverComboBox->addItems({ "docker", "virtualbox", "vmware", "podman" }); +#if __linux__ + driverComboBox->addItems({ "kvm2", "qemu" }); +#elif __APPLE__ + driverComboBox->addItems({ "hyperkit", "qemu", "parallels" }); +#else + driverComboBox->addItem("hyperv"); +#endif + form.addRow(new QLabel(tr("Driver")), driverComboBox); + QComboBox *containerRuntimeComboBox = new QComboBox; + containerRuntimeComboBox->addItems({ "docker", "containerd", "crio" }); + form.addRow(new QLabel(tr("Container Runtime")), containerRuntimeComboBox); + QComboBox *k8sVersionComboBox = new QComboBox; + k8sVersionComboBox->addItems({ "stable", "latest", "none" }); + form.addRow(new QLabel(tr("Kubernetes Version")), k8sVersionComboBox); + QLineEdit cpuField(QString::number(cpus), &dialog); + form.addRow(new QLabel(tr("CPUs")), &cpuField); + QLineEdit memoryField(QString::number(memory), &dialog); + form.addRow(new QLabel(tr("Memory")), &memoryField); + + QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); + buttonBox.addButton(QString(tr("Create")), QDialogButtonBox::AcceptRole); + connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + buttonBox.addButton(QString(tr("Cancel")), QDialogButtonBox::RejectRole); + connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + form.addRow(&buttonBox); + + int code = dialog.exec(); + if (code == QDialog::Accepted) { + driver = driverComboBox->itemText(driverComboBox->currentIndex()); + containerRuntime = + containerRuntimeComboBox->itemText(containerRuntimeComboBox->currentIndex()); + k8sVersion = k8sVersionComboBox->itemText(k8sVersionComboBox->currentIndex()); + if (k8sVersion == "none") { + k8sVersion = "v0.0.0"; + } + cpus = cpuField.text().toInt(); + memory = memoryField.text().toInt(); + QStringList args = { "-p", + profile, + "--driver", + driver, + "--container-runtime", + containerRuntime, + "--kubernetes-version", + k8sVersion, + "--cpus", + QString::number(cpus), + "--memory", + QString::number(memory) }; + emit createCluster(args); + } +} + +void AdvancedView::disableButtons() +{ + startButton->setEnabled(false); + stopButton->setEnabled(false); + pauseButton->setEnabled(false); + deleteButton->setEnabled(false); + dockerEnvButton->setEnabled(false); + sshButton->setEnabled(false); + dashboardButton->setEnabled(false); + basicButton->setEnabled(false); + createButton->setEnabled(false); + refreshButton->setEnabled(false); +} diff --git a/advancedview.h b/advancedview.h new file mode 100644 index 0000000..15fafd9 --- /dev/null +++ b/advancedview.h @@ -0,0 +1,77 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef ADVANCEDVIEW_H +#define ADVANCEDVIEW_H + +#include "cluster.h" + +#include +#include +#include +#include + +class AdvancedView : public QObject +{ + Q_OBJECT + +public: + explicit AdvancedView(QIcon icon); + QWidget *advancedView; + QTableView *clusterListView; + + QString selectedClusterName(); + void updateClustersTable(ClusterList clusters); + void showLoading(); + void hideLoading(); + void disableButtons(); + +public slots: + void update(Cluster cluster); + +signals: + void start(); + void stop(); + void pause(); + void delete_(); + void refresh(); + void dockerEnv(); + void ssh(); + void dashboard(); + void basic(); + void createCluster(QStringList args); + +private: + void setSelectedClusterName(QString cluster); + void askName(); + void askCustom(); + + QPushButton *startButton; + QPushButton *stopButton; + QPushButton *pauseButton; + QPushButton *deleteButton; + QPushButton *refreshButton; + QPushButton *dockerEnvButton; + QPushButton *sshButton; + QPushButton *dashboardButton; + QPushButton *basicButton; + QPushButton *createButton; + QLabel *loading; + ClusterModel *m_clusterModel; + QIcon m_icon; +}; + +#endif // ADVANCEDVIEW_H diff --git a/basicview.cpp b/basicview.cpp new file mode 100644 index 0000000..77a862c --- /dev/null +++ b/basicview.cpp @@ -0,0 +1,119 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "basicview.h" + +#include + +BasicView::BasicView() +{ + basicView = new QWidget(); + + startButton = new QPushButton(tr("Start")); + stopButton = new QPushButton(tr("Stop")); + pauseButton = new QPushButton(tr("Pause")); + deleteButton = new QPushButton(tr("Delete")); + refreshButton = new QPushButton(tr("Refresh")); + dockerEnvButton = new QPushButton(tr("docker-env")); + dockerEnvButton->setToolTip( + "Opens a terminal where the docker-cli points to docker engine inside " + "minikube\n(Useful for building docker images directly inside minikube)"); + sshButton = new QPushButton(tr("SSH")); + dashboardButton = new QPushButton(tr("Dashboard")); + advancedButton = new QPushButton(tr("Advanced View")); + + disableButtons(); + + QVBoxLayout *buttonLayout = new QVBoxLayout; + basicView->setLayout(buttonLayout); + buttonLayout->addWidget(startButton); + buttonLayout->addWidget(stopButton); + buttonLayout->addWidget(pauseButton); + buttonLayout->addWidget(deleteButton); + buttonLayout->addWidget(refreshButton); + buttonLayout->addWidget(dockerEnvButton); + buttonLayout->addWidget(sshButton); + buttonLayout->addWidget(dashboardButton); + buttonLayout->addWidget(advancedButton); + basicView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + + connect(startButton, &QPushButton::clicked, this, &BasicView::start); + connect(stopButton, &QAbstractButton::clicked, this, &BasicView::stop); + connect(pauseButton, &QAbstractButton::clicked, this, &BasicView::pause); + connect(deleteButton, &QAbstractButton::clicked, this, &BasicView::delete_); + connect(refreshButton, &QAbstractButton::clicked, this, &BasicView::refresh); + connect(dockerEnvButton, &QAbstractButton::clicked, this, &BasicView::dockerEnv); + connect(sshButton, &QAbstractButton::clicked, this, &BasicView::ssh); + connect(dashboardButton, &QAbstractButton::clicked, this, &BasicView::dashboard); + connect(advancedButton, &QAbstractButton::clicked, this, &BasicView::advanced); +} + +static QString getPauseLabel(bool isPaused) +{ + if (isPaused) { + return "Unpause"; + } + return "Pause"; +} + +static QString getStartLabel(bool isRunning) +{ + if (isRunning) { + return "Restart"; + } + return "Start"; +} + +void BasicView::update(Cluster cluster) +{ + startButton->setEnabled(true); + advancedButton->setEnabled(true); + refreshButton->setEnabled(true); + bool exists = !cluster.isEmpty(); + bool isRunning = cluster.status() == "Running"; + bool isPaused = cluster.status() == "Paused"; + stopButton->setEnabled(isRunning || isPaused); + pauseButton->setEnabled(isRunning || isPaused); + deleteButton->setEnabled(exists); + dashboardButton->setEnabled(isRunning); +#if __linux__ || __APPLE__ + dockerEnvButton->setEnabled(isRunning); + sshButton->setEnabled(exists); +#else + dockerEnvButton->setEnabled(false); + sshButton->setEnabled(false); +#endif + pauseButton->setText(getPauseLabel(isPaused)); + startButton->setText(getStartLabel(isRunning)); + QString startToolTip = ""; + if (isRunning) { + startToolTip = "Restart an already running minikube instance to pickup config changes."; + } + startButton->setToolTip(startToolTip); +} + +void BasicView::disableButtons() +{ + startButton->setEnabled(false); + stopButton->setEnabled(false); + deleteButton->setEnabled(false); + pauseButton->setEnabled(false); + dockerEnvButton->setEnabled(false); + sshButton->setEnabled(false); + dashboardButton->setEnabled(false); + advancedButton->setEnabled(false); + refreshButton->setEnabled(false); +} diff --git a/basicview.h b/basicview.h new file mode 100644 index 0000000..b865d73 --- /dev/null +++ b/basicview.h @@ -0,0 +1,58 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef BASICVIEW_H +#define BASICVIEW_H + +#include "cluster.h" + +#include +#include + +class BasicView : public QObject +{ + Q_OBJECT + +public: + explicit BasicView(); + QWidget *basicView; + void update(Cluster cluster); + void disableButtons(); + +signals: + void start(); + void stop(); + void pause(); + void delete_(); + void refresh(); + void dockerEnv(); + void ssh(); + void dashboard(); + void advanced(); + +private: + QPushButton *startButton; + QPushButton *stopButton; + QPushButton *pauseButton; + QPushButton *deleteButton; + QPushButton *refreshButton; + QPushButton *dockerEnvButton; + QPushButton *sshButton; + QPushButton *dashboardButton; + QPushButton *advancedButton; +}; + +#endif // BASICVIEW_H diff --git a/cluster.cpp b/cluster.cpp new file mode 100644 index 0000000..b0bbbb5 --- /dev/null +++ b/cluster.cpp @@ -0,0 +1,114 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "cluster.h" + +#include + +void ClusterModel::setClusters(const ClusterList &clusters) +{ + beginResetModel(); + clusterList = clusters; + endResetModel(); +} + +int ClusterModel::rowCount(const QModelIndex &) const +{ + return clusterList.count(); +} + +int ClusterModel::columnCount(const QModelIndex &) const +{ + return 7; +} + +static QStringList binaryAbbrs = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" }; + +QVariant ClusterModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() >= clusterList.size()) + return QVariant(); + if (index.column() >= 7) + return QVariant(); + + if (role == Qt::TextAlignmentRole) { + switch (index.column()) { + case 0: + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + case 1: + return QVariant(Qt::AlignRight | Qt::AlignVCenter); + case 2: + // fall-through + case 3: + // fall-through + case 4: + // fall-through + case 5: + // fall-through + case 6: + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + } + if (role == Qt::DisplayRole) { + Cluster cluster = clusterList.at(index.row()); + switch (index.column()) { + case 0: + return cluster.name(); + case 1: + return cluster.status(); + case 2: + return cluster.driver(); + case 3: + return cluster.containerRuntime(); + case 4: + return cluster.k8sVersion(); + case 5: + return QString::number(cluster.cpus()); + case 6: + return QString::number(cluster.memory()); + } + } + return QVariant(); +} + +QVariant ClusterModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) { + switch (section) { + case 0: + return tr("Name"); + case 1: + return tr("Status"); + case 2: + return tr("Driver"); + case 3: + return tr("Container Runtime"); + case 4: + return tr("Kubernetes Version"); + case 5: + return tr("CPUs"); + case 6: + return tr("Memory (MB)"); + } + } + return QVariant(); // QStringLiteral("Row %1").arg(section); +} diff --git a/cluster.h b/cluster.h new file mode 100644 index 0000000..23c06e2 --- /dev/null +++ b/cluster.h @@ -0,0 +1,89 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef CLUSTER_H +#define CLUSTER_H + +#include +#include +#include +#include + +class Cluster +{ +public: + Cluster() : Cluster("") { } + Cluster(const QString &name) + : m_name(name), + m_status(""), + m_driver(""), + m_container_runtime(""), + m_k8s_version(""), + m_cpus(0), + m_memory(0) + { + } + + QString name() const { return m_name; } + QString status() const { return m_status; } + void setStatus(QString status) { m_status = status; } + QString driver() const { return m_driver; } + void setDriver(QString driver) { m_driver = driver; } + QString containerRuntime() const { return m_container_runtime; } + void setContainerRuntime(QString containerRuntime) { m_container_runtime = containerRuntime; } + QString k8sVersion() const { return m_k8s_version; } + void setK8sVersion(QString k8sVersion) { m_k8s_version = k8sVersion; } + int cpus() const { return m_cpus; } + void setCpus(int cpus) { m_cpus = cpus; } + int memory() const { return m_memory; } + void setMemory(int memory) { m_memory = memory; } + bool isEmpty() { return m_name.isEmpty(); } + +private: + QString m_name; + QString m_status; + QString m_driver; + QString m_container_runtime; + QString m_k8s_version; + int m_cpus; + int m_memory; +}; + +typedef QList ClusterList; +typedef QHash ClusterHash; + +class ClusterModel : public QAbstractListModel +{ + Q_OBJECT + +public: + ClusterModel(const ClusterList &clusters, QObject *parent = nullptr) + : QAbstractListModel(parent), clusterList(clusters) + { + } + + void setClusters(const ClusterList &clusters); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; + +private: + ClusterList clusterList; +}; + +#endif // CLUSTER_H diff --git a/commandrunner.cpp b/commandrunner.cpp new file mode 100644 index 0000000..f2c41c7 --- /dev/null +++ b/commandrunner.cpp @@ -0,0 +1,257 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "commandrunner.h" + +#include +#include +#include +#include +#include +#include + +CommandRunner::CommandRunner(QDialog *parent, Logger *logger) +{ + m_env = QProcessEnvironment::systemEnvironment(); + m_parent = parent; + m_logger = logger; + minikubePath(); +#if __APPLE__ + setMinikubePath(); +#endif +} + +void CommandRunner::executeCommand(QString program, QStringList args) +{ + QProcess *process = new QProcess(this); + process->setProcessEnvironment(m_env); + process->start(program, args); + process->waitForFinished(-1); + if (process->exitCode() == 0) { + return; + } + QString out = process->readAllStandardOutput(); + QString err = process->readAllStandardError(); + QString log = QString("The following command failed:\n%1 %2\n\nStdout:\n%3\n\nStderr:\n%4\n\n") + .arg(program, args.join(" "), out, err); + m_logger->log(log); + delete process; +} + +void CommandRunner::executeMinikubeCommand(QStringList args) +{ + m_isRunning = true; + m_output = ""; + QStringList userArgs = { "--user", "minikube-gui" }; + args << userArgs; + m_process = new QProcess(m_parent); + connect(m_process, QOverload::of(&QProcess::finished), this, + &CommandRunner::executionCompleted); + connect(m_process, &QProcess::readyReadStandardError, this, &CommandRunner::errorReady); + connect(m_process, &QProcess::readyReadStandardOutput, this, &CommandRunner::outputReady); + m_process->setProcessEnvironment(m_env); + m_process->start(m_minikubePath, args); + emit CommandRunner::startingExecution(); +} + +void CommandRunner::startMinikube(QStringList args) +{ + m_command = "start"; + QStringList baseArgs = { "start", "-o", "json" }; + baseArgs << args; + m_args = baseArgs; + executeMinikubeCommand(baseArgs); + emit startCommandStarting(); +} + +void CommandRunner::stopMinikube(QStringList args) +{ + QStringList baseArgs = { "stop" }; + baseArgs << args; + executeMinikubeCommand(baseArgs); +} + +void CommandRunner::pauseMinikube(QStringList args) +{ + QStringList baseArgs = { "pause" }; + baseArgs << args; + executeMinikubeCommand(baseArgs); +} + +void CommandRunner::unpauseMinikube(QStringList args) +{ + QStringList baseArgs = { "unpause" }; + baseArgs << args; + executeMinikubeCommand(baseArgs); +} + +void CommandRunner::deleteMinikube(QStringList args) +{ + m_command = "delete"; + QStringList baseArgs = { "delete" }; + baseArgs << args; + executeMinikubeCommand(baseArgs); +} + +void CommandRunner::stopCommand() +{ + m_process->terminate(); +} + +static Cluster createClusterObject(QJsonObject obj) +{ + QString name; + if (obj.contains("Name")) { + name = obj["Name"].toString(); + } + Cluster cluster(name); + if (obj.contains("Status")) { + QString status = obj["Status"].toString(); + cluster.setStatus(status); + } + if (!obj.contains("Config")) { + return cluster; + } + QJsonObject config = obj["Config"].toObject(); + if (config.contains("CPUs")) { + int cpus = config["CPUs"].toInt(); + cluster.setCpus(cpus); + } + if (config.contains("Memory")) { + int memory = config["Memory"].toInt(); + cluster.setMemory(memory); + } + if (config.contains("Driver")) { + QString driver = config["Driver"].toString(); + cluster.setDriver(driver); + } + if (!config.contains("KubernetesConfig")) { + return cluster; + } + QJsonObject k8sConfig = config["KubernetesConfig"].toObject(); + if (k8sConfig.contains("ContainerRuntime")) { + QString containerRuntime = k8sConfig["ContainerRuntime"].toString(); + cluster.setContainerRuntime(containerRuntime); + } + if (k8sConfig.contains("KubernetesVersion")) { + QString k8sVersion = k8sConfig["KubernetesVersion"].toString(); + cluster.setK8sVersion(k8sVersion); + } + return cluster; +} + +static ClusterList jsonToClusterList(QString text) +{ + ClusterList clusters; + QStringList lines; +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + lines = text.split("\n", Qt::SkipEmptyParts); +#else + lines = text.split("\n", QString::SkipEmptyParts); +#endif + for (int i = 0; i < lines.size(); i++) { + QString line = lines.at(i); + QJsonParseError error; + QJsonDocument json = QJsonDocument::fromJson(line.toUtf8(), &error); + if (json.isNull()) { + qDebug() << error.errorString(); + continue; + } + if (!json.isObject()) { + continue; + } + QJsonObject par = json.object(); + QJsonArray valid = par["valid"].toArray(); + QJsonArray invalid = par["invalid"].toArray(); + for (int i = 0; i < valid.size(); i++) { + QJsonObject obj = valid[i].toObject(); + Cluster cluster = createClusterObject(obj); + clusters << cluster; + } + for (int i = 0; i < invalid.size(); i++) { + QJsonObject obj = invalid[i].toObject(); + Cluster cluster = createClusterObject(obj); + cluster.setStatus("Invalid"); + clusters << cluster; + } + } + return clusters; +} + +void CommandRunner::requestClusters() +{ + m_command = "cluster"; + QStringList args = { "profile", "list", "-o", "json" }; + executeMinikubeCommand(args); +} + +void CommandRunner::executionCompleted() +{ + m_isRunning = false; + QString cmd = m_command; + m_command = ""; + QString output = m_output; + int exitCode = m_process->exitCode(); + delete m_process; + if (cmd != "cluster") { + emit executionEnded(); + } + if (cmd == "start" && exitCode != 0) { + emit error(m_args, output); + } + if (cmd == "cluster") { + ClusterList clusterList = jsonToClusterList(output); + emit updatedClusters(clusterList); + } +} + +void CommandRunner::errorReady() +{ + QString text = m_process->readAllStandardError(); + m_output.append(text); + emit output(text); +} + +void CommandRunner::outputReady() +{ + QString text = m_process->readAllStandardOutput(); + m_output.append(text); + emit output(text); +} + +#if __APPLE__ +void CommandRunner::setMinikubePath() +{ + m_env = QProcessEnvironment::systemEnvironment(); + QString path = m_env.value("PATH") + ":/usr/local/bin"; + m_env.insert("PATH", path); +} +#endif + +void CommandRunner::minikubePath() +{ + m_minikubePath = QStandardPaths::findExecutable("minikube"); + if (!m_minikubePath.isEmpty()) { + return; + } + QStringList path = { "/usr/local/bin" }; + m_minikubePath = QStandardPaths::findExecutable("minikube", path); +} + +bool CommandRunner::isRunning() +{ + return m_isRunning; +} diff --git a/commandrunner.h b/commandrunner.h new file mode 100644 index 0000000..9d7bd77 --- /dev/null +++ b/commandrunner.h @@ -0,0 +1,79 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef COMMANDRUNNER_H +#define COMMANDRUNNER_H + +#include "cluster.h" +#include "logger.h" + +#include +#include +#include +#include +#include +#include +#include + +class CommandRunner : public QObject +{ + Q_OBJECT + +public: + CommandRunner(QDialog *parent, Logger *logger); + + void executeCommand(QString program, QStringList args); + void startMinikube(QStringList args); + void stopMinikube(QStringList args); + void pauseMinikube(QStringList args); + void unpauseMinikube(QStringList args); + void deleteMinikube(QStringList args); + void stopCommand(); + void requestClusters(); + bool isRunning(); + +signals: + void startingExecution(); + void executionEnded(); + void output(QString text); + void error(QStringList args, QString text); + void updatedClusters(ClusterList clusterList); + void startCommandStarting(); + +private slots: + void executionCompleted(); + void outputReady(); + void errorReady(); + +private: + void executeMinikubeCommand(QStringList args); + void minikubePath(); +#if __APPLE__ + void setMinikubePath(); +#endif + + QProcess *m_process; + QProcessEnvironment m_env; + QString m_output; + QString m_minikubePath; + QString m_command; + QDialog *m_parent; + Logger *m_logger; + QStringList m_args; + bool m_isRunning; +}; + +#endif // COMMANDRUNNER_H diff --git a/errormessage.cpp b/errormessage.cpp new file mode 100644 index 0000000..a9684ec --- /dev/null +++ b/errormessage.cpp @@ -0,0 +1,80 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "errormessage.h" + +#include +#include +#include +#include +#include +#include + +ErrorMessage::ErrorMessage(QDialog *parent, QIcon icon) +{ + m_parent = parent; + m_icon = icon; +} + +void ErrorMessage::error(QString errorCode, QString advice, QString message, QString url, + QString issues) +{ + + m_dialog = new QDialog(m_parent); + m_dialog->setWindowTitle(tr("minikube start failed")); + m_dialog->setWindowIcon(m_icon); + m_dialog->setFixedWidth(600); + m_dialog->setModal(true); + QFormLayout form(m_dialog); + createLabel("Error Code", errorCode, &form, false); + createLabel("Advice", advice, &form, false); + QTextEdit *errorMessage = new QTextEdit(); + errorMessage->setText(message); + errorMessage->setWordWrapMode(QTextOption::WrapAnywhere); + int pointSize = errorMessage->font().pointSize(); + errorMessage->setFont(QFont("Courier", pointSize)); + errorMessage->setAutoFillBackground(true); + errorMessage->setReadOnly(true); + form.addRow(errorMessage); + createLabel("Link to documentation", url, &form, true); + createLabel("Link to related issue", issues, &form, true); + QLabel *fileLabel = new QLabel(); + fileLabel->setOpenExternalLinks(true); + fileLabel->setWordWrap(true); + QString logFile = QDir::homePath() + "/.minikube/logs/lastStart.txt"; + fileLabel->setText("View log file"); + form.addRow(fileLabel); + QDialogButtonBox buttonBox(Qt::Horizontal, m_dialog); + buttonBox.addButton(QString(tr("OK")), QDialogButtonBox::AcceptRole); + connect(&buttonBox, &QDialogButtonBox::accepted, m_dialog, &QDialog::accept); + form.addRow(&buttonBox); + m_dialog->exec(); +} + +QLabel *ErrorMessage::createLabel(QString title, QString text, QFormLayout *form, bool isLink) +{ + QLabel *label = new QLabel(); + if (!text.isEmpty()) { + form->addRow(label); + } + if (isLink) { + label->setOpenExternalLinks(true); + text = "" + text + ""; + } + label->setWordWrap(true); + label->setText(title + ": " + text); + return label; +} diff --git a/errormessage.h b/errormessage.h new file mode 100644 index 0000000..dea594b --- /dev/null +++ b/errormessage.h @@ -0,0 +1,43 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef ERRORMESSAGE_H +#define ERRORMESSAGE_H + +#include +#include +#include +#include +#include + +class ErrorMessage : public QObject +{ + Q_OBJECT + +public: + explicit ErrorMessage(QDialog *parent, QIcon icon); + + void error(QString errorCode, QString advice, QString errorMessage, QString url, + QString issues); + QLabel *createLabel(QString title, QString text, QFormLayout *form, bool isLink); + +private: + QDialog *m_dialog; + QIcon m_icon; + QDialog *m_parent; +}; + +#endif // ERRORMESSAGE_H diff --git a/hyperkit.cpp b/hyperkit.cpp new file mode 100644 index 0000000..0b83abd --- /dev/null +++ b/hyperkit.cpp @@ -0,0 +1,73 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "hyperkit.h" + +#include +#include + +HyperKit::HyperKit(QIcon icon) +{ + m_icon = icon; +} + +#if __APPLE__ +bool HyperKit::hyperkitPermissionFix(QStringList args, QString text) +{ + if (!text.contains("docker-machine-driver-hyperkit needs to run with elevated permissions")) { + return false; + } + if (!showHyperKitMessage()) { + return false; + } + + hyperkitPermission(); + emit rerun(args); + return true; +} + +void HyperKit::hyperkitPermission() +{ + QString command = "sudo chown root:wheel ~/.minikube/bin/docker-machine-driver-hyperkit && " + "sudo chmod u+s ~/.minikube/bin/docker-machine-driver-hyperkit && exit"; + QStringList arguments = { "-e", "tell app \"Terminal\"", + "-e", "set w to do script \"" + command + "\"", + "-e", "activate", + "-e", "repeat", + "-e", "delay 0.1", + "-e", "if not busy of w then exit repeat", + "-e", "end repeat", + "-e", "end tell" }; + QProcess *process = new QProcess(); + process->start("/usr/bin/osascript", arguments); + process->waitForFinished(-1); +} + +bool HyperKit::showHyperKitMessage() +{ + QMessageBox msgBox; + msgBox.setWindowTitle("HyperKit Permissions Required"); + msgBox.setWindowIcon(m_icon); + msgBox.setModal(true); + msgBox.setText("The HyperKit driver requires a one-time sudo permission.\n\nIf you'd like " + "to proceed, press OK and then enter your password into the terminal prompt, " + "the start will resume after."); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Ok); + int code = msgBox.exec(); + return code == QMessageBox::Ok; +} +#endif diff --git a/hyperkit.h b/hyperkit.h new file mode 100644 index 0000000..800c30d --- /dev/null +++ b/hyperkit.h @@ -0,0 +1,41 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef HYPERKIT_H +#define HYPERKIT_H + +#include +#include +#include + +class HyperKit : public QObject +{ + Q_OBJECT + +public: + explicit HyperKit(QIcon icon); + bool hyperkitPermissionFix(QStringList args, QString text); + +signals: + void rerun(QStringList args); + +private: + void hyperkitPermission(); + bool showHyperKitMessage(); + QIcon m_icon; +}; + +#endif // HYPERKIT_H diff --git a/images/minikube.icns b/images/minikube.icns new file mode 100644 index 0000000000000000000000000000000000000000..392d780c7870c94a41ee7a234cc3692c4be99b98 GIT binary patch literal 119220 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ⅆ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

=eOrg!M$%I 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 +#include +#include +#include + +Logger::Logger() +{ + QDir dir = QDir(QDir::homePath() + "/.minikube-gui"); + if (!dir.exists()) { + dir.mkpath("."); + } + m_logPath = dir.filePath("logs.txt"); +} + +void Logger::log(QString message) +{ + QFile file(m_logPath); + if (!file.open(QIODevice::Append)) { + return; + } + QTextStream stream(&file); + stream << message << "\n"; + file.close(); +} diff --git a/logger.h b/logger.h new file mode 100644 index 0000000..c0ae79a --- /dev/null +++ b/logger.h @@ -0,0 +1,34 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef LOGGER_H +#define LOGGER_H + +#include + +class Logger : public QObject +{ + Q_OBJECT + +public: + explicit Logger(); + void log(QString message); + +private: + QString m_logPath; +}; + +#endif // LOGGER_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..38acf6e --- /dev/null +++ b/main.cpp @@ -0,0 +1,58 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include + +#ifndef QT_NO_SYSTEMTRAYICON + +#include +#include "window.h" + +int main(int argc, char *argv[]) +{ + Q_INIT_RESOURCE(minikube); + + QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + + QApplication app(argc, argv); + + if (!QSystemTrayIcon::isSystemTrayAvailable()) { + QMessageBox::critical(0, QObject::tr("minikube"), QObject::tr("No system tray detected.")); + return 1; + } + QApplication::setQuitOnLastWindowClosed(false); + + Window window; + window.show(); + return app.exec(); +} + +#else + +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QLabel *label = new QLabel("System tray is not supported on this machine."); + label->setWordWrap(true); + label->show(); + + app.exec(); +} + +#endif diff --git a/minikube.pro b/minikube.pro new file mode 100644 index 0000000..8143572 --- /dev/null +++ b/minikube.pro @@ -0,0 +1,45 @@ +HEADERS = window.h \ + advancedview.h \ + basicview.h \ + cluster.h \ + commandrunner.h \ + errormessage.h \ + hyperkit.h \ + logger.h \ + operator.h \ + progresswindow.h \ + tray.h \ + updater.h +SOURCES = main.cpp \ + advancedview.cpp \ + basicview.cpp \ + cluster.cpp \ + commandrunner.cpp \ + errormessage.cpp \ + hyperkit.cpp \ + logger.cpp \ + operator.cpp \ + progresswindow.cpp \ + tray.cpp \ + updater.cpp \ + window.cpp +RESOURCES = minikube.qrc +ICON = images/minikube.icns + +QT += widgets network +requires(qtConfig(combobox)) + +DISTFILES += \ + LICENSE + +# Enabling qtermwidget requires GPL-v2 license +#CONFIG += gpl_licensed + +gpl_licensed { + win32: DEFINES += QT_NO_TERMWIDGET + + unix: CONFIG += link_pkgconfig + unix: PKGCONFIG += qtermwidget5 +} else { + DEFINES += QT_NO_TERMWIDGET +} diff --git a/minikube.qrc b/minikube.qrc new file mode 100644 index 0000000..6e9fe37 --- /dev/null +++ b/minikube.qrc @@ -0,0 +1,5 @@ + + + images/minikube.png + + diff --git a/operator.cpp b/operator.cpp new file mode 100644 index 0000000..8520a21 --- /dev/null +++ b/operator.cpp @@ -0,0 +1,434 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "operator.h" + +#include +#include +#include +#include + +Operator::Operator(AdvancedView *advancedView, BasicView *basicView, CommandRunner *commandRunner, + ErrorMessage *errorMessage, ProgressWindow *progressWindow, Tray *tray, + HyperKit *hyperKit, Updater *updater, QStackedWidget *stackedWidget, + QDialog *parent) +{ + m_advancedView = advancedView; + m_basicView = basicView; + m_commandRunner = commandRunner; + m_errorMessage = errorMessage; + m_progressWindow = progressWindow; + m_tray = tray; + m_hyperKit = hyperKit; + m_updater = updater; + m_stackedWidget = stackedWidget; + m_parent = parent; + m_isBasicView = true; + dashboardProcess = NULL; + + connect(m_basicView, &BasicView::start, this, &Operator::startMinikube); + connect(m_basicView, &BasicView::stop, this, &Operator::stopMinikube); + connect(m_basicView, &BasicView::pause, this, &Operator::pauseOrUnpauseMinikube); + connect(m_basicView, &BasicView::delete_, this, &Operator::deleteMinikube); + connect(m_basicView, &BasicView::refresh, this, &Operator::updateClusters); + connect(m_basicView, &BasicView::dockerEnv, this, &Operator::dockerEnv); + connect(m_basicView, &BasicView::ssh, this, &Operator::sshConsole); + connect(m_basicView, &BasicView::dashboard, this, &Operator::dashboardBrowser); + connect(m_basicView, &BasicView::advanced, this, &Operator::toAdvancedView); + + connect(m_advancedView, &AdvancedView::start, this, &Operator::startMinikube); + connect(m_advancedView, &AdvancedView::stop, this, &Operator::stopMinikube); + connect(m_advancedView, &AdvancedView::pause, this, &Operator::pauseOrUnpauseMinikube); + connect(m_advancedView, &AdvancedView::delete_, this, &Operator::deleteMinikube); + connect(m_advancedView, &AdvancedView::refresh, this, &Operator::updateClusters); + connect(m_advancedView, &AdvancedView::dockerEnv, this, &Operator::dockerEnv); + connect(m_advancedView, &AdvancedView::ssh, this, &Operator::sshConsole); + connect(m_advancedView, &AdvancedView::dashboard, this, &Operator::dashboardBrowser); + connect(m_advancedView, &AdvancedView::basic, this, &Operator::toBasicView); + connect(m_advancedView, &AdvancedView::createCluster, this, &Operator::createCluster); + connect(m_advancedView->clusterListView, SIGNAL(clicked(QModelIndex)), this, + SLOT(updateButtons())); + + connect(m_commandRunner, &CommandRunner::startingExecution, this, &Operator::commandStarting); + connect(m_commandRunner, &CommandRunner::executionEnded, this, &Operator::commandEnding); + connect(m_commandRunner, &CommandRunner::output, this, &Operator::commandOutput); + connect(m_commandRunner, &CommandRunner::error, this, &Operator::commandError); + connect(m_commandRunner, &CommandRunner::updatedClusters, this, &Operator::clustersReceived); + connect(m_commandRunner, &CommandRunner::startCommandStarting, this, + &Operator::startCommandStarting); + + connect(m_progressWindow, &ProgressWindow::cancelled, this, &Operator::cancelCommand); + + connect(m_tray, &Tray::restoreWindow, this, &Operator::restoreWindow); + connect(m_tray, &Tray::hideWindow, this, &Operator::hideWindow); + connect(m_tray, &Tray::start, this, &Operator::startMinikube); + connect(m_tray, &Tray::stop, this, &Operator::stopMinikube); + connect(m_tray, &Tray::pauseOrUnpause, this, &Operator::pauseOrUnpauseMinikube); + + connect(m_hyperKit, &HyperKit::rerun, this, &Operator::createCluster); + + updateClusters(); +} + +QStringList Operator::getCurrentClusterFlags() +{ + return { "-p", selectedClusterName() }; +} + +void Operator::startMinikube() +{ + m_commandRunner->startMinikube(getCurrentClusterFlags()); +} + +void Operator::stopMinikube() +{ + m_commandRunner->stopMinikube(getCurrentClusterFlags()); +} + +void Operator::pauseOrUnpauseMinikube() +{ + Cluster cluster = selectedCluster(); + if (cluster.status() == "Paused") { + unpauseMinikube(); + return; + } + pauseMinikube(); +} + +void Operator::pauseMinikube() +{ + m_commandRunner->pauseMinikube(getCurrentClusterFlags()); +} + +void Operator::unpauseMinikube() +{ + m_commandRunner->unpauseMinikube(getCurrentClusterFlags()); +} + +void Operator::deleteMinikube() +{ + m_commandRunner->deleteMinikube(getCurrentClusterFlags()); +} + +void Operator::createCluster(QStringList args) +{ + m_commandRunner->startMinikube(args); +} + +void Operator::startCommandStarting() +{ + commandStarting(); + m_progressWindow->setText("Starting..."); + m_progressWindow->show(); +} + +void Operator::commandStarting() +{ + m_advancedView->showLoading(); + m_tray->disableActions(); + m_parent->setCursor(Qt::WaitCursor); + disableButtons(); +} + +void Operator::disableButtons() +{ + if (m_isBasicView) { + m_basicView->disableButtons(); + } else { + m_advancedView->disableButtons(); + } +} + +void Operator::commandEnding() +{ + m_progressWindow->done(); + updateClusters(); +} + +void Operator::toAdvancedView() +{ + m_isBasicView = false; + m_stackedWidget->setCurrentIndex(1); + m_parent->resize(670, 400); + updateButtons(); +} + +void Operator::toBasicView() +{ + m_isBasicView = true; + m_stackedWidget->setCurrentIndex(0); + m_parent->resize(200, 300); + updateButtons(); +} + +void Operator::updateClusters() +{ + m_commandRunner->requestClusters(); +} + +void Operator::clustersReceived(ClusterList clusterList) +{ + m_clusterList = clusterList; + m_advancedView->updateClustersTable(m_clusterList); + updateButtons(); + m_advancedView->hideLoading(); + m_parent->unsetCursor(); + m_updater->checkForUpdates(); +} + +void Operator::updateButtons() +{ + Cluster cluster = selectedCluster(); + if (m_isBasicView) { + m_basicView->update(cluster); + } else { + m_advancedView->update(cluster); + } + m_tray->updateTrayActions(cluster); + m_tray->updateStatus(cluster); +} + +void Operator::restoreWindow() +{ + bool wasVisible = m_parent->isVisible(); + m_parent->showNormal(); + m_parent->activateWindow(); + if (wasVisible) { + return; + } + if (m_commandRunner->isRunning()) + return; + updateClusters(); +} + +void Operator::hideWindow() +{ + m_parent->hide(); +} + +void Operator::commandOutput(QString text) +{ + QStringList lines; +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + lines = text.split("\n", Qt::SkipEmptyParts); +#else + lines = text.split("\n", QString::SkipEmptyParts); +#endif + for (int i = 0; i < lines.size(); i++) { + QJsonDocument json = QJsonDocument::fromJson(lines[i].toUtf8()); + QJsonObject object = json.object(); + QString type = object["type"].toString(); + if (type != "io.k8s.sigs.minikube.step") { + return; + } + QJsonObject data = object["data"].toObject(); + QString stringStep = data["currentstep"].toString(); + int currStep = stringStep.toInt(); + QString totalString = data["totalsteps"].toString(); + int totalSteps = totalString.toInt(); + QString message = data["message"].toString(); + m_progressWindow->setBarMaximum(totalSteps); + m_progressWindow->setBarValue(currStep); + m_progressWindow->setText(message); + } +} + +void Operator::commandError(QStringList args, QString text) +{ +#if __APPLE__ + if (m_hyperKit->hyperkitPermissionFix(args, text)) { + return; + } +#endif + QStringList lines; +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + lines = text.split("\n", Qt::SkipEmptyParts); +#else + lines = text.split("\n", QString::SkipEmptyParts); +#endif + for (int i = 0; i < lines.size(); i++) { + QString line = lines.at(i); + QJsonParseError error; + QJsonDocument json = QJsonDocument::fromJson(line.toUtf8(), &error); + if (json.isNull() || !json.isObject()) { + continue; + } + QJsonObject par = json.object(); + QJsonObject data = par["data"].toObject(); + if (!data.contains("exitcode")) { + continue; + } + QString advice = data["advice"].toString(); + QString message = data["message"].toString(); + QString name = data["name"].toString(); + QString url = data["url"].toString(); + QString issues = data["issues"].toString(); + + m_errorMessage->error(name, advice, message, url, issues); + break; + } +} + +void Operator::cancelCommand() +{ + m_commandRunner->stopCommand(); +} + +QString Operator::selectedClusterName() +{ + if (m_isBasicView) { + return "minikube"; + } + return m_advancedView->selectedClusterName(); +} + +Cluster Operator::selectedCluster() +{ + QString clusterName = selectedClusterName(); + if (clusterName.isEmpty()) { + return Cluster(); + } + ClusterList clusters = m_clusterList; + ClusterHash clusterHash; + for (int i = 0; i < clusters.size(); i++) { + Cluster cluster = clusters.at(i); + clusterHash[cluster.name()] = cluster; + } + return clusterHash[clusterName]; +} + +static QString minikubePath() +{ + QString minikubePath = QStandardPaths::findExecutable("minikube"); + if (!minikubePath.isEmpty()) { + return minikubePath; + } + QStringList path = { "/usr/local/bin" }; + return QStandardPaths::findExecutable("minikube", path); +} + +void Operator::sshConsole() +{ + QString program = minikubePath(); + QString commandArgs = QString("ssh -p %1").arg(selectedClusterName()); + QString command = QString("%1 %2").arg(program, commandArgs); +#ifndef QT_NO_TERMWIDGET + QMainWindow *mainWindow = new QMainWindow(); + int startnow = 0; // set shell program first + + QTermWidget *console = new QTermWidget(startnow); + + QFont font = QApplication::font(); + font.setFamily("Monospace"); + font.setPointSize(10); + + console->setTerminalFont(font); + console->setColorScheme("Tango"); + console->setShellProgram(program); + console->setArgs({ commandArgs }); + console->startShellProgram(); + + QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close())); + + mainWindow->setWindowTitle(nameLabel->text()); + mainWindow->resize(800, 400); + mainWindow->setCentralWidget(console); + mainWindow->show(); +#elif __APPLE__ + QStringList arguments = { "-e", "tell app \"Terminal\"", + "-e", "do script \"" + command + "\"", + "-e", "activate", + "-e", "end tell" }; + m_commandRunner->executeCommand("/usr/bin/osascript", arguments); +#else + QString terminal = qEnvironmentVariable("TERMINAL"); + if (terminal.isEmpty()) { + terminal = "x-terminal-emulator"; + if (QStandardPaths::findExecutable(terminal).isEmpty()) { + terminal = "xterm"; + } + } + + m_commandRunner->executeCommand(QStandardPaths::findExecutable(terminal), { "-e", command }); +#endif +} + +void Operator::dockerEnv() +{ + QString program = minikubePath(); + QString commandArgs = QString("$(%1 -p %2 docker-env)").arg(program, selectedClusterName()); + QString command = QString("eval %1").arg(commandArgs); +#ifndef QT_NO_TERMWIDGET + QMainWindow *mainWindow = new QMainWindow(); + int startnow = 0; // set shell program first + + QTermWidget *console = new QTermWidget(startnow); + + QFont font = QApplication::font(); + font.setFamily("Monospace"); + font.setPointSize(10); + + console->setTerminalFont(font); + console->setColorScheme("Tango"); + console->setShellProgram("eval"); + console->setArgs({ commandArgs }); + console->startShellProgram(); + + QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close())); + + mainWindow->setWindowTitle(nameLabel->text()); + mainWindow->resize(800, 400); + mainWindow->setCentralWidget(console); + mainWindow->show(); +#elif __APPLE__ + QStringList arguments = { "-e", "tell app \"Terminal\"", + "-e", "do script \"" + command + "\"", + "-e", "activate", + "-e", "end tell" }; + m_commandRunner->executeCommand("/usr/bin/osascript", arguments); +#else + QString terminal = qEnvironmentVariable("TERMINAL"); + if (terminal.isEmpty()) { + terminal = "x-terminal-emulator"; + if (QStandardPaths::findExecutable(terminal).isEmpty()) { + terminal = "xterm"; + } + } + + m_commandRunner->executeCommand(QStandardPaths::findExecutable(terminal), { "-e", command }); +#endif +} + +void Operator::dashboardBrowser() +{ + dashboardClose(); + + QString program = minikubePath(); + QProcess *process = new QProcess(this); + QStringList arguments = { "dashboard", "-p", selectedClusterName() }; + process->start(program, arguments); + + dashboardProcess = process; + dashboardProcess->waitForStarted(); +} + +void Operator::dashboardClose() +{ + if (dashboardProcess) { + dashboardProcess->terminate(); + dashboardProcess->waitForFinished(); + } +} diff --git a/operator.h b/operator.h new file mode 100644 index 0000000..1a48712 --- /dev/null +++ b/operator.h @@ -0,0 +1,90 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef OPERATOR_H +#define OPERATOR_H + +#include "advancedview.h" +#include "basicview.h" +#include "cluster.h" +#include "commandrunner.h" +#include "errormessage.h" +#include "progresswindow.h" +#include "tray.h" +#include "hyperkit.h" +#include "updater.h" + +#include + +class Operator : public QObject +{ + Q_OBJECT + +public: + Operator(AdvancedView *advancedView, BasicView *basicView, CommandRunner *commandRunner, + ErrorMessage *errorMessage, ProgressWindow *progressWindow, Tray *tray, + HyperKit *hyperKit, Updater *updater, QStackedWidget *stackedWidget, QDialog *parent); + +public slots: + void startMinikube(); + void stopMinikube(); + void pauseOrUnpauseMinikube(); + void deleteMinikube(); + +private slots: + void commandStarting(); + void commandEnding(); + void commandOutput(QString text); + void commandError(QStringList args, QString text); + void cancelCommand(); + void toBasicView(); + void toAdvancedView(); + void createCluster(QStringList args); + void updateButtons(); + void clustersReceived(ClusterList clusterList); + void startCommandStarting(); + +private: + QStringList getCurrentClusterFlags(); + void updateClusters(); + QString selectedClusterName(); + Cluster selectedCluster(); + void sshConsole(); + void dockerEnv(); + void dashboardBrowser(); + void dashboardClose(); + void pauseMinikube(); + void unpauseMinikube(); + void restoreWindow(); + void hideWindow(); + void disableButtons(); + + AdvancedView *m_advancedView; + BasicView *m_basicView; + CommandRunner *m_commandRunner; + ErrorMessage *m_errorMessage; + ProgressWindow *m_progressWindow; + ClusterList m_clusterList; + Tray *m_tray; + HyperKit *m_hyperKit; + Updater *m_updater; + bool m_isBasicView; + QProcess *dashboardProcess; + QStackedWidget *m_stackedWidget; + QDialog *m_parent; +}; + +#endif // OPERATOR_H diff --git a/progresswindow.cpp b/progresswindow.cpp new file mode 100644 index 0000000..f72c0c1 --- /dev/null +++ b/progresswindow.cpp @@ -0,0 +1,81 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "progresswindow.h" + +#include +#include + +ProgressWindow::ProgressWindow(QWidget *parent, QIcon icon) +{ + m_icon = icon; + + m_dialog = new QDialog(parent); + m_dialog->setWindowIcon(m_icon); + m_dialog->resize(300, 150); + m_dialog->setWindowFlags(Qt::FramelessWindowHint); + m_dialog->setModal(true); + + QVBoxLayout form(m_dialog); + + m_text = new QLabel(); + m_text->setWordWrap(true); + form.addWidget(m_text); + + m_progressBar = new QProgressBar(); + form.addWidget(m_progressBar); + + m_cancelButton = new QPushButton(); + m_cancelButton->setText(tr("Cancel")); + connect(m_cancelButton, &QAbstractButton::clicked, this, &ProgressWindow::cancel); + form.addWidget(m_cancelButton); + + // if the dialog isn't opened now it breaks formatting + m_dialog->open(); + m_dialog->hide(); +} + +void ProgressWindow::setBarMaximum(int max) +{ + m_progressBar->setMaximum(max); +} + +void ProgressWindow::setBarValue(int value) +{ + m_progressBar->setValue(value); +} + +void ProgressWindow::setText(QString text) +{ + m_text->setText(text); +} + +void ProgressWindow::show() +{ + m_dialog->open(); +} + +void ProgressWindow::cancel() +{ + done(); + emit cancelled(); +} + +void ProgressWindow::done() +{ + m_dialog->hide(); + m_progressBar->setValue(0); +} diff --git a/progresswindow.h b/progresswindow.h new file mode 100644 index 0000000..2ffec96 --- /dev/null +++ b/progresswindow.h @@ -0,0 +1,54 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef PROGRESSWINDOW_H +#define PROGRESSWINDOW_H + +#include +#include +#include +#include +#include +#include +#include + +class ProgressWindow : public QObject +{ + Q_OBJECT + +public: + explicit ProgressWindow(QWidget *parent, QIcon icon); + + void setBarMaximum(int max); + void setBarValue(int value); + void setText(QString text); + void show(); + void done(); + +signals: + void cancelled(); + +private: + void cancel(); + + QDialog *m_dialog; + QLabel *m_text; + QProgressBar *m_progressBar; + QPushButton *m_cancelButton; + QIcon m_icon; +}; + +#endif // PROGRESSWINDOW_H diff --git a/releases.json b/releases.json new file mode 100644 index 0000000..7b4698c --- /dev/null +++ b/releases.json @@ -0,0 +1,5 @@ +[ + { + "name":"0.0.0" + } +] diff --git a/tray.cpp b/tray.cpp new file mode 100644 index 0000000..3405f71 --- /dev/null +++ b/tray.cpp @@ -0,0 +1,132 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tray.h" + +#include +#include +#include + +Tray::Tray(QIcon icon) +{ + m_icon = icon; + + trayIconMenu = new QMenu(); + trayIcon = new QSystemTrayIcon(this); + + connect(trayIcon, &QSystemTrayIcon::activated, this, &Tray::iconActivated); + + minimizeAction = new QAction(tr("Mi&nimize"), this); + connect(minimizeAction, &QAction::triggered, this, &Tray::hideWindow); + + restoreAction = new QAction(tr("&Restore"), this); + connect(restoreAction, &QAction::triggered, this, &Tray::restoreWindow); + + quitAction = new QAction(tr("&Quit"), this); + connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); + + startAction = new QAction(tr("Start"), this); + connect(startAction, &QAction::triggered, this, &Tray::start); + + pauseAction = new QAction(tr("Pause"), this); + connect(pauseAction, &QAction::triggered, this, &Tray::pauseOrUnpause); + + stopAction = new QAction(tr("Stop"), this); + connect(stopAction, &QAction::triggered, this, &Tray::stop); + + statusAction = new QAction(tr("Status:"), this); + statusAction->setEnabled(false); + + trayIconMenu->addAction(statusAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(startAction); + trayIconMenu->addAction(pauseAction); + trayIconMenu->addAction(stopAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(minimizeAction); + trayIconMenu->addAction(restoreAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(quitAction); + + trayIcon->setContextMenu(trayIconMenu); + trayIcon->setIcon(m_icon); + trayIcon->show(); +} + +void Tray::iconActivated(QSystemTrayIcon::ActivationReason reason) +{ + switch (reason) { + case QSystemTrayIcon::Trigger: + case QSystemTrayIcon::DoubleClick: + emit restoreWindow(); + break; + default:; + } +} + +void Tray::updateStatus(Cluster cluster) +{ + QString status = cluster.status(); + if (status.isEmpty()) { + status = "Stopped"; + } + statusAction->setText("Status: " + status); +} + +bool Tray::isVisible() +{ + return trayIcon->isVisible(); +} + +void Tray::setVisible(bool visible) +{ + minimizeAction->setEnabled(visible); + restoreAction->setEnabled(!visible); +} + +static QString getPauseLabel(bool isPaused) +{ + if (isPaused) { + return "Unpause"; + } + return "Pause"; +} + +static QString getStartLabel(bool isRunning) +{ + if (isRunning) { + return "Restart"; + } + return "Start"; +} + +void Tray::updateTrayActions(Cluster cluster) +{ + startAction->setEnabled(true); + bool isRunning = cluster.status() == "Running"; + bool isPaused = cluster.status() == "Paused"; + pauseAction->setEnabled(isRunning || isPaused); + stopAction->setEnabled(isRunning || isPaused); + pauseAction->setText(getPauseLabel(isPaused)); + startAction->setText(getStartLabel(isRunning)); +} + +void Tray::disableActions() +{ + startAction->setEnabled(false); + stopAction->setEnabled(false); + pauseAction->setEnabled(false); +} diff --git a/tray.h b/tray.h new file mode 100644 index 0000000..9c7c794 --- /dev/null +++ b/tray.h @@ -0,0 +1,61 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef TRAY_H +#define TRAY_H + +#include "cluster.h" + +#include +#include + +class Tray : public QObject +{ + Q_OBJECT + +public: + explicit Tray(QIcon icon); + bool isVisible(); + void setVisible(bool visible); + void updateStatus(Cluster cluster); + void updateTrayActions(Cluster cluster); + void disableActions(); + +signals: + void restoreWindow(); + void showWindow(); + void hideWindow(); + void start(); + void stop(); + void pauseOrUnpause(); + +private: + void createTrayIcon(); + void createActions(); + void iconActivated(QSystemTrayIcon::ActivationReason reason); + QAction *minimizeAction; + QAction *restoreAction; + QAction *quitAction; + QAction *startAction; + QAction *pauseAction; + QAction *stopAction; + QAction *statusAction; + QSystemTrayIcon *trayIcon; + QMenu *trayIconMenu; + QIcon m_icon; +}; + +#endif // TRAY_H diff --git a/updater.cpp b/updater.cpp new file mode 100644 index 0000000..9f98581 --- /dev/null +++ b/updater.cpp @@ -0,0 +1,133 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "updater.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Updater::Updater(QVersionNumber version, QIcon icon) +{ + m_version = version; + m_icon = icon; +} + +static bool checkedForUpdateRecently() +{ + QString filePath = QStandardPaths::locate(QStandardPaths::HomeLocation, + "/.minikube-gui/last_update_check"); + if (filePath == "") { + return false; + } + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) { + return false; + } + QTextStream in(&file); + QString line = in.readLine(); + QDateTime nextCheck = QDateTime::fromString(line).addSecs(60 * 60 * 24); + QDateTime now = QDateTime::currentDateTime(); + return nextCheck > now; +} + +static void logUpdateCheck() +{ + QDir dir = QDir(QDir::homePath() + "/.minikube-gui"); + if (!dir.exists()) { + dir.mkpath("."); + } + QString filePath = dir.filePath("last_update_check"); + QFile file(filePath); + if (!file.open(QIODevice::WriteOnly)) { + return; + } + QTextStream stream(&file); + stream << QDateTime::currentDateTime().toString() << "\n"; +} + +void Updater::checkForUpdates() +{ + if (checkedForUpdateRecently()) { + return; + } + logUpdateCheck(); + QString releases = getRequest("https://storage.googleapis.com/minikube-gui/releases.json"); + QJsonObject latestRelease = + QJsonDocument::fromJson(releases.toUtf8()).array().first().toObject(); + QString latestReleaseVersion = latestRelease["name"].toString(); + QVersionNumber latestReleaseVersionNumber = QVersionNumber::fromString(latestReleaseVersion); + if (m_version >= latestReleaseVersionNumber) { + return; + } + QJsonObject links = latestRelease["links"].toObject(); + QString key; +#if __linux__ + key = "linux"; +#elif __APPLE__ + key = "darwin"; +#else + key = "windows"; +#endif + QString link = links[key].toString(); + notifyUpdate(latestReleaseVersion, link); +} + +void Updater::notifyUpdate(QString latest, QString link) +{ + QDialog dialog; + dialog.setWindowTitle(tr("minikube GUI Update Available")); + dialog.setWindowIcon(m_icon); + dialog.setModal(true); + QFormLayout form(&dialog); + QLabel *msgLabel = new QLabel(); + msgLabel->setText("Version " + latest + + " of minikube GUI is now available!\n\nDownload the update from:"); + form.addWidget(msgLabel); + QLabel *linkLabel = new QLabel(); + linkLabel->setOpenExternalLinks(true); + linkLabel->setText("" + link + ""); + form.addWidget(linkLabel); + QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); + buttonBox.addButton(QString(tr("OK")), QDialogButtonBox::AcceptRole); + connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + form.addRow(&buttonBox); + dialog.exec(); +} + +QString Updater::getRequest(QString url) +{ + QNetworkAccessManager *manager = new QNetworkAccessManager(); + QObject::connect(manager, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply) { + if (reply->error()) { + qDebug() << reply->errorString(); + } + }); + QNetworkReply *resp = manager->get(QNetworkRequest(QUrl(url))); + QEventLoop loop; + connect(resp, &QNetworkReply::finished, &loop, &QEventLoop::quit); + loop.exec(); + return resp->readAll(); +} diff --git a/updater.h b/updater.h new file mode 100644 index 0000000..ee0de93 --- /dev/null +++ b/updater.h @@ -0,0 +1,39 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef UPDATER_H +#define UPDATER_H + +#include +#include +#include + +class Updater : public QObject +{ + Q_OBJECT + +public: + explicit Updater(QVersionNumber version, QIcon icon); + void checkForUpdates(); + +private: + void notifyUpdate(QString latest, QString link); + QString getRequest(QString url); + QVersionNumber m_version; + QIcon m_icon; +}; + +#endif // UPDATER_H diff --git a/window.cpp b/window.cpp new file mode 100644 index 0000000..0ed58ff --- /dev/null +++ b/window.cpp @@ -0,0 +1,152 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "window.h" + +#ifndef QT_NO_SYSTEMTRAYICON + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_TERMWIDGET +#include +#include +#include "qtermwidget.h" +#endif + +const QVersionNumber version = QVersionNumber::fromString("0.0.1"); + +Window::Window() +{ + trayIconIcon = new QIcon(":/images/minikube.png"); + checkForMinikube(); + + stackedWidget = new QStackedWidget; + logger = new Logger(); + commandRunner = new CommandRunner(this, logger); + basicView = new BasicView(); + advancedView = new AdvancedView(*trayIconIcon); + errorMessage = new ErrorMessage(this, *trayIconIcon); + progressWindow = new ProgressWindow(this, *trayIconIcon); + tray = new Tray(*trayIconIcon); + hyperKit = new HyperKit(*trayIconIcon); + updater = new Updater(version, *trayIconIcon); + + op = new Operator(advancedView, basicView, commandRunner, errorMessage, progressWindow, tray, + hyperKit, updater, stackedWidget, this); + + stackedWidget->addWidget(basicView->basicView); + stackedWidget->addWidget(advancedView->advancedView); + layout = new QVBoxLayout; + layout->addWidget(stackedWidget); + setLayout(layout); + resize(200, 300); + setWindowTitle(tr("minikube")); + setWindowIcon(*trayIconIcon); +} + +void Window::setVisible(bool visible) +{ + tray->setVisible(visible); + QDialog::setVisible(visible); +} + +void Window::closeEvent(QCloseEvent *event) +{ +#if __APPLE__ + if (!event->spontaneous() || !isVisible()) { + return; + } +#endif + if (tray->isVisible()) { + QMessageBox::information(this, tr("minikube"), + tr("minikube will minimize to the " + "system tray. To terminate the program, " + "choose Quit in the context menu " + "of the system tray entry.")); + hide(); + event->ignore(); + } +} + +static QString minikubePath() +{ + QString minikubePath = QStandardPaths::findExecutable("minikube"); + if (!minikubePath.isEmpty()) { + return minikubePath; + } + QStringList path = { "/usr/local/bin" }; + return QStandardPaths::findExecutable("minikube", path); +} + +void Window::checkForMinikube() +{ + QString program = minikubePath(); + if (!program.isEmpty()) { + return; + } + + QDialog dialog; + dialog.setWindowTitle(tr("minikube")); + dialog.setWindowIcon(*trayIconIcon); + dialog.setModal(true); + QFormLayout form(&dialog); + QLabel *message = new QLabel(this); + message->setText("minikube was not found on the path.\nPlease follow the install instructions " + "below to install minikube first.\n"); + form.addWidget(message); + QLabel *link = new QLabel(this); + link->setOpenExternalLinks(true); + link->setText("https://minikube.sigs.k8s.io/" + "docs/start/"); + form.addWidget(link); + QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); + buttonBox.addButton(QString(tr("OK")), QDialogButtonBox::AcceptRole); + connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + form.addRow(&buttonBox); + dialog.exec(); + exit(EXIT_FAILURE); +} + +#endif diff --git a/window.h b/window.h new file mode 100644 index 0000000..8feff4a --- /dev/null +++ b/window.h @@ -0,0 +1,96 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_SYSTEMTRAYICON + +#include + +QT_BEGIN_NAMESPACE +class QAction; +class QCheckBox; +class QComboBox; +class QGroupBox; +class QIcon; +class QLabel; +class QLineEdit; +class QMenu; +class QPushButton; +class QSpinBox; +class QTextEdit; +class QTableView; +class QProcess; +QT_END_NAMESPACE + +#include "basicview.h" +#include "advancedview.h" +#include "progresswindow.h" +#include "operator.h" +#include "errormessage.h" +#include "tray.h" +#include "hyperkit.h" +#include "updater.h" +#include "logger.h" + +class Window : public QDialog +{ + Q_OBJECT + +public: + Window(); + + void setVisible(bool visible) override; + void restoreWindow(); + +protected: + void closeEvent(QCloseEvent *event) override; + +private: + QIcon *trayIconIcon; + + void checkForMinikube(); + QStackedWidget *stackedWidget; + void checkForUpdates(); + QString getRequest(QString url); + void notifyUpdate(QString latest, QString link); + + BasicView *basicView; + AdvancedView *advancedView; + Operator *op; + CommandRunner *commandRunner; + ErrorMessage *errorMessage; + ProgressWindow *progressWindow; + Tray *tray; + HyperKit *hyperKit; + Updater *updater; + QVBoxLayout *layout; + Logger *logger; +}; + +#endif // QT_NO_SYSTEMTRAYICON + +#endif