Skip to content

Commit

Permalink
Merge pull request #29 from bostrot/additional_features
Browse files Browse the repository at this point in the history
Additional features
  • Loading branch information
bostrot authored Apr 15, 2022
2 parents 7b2c3a2 + 8251ce6 commit 5c05d17
Show file tree
Hide file tree
Showing 24 changed files with 931 additions and 246 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,27 @@ WSL is great. It makes it very simple to spin up new workplaces with different s

Fairly simple. Download the latest release from the releases Page and start wsl2distromanager.exe

## Features

* Starting the program. YAY!
* Quick Actions (execute pre-defined scripts directly on your instances for quick configurations)
* Download and use Turnkey or other LXC containers (experimental, tested with e.g. Turnkey Wordpress)
* Use your own repository for rootfs' or LXC containers
* List WSL
* Copy WSL
* Delete WSL
* Start WSL
* Rename WSL
* Create WSL
* Download WSL
* Select rootfs from storage
* and more but I am tired of writing already ... Feel free to open a PR.


## What works

- [x] Starting the program. YAY!
- [X] Quick Actions
- [x] List WSL
- [x] Copy WSL
- [x] Delete WSL
Expand Down
Binary file modified build/windows/runner/Release/data/app.so
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"],"packages/fluent_ui/assets/AcrylicNoise.png":["packages/fluent_ui/assets/AcrylicNoise.png"],"packages/fluent_ui/fonts/FluentIcons.ttf":["packages/fluent_ui/fonts/FluentIcons.ttf"]}
{"packages/fluent_ui/assets/AcrylicNoise.png":["packages/fluent_ui/assets/AcrylicNoise.png"],"packages/fluent_ui/fonts/FluentIcons.ttf":["packages/fluent_ui/fonts/FluentIcons.ttf"]}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]},{"family":"packages/cupertino_icons/CupertinoIcons","fonts":[{"asset":"packages/cupertino_icons/assets/CupertinoIcons.ttf"}]},{"family":"packages/fluent_ui/FluentIcons","fonts":[{"asset":"packages/fluent_ui/fonts/FluentIcons.ttf"}]}]
[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]},{"family":"packages/fluent_ui/FluentIcons","fonts":[{"asset":"packages/fluent_ui/fonts/FluentIcons.ttf"}]}]
Binary file modified build/windows/runner/Release/data/flutter_assets/NOTICES.Z
Binary file not shown.
Binary file not shown.
Binary file modified build/windows/runner/Release/desktop_window_plugin.dll
Binary file not shown.
Binary file modified build/windows/runner/Release/flutter_windows.dll
Binary file not shown.
Binary file modified build/windows/runner/Release/system_theme_plugin.dll
Binary file not shown.
Binary file modified build/windows/runner/Release/url_launcher_windows_plugin.dll
Binary file not shown.
Binary file modified build/windows/runner/Release/wsl2distromanager.exe
Binary file not shown.
80 changes: 40 additions & 40 deletions lib/components/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,20 @@ class WSLApi {
return processes;
}

/// Executes a command in a WSL distro and returns the output
/// @param distribution: String
/// @param cmd: String
/// @return Future<String>
Future<String> execCmdAsRoot(String distribution, String cmd) async {
List<String> args = ['--distribution', distribution, '-u', 'root'];
for (var arg in cmd.split(' ')) {
args.add(arg);
}
ProcessResult results = await Process.run('wsl', args,
runInShell: true, stdoutEncoding: utf8, stderrEncoding: utf8);
return results.stdout;
}

/// Executes a command in a WSL distro. passwd will open a shell
/// @param distribution: String
/// @param cmd: List<String>
Expand Down Expand Up @@ -441,46 +455,32 @@ class WSLApi {

/// Returns list of downloadable WSL distros
/// @return Future<List<String>>
Future<List<String>> getDownloadable() async {
/*ProcessResult results =
await Process.run('wsl', ['--list', '--online'], stdoutEncoding: null);
String output = utf8Convert(results.stdout);
List<String> list = [];
bool nameStarted = false;
output.split('\n').forEach((line) {
// Filter out docker data
if (line != '' && nameStarted) {
list.add(line.split(' ')[0]);
}
// List started
if (line.startsWith('NAME')) {
nameStarted = true;
}
});*/
// Get even more distros
String repoLink =
"http://ftp.halifax.rwth-aachen.de/turnkeylinux/images/proxmox/";
await Dio().get(repoLink).then((value) => {
value.data.split('\n').forEach((line) {
if (line.contains('tar.gz"') &&
line.contains('href=') &&
(line.contains('debian-10') || line.contains('debian-11'))) {
String name = line
.split('href="')[1]
.split('"')[0]
.toString()
.replaceAll('.tar.gz', '')
.replaceAll('1_amd64', '')
.replaceAll(RegExp(r'-|_'), ' ')
.replaceAllMapped(RegExp(r' .|^.'),
(Match m) => m[0].toString().toUpperCase());
distroRootfsLinks.addAll({
name:
repoLink + line.split('href="')[1].split('"')[0].toString()
});
}
})
});
Future<List<String>> getDownloadable(
String repo, Function(String) onError) async {
try {
await Dio().get(repo).then((value) => {
value.data.split('\n').forEach((line) {
if (line.contains('tar.gz"') &&
line.contains('href=') &&
(line.contains('debian-10') || line.contains('debian-11'))) {
String name = line
.split('href="')[1]
.split('"')[0]
.toString()
.replaceAll('.tar.gz', '')
.replaceAll('1_amd64', '')
.replaceAll(RegExp(r'-|_'), ' ')
.replaceAllMapped(RegExp(r' .|^.'),
(Match m) => m[0].toString().toUpperCase());
distroRootfsLinks.addAll({
name: repo + line.split('href="')[1].split('"')[0].toString()
});
}
})
});
} catch (e) {
onError(e.toString());
}
List<String> list = [];
list.addAll(distroRootfsLinks.keys);
return list;
Expand Down
62 changes: 62 additions & 0 deletions lib/components/console.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import 'package:fluent_ui/fluent_ui.dart';
import 'package:wsl2distromanager/components/api.dart';
import 'package:wsl2distromanager/components/theme.dart';

class Console extends StatefulWidget {
const Console(
{Key? key,
required this.item,
required this.cmds,
required this.afterInit})
: super(key: key);
final String item;
final String cmds;
final Function afterInit;
@override
State<Console> createState() => _ConsoleState();
}

class _ConsoleState extends State<Console> {
String output = '';
ScrollController scrollController = ScrollController();

@override
void initState() {
WSLApi().execCmds(widget.item, widget.cmds.split('\n'), onMsg: (msg) {
try {
setState(() {
output += msg;
});
} catch (e) {
// ignore if state is already disposed
}
// Scroll to bottom
scrollController.animateTo(
scrollController.position.maxScrollExtent + 100.0,
duration: const Duration(milliseconds: 200),
curve: Curves.easeOut);
}, onDone: () {
output += '\n\n== Done ==';
});
super.initState();
widget.afterInit();
}

@override
Widget build(BuildContext context) {
return Container(
color: themeData.activeColor.withOpacity(0.1),
height: 100.0,
width: double.infinity,
child: SingleChildScrollView(
controller: scrollController,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SelectableText(
output,
style: TextStyle(color: themeData.activeColor.withOpacity(0.5)),
),
))));
}
}
3 changes: 3 additions & 0 deletions lib/components/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const String updateUrl =
const String motdUrl =
'https://raw.githubusercontent.com/bostrot/wsl2-distro-manager/main/motd.json';

const String defaultRepoLink =
'http://ftp.halifax.rwth-aachen.de/turnkeylinux/images/proxmox/';

// https://docs.microsoft.com/en-us/windows/wsl/install-on-server
Map<String, String> distroRootfsLinks = {
'Ubuntu 21.04':
Expand Down
1 change: 0 additions & 1 deletion lib/components/list_item.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:flutter/gestures.dart';
import 'package:wsl2distromanager/components/api.dart';
import 'package:wsl2distromanager/components/theme.dart';

Expand Down
11 changes: 10 additions & 1 deletion lib/dialogs/base_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ dialog({
required item,
required Function statusMsg,
Function? onSubmit,
bool bodyIsWidget = false,
Widget bodyAsWidget = const Text(''),
String title = '',
String body = '',
String submitText = '',
Expand All @@ -25,7 +27,14 @@ dialog({
title: centerText ? Center(child: Text(title)) : Text(title),
content: Column(
children: [
centerText ? Center(child: Text(body)) : Text(body),
!bodyIsWidget
? centerText
? Center(child: Text(body))
: Text(body)
: SizedBox(
width: double.infinity,
height: 120.0,
child: SingleChildScrollView(child: bodyAsWidget)),
submitInput
? Padding(
padding: const EdgeInsets.only(top: 10.0),
Expand Down
17 changes: 13 additions & 4 deletions lib/dialogs/create_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ createDialog(context, Function(String, {bool loading}) statusMsg) {
api: api,
autoSuggestBox: autoSuggestBox,
locationController: locationController,
userController: userController),
userController: userController,
statusMsg: statusMsg),
),
actions: [
Button(
Expand Down Expand Up @@ -87,9 +88,9 @@ createDialog(context, Function(String, {bool loading}) statusMsg) {
if (Navigator.canPop(context)) {
Navigator.pop(context);
}
statusMsg('Installing fake systemd ...');
// Install fake systemctl
if (autoSuggestBox.text.contains('Turnkey')) {
statusMsg('Installing fake systemd ...');
WSLApi().execCmds(
name,
[
Expand All @@ -98,8 +99,10 @@ createDialog(context, Function(String, {bool loading}) statusMsg) {
'chmod +x /usr/bin/systemctl',
'/usr/bin/systemctl',
],
onMsg: (output) => print(output),
onMsg: (output) => null,
onDone: () => statusMsg('DONE: creating instance'));
} else {
statusMsg('DONE: creating instance');
}
}
// Save distro label
Expand Down Expand Up @@ -128,13 +131,15 @@ class CreateWidget extends StatefulWidget {
required this.autoSuggestBox,
required this.locationController,
required this.userController,
required this.statusMsg,
}) : super(key: key);

final TextEditingController nameController;
final WSLApi api;
final TextEditingController autoSuggestBox;
final TextEditingController locationController;
final TextEditingController userController;
final Function(String, {bool loading}) statusMsg;

@override
State<CreateWidget> createState() => _CreateWidgetState();
Expand Down Expand Up @@ -183,7 +188,11 @@ class _CreateWidgetState extends State<CreateWidget> {
'Either use one of the pre-defined Distros or a file path to a '
'rootfs',
child: FutureBuilder<List<String>>(
future: widget.api.getDownloadable(),
future: widget.api.getDownloadable(
(prefs.getString('RepoLink') ??
'http://ftp.halifax.rwth-aachen.de/'
'turnkeylinux/images/proxmox/'),
(e) => widget.statusMsg(e)),
builder: (context, snapshot) {
List<String> list = [];
if (snapshot.hasData) {
Expand Down
Loading

0 comments on commit 5c05d17

Please sign in to comment.