Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial commit #1

Merged
merged 1 commit into from
Dec 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 38 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
308 changes: 308 additions & 0 deletions advancedview.cpp
Original file line number Diff line number Diff line change
@@ -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 <QHeaderView>
#include <QTableView>
#include <QHBoxLayout>
#include <QLabel>
#include <QDialog>
#include <QFormLayout>
#include <QDialogButtonBox>
#include <QLineEdit>
#include <QComboBox>

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);
}
Loading