createInstance function
Implementation
Future<void> createInstance(
TextEditingController nameController,
TextEditingController locationController,
WSLApi api,
TextEditingController autoSuggestBox,
TextEditingController userController,
) async {
plausible.event(name: "wsl_create");
String label = nameController.text;
// Replace all special characters with _
String name = label.replaceAll(RegExp('[^A-Za-z0-9]'), '_');
if (name != '') {
String distroName = autoSuggestBox.text;
// Set paths
Notify.message('creatinginstance-text'.i18n(), loading: true);
String location = locationController.text;
if (location == '') {
location = prefs.getString("DistroPath") ?? defaultPath;
location += '/$name';
}
// Check if docker image
bool isDockerImage = false;
if (distroName.startsWith('dockerhub:')) {
isDockerImage = true;
// Remove prefix
distroName = autoSuggestBox.text.split('dockerhub:')[1];
// Get tag
if (!distroName.contains(':')) {
distroName += ':latest';
}
String? image = distroName.split(':')[0];
String? tag = distroName.split(':')[1];
if (!distroName.contains('/')) {
image = 'library/$image';
}
bool isDownloaded = false;
// Check if image already downloaded
if (await DockerImage().isDownloaded(image, tag: tag)) {
isDownloaded = true;
}
// Check if image exists
if (!isDownloaded && await DockerImage().hasImage(image, tag: tag)) {
// Download image
Notify.message('${'downloading-text'.i18n()}...');
var docker = DockerImage()..distroName = distroName;
await docker.getRootfs(name, image, tag: tag,
progress: (current, total, currentStep, totalStep) {
if (currentStep != -1) {
String progressInMB =
(currentStep / 1024 / 1024).toStringAsFixed(2);
// String totalInMB = (total / 1024 / 1024).toStringAsFixed(2);
String percentage =
(currentStep / totalStep * 100).toStringAsFixed(0);
Notify.message('${'downloading-text'.i18n()}'
' Layer ${current + 1}/$total: $percentage% ($progressInMB MB)');
} else {
Notify.message(
'extractinglayers-text'.i18n(['$current', '$total']));
}
});
Notify.message('downloaded-text'.i18n());
// Set distropath with distroName
distroName = DockerImage().filename(image, tag);
} else if (!isDownloaded) {
Notify.message('distronotfound-text'.i18n());
return;
}
if (isDownloaded) {
// Set distropath with distroName
distroName = DockerImage().filename(image, tag);
}
}
// Navigator.of(context, rootNavigator: true).pop();
// Create instance
ProcessResult result = await api.create(
name, distroName, location, (String msg) => Notify.message(msg),
image: isDockerImage);
// Check if instance was created then handle postprocessing
if (result.exitCode != 0) {
Notify.message(WSLApi().utf8Convert(result.stdout));
} else {
var userCmds = prefs.getStringList('UserCmds_$distroName');
var groupCmds = prefs.getStringList('GroupCmds_$distroName');
if (userCmds != null && groupCmds != null) {
for (int i = 0; i < groupCmds.length; i++) {
var cmd = groupCmds[i].replaceAll("/bin/sh -c ", "");
cmd = cmd.replaceAll(RegExp(r'\s+'), ' ');
await api.exec(name, [cmd]);
}
for (int i = 0; i < userCmds.length; i++) {
var cmd = userCmds[i].replaceAll("/bin/sh -c ", "");
// Replace multiple spaces with one
cmd = cmd.replaceAll(RegExp(r'\s+'), ' ');
await api.exec(name, [cmd]);
}
}
String user = userController.text;
if (user != '') {
List<int> processes = await api.exec(name, [
'apt-get update',
'apt-get install -y sudo',
'useradd -m -s /bin/bash -G sudo $user',
'passwd $user',
'echo \'$user ALL=(ALL) NOPASSWD:ALL\' >> /etc/sudoers.d/wslsudo',
'echo -e \'[user]\ndefault = $user\' > /etc/wsl.conf',
]);
bool success = true;
for (dynamic process in processes) {
if (process != 0) {
success = false;
break;
}
}
if (success) {
prefs.setString('StartPath_$name', '/home/$user');
prefs.setString('StartUser_$name', user);
Notify.message('createdinstance-text'.i18n());
} else {
Notify.message('createdinstancenouser-text'.i18n());
}
} else {
// Install fake systemctl
if (distroName.contains('Turnkey')) {
// Set first start variable
prefs.setBool('TurnkeyFirstStart_$name', true);
Notify.message('installingfakesystemd-text'.i18n(), loading: true);
WSLApi().execCmds(
name,
[
'wget https://raw.githubusercontent.com/bostrot/'
'fake-systemd/master/systemctl -O /usr/bin/systemctl',
'chmod +x /usr/bin/systemctl',
'/usr/bin/systemctl',
],
onMsg: (output) => null,
onDone: () => Notify.message('createdinstance-text'.i18n()));
} else {
Notify.message('createdinstance-text'.i18n());
}
}
// Save distro label
prefs.setString('DistroName_$name', label);
// Save distro path
prefs.setString('Path_$name', location);
}
// Download distro check
} else {
Notify.message('entername-text'.i18n());
}
}