Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • m1ghtfr3e/bitmask-vpn
  • leap/bitmask-vpn
  • meskio/bitmask-vpn
  • kali/bitmask-vpn
  • nsheep/bitmask-vpn
  • nilesh/bitmask-vpn
  • micah/bitmask-vpn
  • kwadronaut/bitmask-vpn
  • th/bitmask-vpn
  • wxl/bitmask-vpn
  • Nowa-Ammerlaan/bitmask-vpn
  • elijah/bitmask-vpn
  • happysalada/bitmask-vpn
  • JUZZZEE/bitmask-vpn
  • jkito/bitmask-vpn
  • panetone/bitmask-vpn
  • hsilva/bitmask-vpn
  • S0b0tkaZ11gy/bitmask-vpn
  • polster/bitmask-vpn-pahoeohe
  • Kulibin/bitmask-vpn
  • TheMimoGz/bitmask-vpn
  • fifi/bitmask-vpn
  • fly/bitmask-vpn
  • VlKozlove/bitmask-vpn
  • DonMephedrone/bitmask-vpn
  • Arti/bitmask-vpn
  • annxxxxx/bitmask-vpn
  • Arti/arti-bitmask-vpn-fork
  • peanut2/bitmask-vpn
29 results
Show changes
Showing
with 900 additions and 428 deletions
......@@ -4,7 +4,7 @@ Source: <https://0xacab.org/leap/riseup_vpn>
Files: *
Copyright: 2018 LEAP Encryption Access Project <info@leap.se>
License: GPLv3
License: GPL
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
......
......@@ -10,7 +10,7 @@ import os
from string import Template
TEMPLATES = ('app.desktop', 'changelog', 'control', 'rules')
TEMPLATES = ('app.install', 'app.desktop', 'changelog', 'control', 'rules', 'source/include-binaries')
here = os.path.split(os.path.realpath(__file__))[0]
......
From 82e3eda5709f1f8dd6bdb898a3c6b71a41cc4e62 Mon Sep 17 00:00:00 2001
From: jkito <belter@riseup.net>
Date: Sun, 25 Aug 2024 17:18:10 +0530
Subject: [PATCH] build: use qt5compat qml module to build on qt6.4 for ubuntu
and debian
---
bitmask.pro | 2 +-
gui/components/ErrorBox.qml | 2 +-
gui/components/Footer.qml | 14 ++++++--------
gui/components/Home.qml | 2 +-
gui/components/InitErrors.qml | 2 +-
gui/components/Locations.qml | 7 +++----
gui/components/MotdBox.qml | 2 +-
gui/components/Preferences.qml | 4 ++--
gui/components/SignalIcon.qml | 7 +++----
gui/components/Splash.qml | 2 +-
gui/components/StatusBox.qml | 2 +-
11 files changed, 21 insertions(+), 25 deletions(-)
diff --git a/bitmask.pro b/bitmask.pro
index bbeacb12..58ba5f2f 100644
--- a/bitmask.pro
+++ b/bitmask.pro
@@ -1,8 +1,8 @@
TARGET = $$TARGET
QT += quickcontrols2 svg
-CONFIG += qt staticlib
CONFIG += c++17 strict_c++
+CONFIG += qt staticlib core5compat
CONFIG += qtquickcompiler
RELEASE = $$RELEASE
diff --git a/gui/components/ErrorBox.qml b/gui/components/ErrorBox.qml
index 5667ed9d..ef8f58fb 100644
--- a/gui/components/ErrorBox.qml
+++ b/gui/components/ErrorBox.qml
@@ -1,6 +1,6 @@
import QtQuick
import QtQuick.Controls
-import QtQuick.Effects
+import Qt5Compat.GraphicalEffects
import "../themes/themes.js" as Theme
Item {
diff --git a/gui/components/Footer.qml b/gui/components/Footer.qml
index d534f96a..9df6db62 100644
--- a/gui/components/Footer.qml
+++ b/gui/components/Footer.qml
@@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
-import QtQuick.Effects
+import Qt5Compat.GraphicalEffects
import "../themes/themes.js" as Theme
ToolBar {
@@ -49,7 +49,7 @@ ToolBar {
}
Image {
- id: lightning
+ id: lightning
smooth: true
visible: ctx != undefined & root.selectedGateway == "auto"
width: 16
@@ -61,11 +61,10 @@ ToolBar {
verticalCenter: gwButton.verticalCenter
}
}
- MultiEffect {
+ ColorOverlay{
anchors.fill: lightning
source: lightning
- colorizationColor: getLocationColor()
- colorization: 1.0
+ color: getLocationColor()
antialiasing: true
}
@@ -123,11 +122,10 @@ ToolBar {
rightMargin: 20
}
}
- MultiEffect {
+ ColorOverlay{
anchors.fill: gwQuality
source: gwQuality
- colorizationColor: getSignalColor()
- colorization: 1.0
+ color: getSignalColor()
antialiasing: false
}
}
diff --git a/gui/components/Home.qml b/gui/components/Home.qml
index f3bea85a..7830f46d 100644
--- a/gui/components/Home.qml
+++ b/gui/components/Home.qml
@@ -1,6 +1,6 @@
import QtQuick
import QtQuick.Controls
-import QtQuick.Effects
+import Qt5Compat.GraphicalEffects
Page {
StatusBox {
diff --git a/gui/components/InitErrors.qml b/gui/components/InitErrors.qml
index aaf9897b..10b4755c 100644
--- a/gui/components/InitErrors.qml
+++ b/gui/components/InitErrors.qml
@@ -1,6 +1,6 @@
import QtQuick
import QtQuick.Controls
-import QtQuick.Effects
+import Qt5Compat.GraphicalEffects
ErrorBox {
diff --git a/gui/components/Locations.qml b/gui/components/Locations.qml
index 2a188738..6228a58c 100644
--- a/gui/components/Locations.qml
+++ b/gui/components/Locations.qml
@@ -1,7 +1,7 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
-import QtQuick.Effects
+import Qt5Compat.GraphicalEffects
import "../themes/themes.js" as Theme
@@ -81,11 +81,10 @@ ThemedPage {
//verticalCenterOffset: 3
}
}
- MultiEffect {
+ ColorOverlay{
anchors.fill: lightning
source: lightning
- colorizationColor: "black"
- colorization: 1.0
+ color: "black"
antialiasing: true
}
}
diff --git a/gui/components/MotdBox.qml b/gui/components/MotdBox.qml
index 2c8cdb8b..7b851c0c 100644
--- a/gui/components/MotdBox.qml
+++ b/gui/components/MotdBox.qml
@@ -1,6 +1,6 @@
import QtQuick
import QtQuick.Controls
-import QtQuick.Effects
+import Qt5Compat.GraphicalEffects
import "../themes/themes.js" as Theme
Item {
diff --git a/gui/components/Preferences.qml b/gui/components/Preferences.qml
index d8ed6587..a0b6bba6 100644
--- a/gui/components/Preferences.qml
+++ b/gui/components/Preferences.qml
@@ -2,8 +2,8 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Controls.Material
-import QtQuick.Effects
-import QtCore
+import Qt5Compat.GraphicalEffects
+import Qt.labs.settings
import "../themes/themes.js" as Theme
diff --git a/gui/components/SignalIcon.qml b/gui/components/SignalIcon.qml
index 8747f054..38a23710 100644
--- a/gui/components/SignalIcon.qml
+++ b/gui/components/SignalIcon.qml
@@ -1,7 +1,7 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
-import QtQuick.Effects
+import Qt5Compat.GraphicalEffects
import "../themes/themes.js" as Theme
@@ -41,11 +41,10 @@ Item {
]
}
}
- MultiEffect {
+ ColorOverlay{
anchors.fill: icon
source: icon
- colorizationColor: getQualityColor()
- colorization: 1.0
+ color: getQualityColor()
antialiasing: true
}
diff --git a/gui/components/Splash.qml b/gui/components/Splash.qml
index c9351804..d18cc3ba 100644
--- a/gui/components/Splash.qml
+++ b/gui/components/Splash.qml
@@ -1,6 +1,6 @@
import QtQuick
import QtQuick.Controls
-import QtQuick.Effects
+import Qt5Compat.GraphicalEffects
import "../themes/themes.js" as Theme
Page {
diff --git a/gui/components/StatusBox.qml b/gui/components/StatusBox.qml
index d17c2fe0..24a1f8f2 100644
--- a/gui/components/StatusBox.qml
+++ b/gui/components/StatusBox.qml
@@ -1,6 +1,6 @@
import QtQuick
import QtQuick.Controls
-import QtQuick.Effects
+import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import QtQuick.Templates as T
import QtQuick.Controls.impl
--
2.46.0
0001-build-use-qt5compat-qml-module-to-build-on-qt6.4-for.patch
......@@ -9,6 +9,11 @@ export GOCACHE=/tmp/gocache
export DH_GOPKG = 0xacab.org/leap/bitmask-vpn
export DH_GOLANG_EXCLUDES := vendor packages tools cmd/bitmask-helper cmd/bitmask-connect
export PATH := $(shell qmake6 -query "QT_INSTALL_BINS"):$(PATH)
export PROVIDER=${name}
export VENDOR_PATH=providers
#dh_golang doesn't do this for you
ifeq ($(DEB_HOST_ARCH), i386)
......@@ -32,12 +37,13 @@ APPNAME = ${binaryName}
override_dh_auto_test:
override_dh_auto_build:
make gen_providers_json
make build
override_dh_install:
mkdir -p $(CURDIR)/debian/${APPNAME}/usr/bin
mkdir -p $(CURDIR)/debian/${APPNAME}/usr/sbin
cp $(CURDIR)/helpers/bitmask-root $(CURDIR)/debian/${APPNAME}/usr/sbin/
cp $(CURDIR)/pkg/pickle/helpers/bitmask-root $(CURDIR)/debian/${APPNAME}/usr/sbin/
mkdir -p $(CURDIR)/debian/${APPNAME}/usr/share/polkit-1/actions
cp $(CURDIR)/helpers/se.leap.bitmask.policy $(CURDIR)/debian/${APPNAME}/usr/share/polkit-1/actions
cp build/qt/release/${APPNAME} $(CURDIR)/debian/${APPNAME}/usr/bin/${APPNAME}
......
debian/icons/scalable/${binaryName}.png
......@@ -15,7 +15,7 @@ BUILD_RELEASE?=no
WIN_CERT_PATH?=z:\leap\LEAP.pfx
WIN_CERT_PASS?=
OSX_CERT = "Developer ID Installer: LEAP Encryption Access Project"
DEB_VERSION = $(shell echo ${VERSION} | cut -d '-' -f 1,2)
DEB_VERSION = $(shell echo ${VERSION} | rev | cut -d '-' -f2- | rev)
ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10...
SYSTEM = Windows
......@@ -91,7 +91,7 @@ pkg_snap:
-@rm ../../snap
@mv ../../$(BINNAME)* ../../deploy
pkg_deb:
prepare_deb:
echo "[+] building debian package version" ${DEB_VERSION}
-@mkdir -p ../../deploy
@if [ $(BUILD_RELEASE) = no ]; then\
......@@ -106,6 +106,8 @@ pkg_deb:
@rm -rf build/${BINNAME}_${DEB_VERSION} build/bitmask-vpn_${VERSION}-src
@cd build && tar xzf $(BINNAME)_${DEB_VERSION}.orig.tar.gz && mv bitmask-vpn_${VERSION}-src ${BINNAME}_${DEB_VERSION}
@cp -r debian/ build/$(BINNAME)_$(DEB_VERSION)/
pkg_deb: prepare_deb
@cd build/$(BINNAME)_$(DEB_VERSION) && debuild -us -uc
@mv build/*.deb ../../deploy
......
......@@ -8,6 +8,7 @@
<AllowNonAsciiCharacters>false</AllowNonAsciiCharacters>
<Logo>installer-logo.png</Logo>
<InstallerApplicationIcon>installer-icon</InstallerApplicationIcon>
<ControlScript>script.qs</ControlScript>
<!--
<RemoteRepositories>
......
function Controller()
{
console.log("Controller script called")
}
Controller.prototype.ComponentSelectionPageCallback = function()
{
gui.clickButton(buttons.NextButton);
}
Controller.prototype.ReadyForInstallationPageCallback = function() {
console.log("Control script being called")
try {
var page = gui.pageWidgetByObjectName("DynamicInstallForAllUsersCheckBoxForm");
if(page) {
console.log("Control script being called")
var choice = page.installForAllCheckBox.checked ? "true" : "false";
installer.setValue("installForAllUsers", choice);
}
} catch(e) {
console.log(e);
}
}
\ No newline at end of file
!defined(INSTALLER, var):INSTALLER= "BitmaskVPN-Installer-git"
!defined(INSTALLER, var):INSTALLER= "Bitmask-Installer-git"
!defined(TARGET, var):TARGET= "bitmask-vpn"
TEMPLATE = aux
CONFIG -= debug_and_release
......
package main
import (
"bytes"
"errors"
"flag"
"fmt"
"io"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"text/template"
)
/* Outline
* runs as root and setup the bitmask-helper privileged helper on macOS
* needs to perform the following steps:
* 1. check if running as root
* 2. setup the plist file with the correct path to bitmask-helper
* 3. install plist file in location
* 4. while doing the above make sure that existing helper is not running and removed
*/
const (
plistTemplate = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WorkingDirectory</key>
<string>{{ .Path }}</string>
<key>StandardOutPath</key>
<string>{{ .Path }}/helper/bitmask-helper.log</string>
<key>StandardErrorPath</key>
<string>{{ .Path }}/helper/bitmask-helper-err.log</string>
<key>GroupName</key>
<string>daemon</string>
<key>RunAtLoad</key>
<true/>
<key>SessionCreate</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>ThrottleInterval</key>
<integer>5</integer>
<key>Label</key>
<string>{{ .Label }}</string>
<key>ProgramArguments</key>
<array>
<string>{{ .Path }}/bitmask-helper</string>
<string>-socket-uid</string>
<string>{{.Uid}}</string>
<string>-socket-gid</string>
<string>{{.Gid}}</string>
</array>
</dict>
</plist>`
helperName = "bitmask-helper"
// -action flag values
actionPostInstall = "post-install"
actionUninstall = "uninstall"
// -stage flag values
stagePre = "preinstall"
stageUninstall = "uninstall"
// listening socket flag values
socketUid = "socket-uid"
socketGid = "socket-gid"
)
var (
curdir = func() string {
execPath, err := os.Executable()
if err != nil {
log.Printf("error getting executable path: %v", err)
return ""
}
return filepath.Dir(execPath)
}()
// flags
installerAction string
installerStage string
appName string
plistPath string
launchdDaemonLabel string
uid int
gid int
)
func init() {
const (
action = "action"
stage = "stage"
appname = "appname"
)
var usageAction = fmt.Sprintf("the installer actions: %s", strings.Join([]string{actionPostInstall, actionUninstall}, ","))
var usageStage = "the installer action stage: preinstall, uninstall"
var usageAppName = "name of the application being installed this is used to form the app bundle name by appending .app to it"
flag.StringVar(&installerAction, action, "", usageAction)
flag.StringVar(&installerStage, stage, stageUninstall, usageStage)
flag.StringVar(&appName, appname, "", usageAppName)
flag.IntVar(&uid, socketUid, 0, "Helper unix socket UID")
flag.IntVar(&gid, socketGid, 0, "Helper unix socket GID")
flag.Parse()
}
func main() {
if os.Getuid() != 0 {
log.Fatal("not running as root")
}
if appName == "" || installerAction == "" {
log.Fatal("-action and -appname flags cannot be empty")
}
plistPath = fmt.Sprintf("/Library/LaunchDaemons/se.leap.helper.%s.plist", appName)
launchdDaemonLabel = fmt.Sprintf("se.leap.Helper.%s", appName)
switch installerAction {
case actionPostInstall:
if err := setupLogFile(filepath.Join(curdir, "post-install.log")); err != nil {
log.Fatal(err)
}
log.Println("running action: post-install")
if appBundlePath() == "" {
log.Fatal("could not find path to .app bundle")
}
err := postInstall()
if err != nil {
log.Fatal(err)
}
case actionUninstall:
log.Println("running action: uninstall")
uninstall(installerStage)
default:
log.Fatalf("unknown command supplied: %s", installerAction)
}
}
func appBundlePath() string {
path := filepath.Join(curdir, appName+".app")
_, err := os.Stat(path)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
log.Printf("unable to find the app bundle path: %v", err)
return ""
}
}
return path
}
func setupLogFile(logFile string) error {
f, err := os.Create(logFile)
if err != nil {
return err
}
w := io.MultiWriter(os.Stdout, f)
log.SetOutput(w)
return nil
}
func postInstall() error {
if isHelperRunning() {
if err := unloadHelperPlist(); err != nil {
log.Println(err)
}
}
log.Println("Changing ownership of 'bitmask-helper'")
// change ownership of bitmask-helper to root
if err := os.Chown(filepath.Join(appBundlePath(), helperName), 0, 0); err != nil {
log.Println("error while changing ownership of 'bitmask-helper': ", err)
}
// copy launchd plist file to target location /Library/LaunchDaemons
log.Println("Generate plist file for helper launchd daemon")
plist, err := generatePlist()
if err != nil {
return err
}
log.Println(plist)
log.Println("Writing plist content to file")
fout, err := os.OpenFile(plistPath, os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
return err
}
if n, err := io.WriteString(fout, plist); n < len(plist) || err != nil {
return fmt.Errorf("failed writing the plist file: %s: %v", fout.Name(), err)
}
// load the plist file onto launchd
log.Println("Loading plist file")
if err := loadHelperPlist(plistPath); err != nil {
log.Printf("error while loading launchd daemon: %s: %v\n", plistPath, err)
}
// change ownership of 'helper' dir
log.Println("Changing ownership of 'helper' dir")
if err := os.Chown(filepath.Join(appBundlePath(), "helper"), 0, 0); err != nil {
log.Println("error while changing ownership of dir 'helper': ", err)
}
return nil
}
func uninstall(stage string) {
switch stage {
case stagePre, stageUninstall:
if err := setupLogFile(filepath.Join("/tmp", fmt.Sprintf("bitmask-%s.log", stage))); err != nil {
log.Fatal(err)
}
if appBundlePath() == "" {
log.Fatal("could not find path to .app bundle")
}
default:
log.Fatal("unknow stage for uninstall: ", stage)
}
if isHelperRunning() {
if err := unloadHelperPlist(); err != nil {
log.Println("error while unloading launchd daemon: ", err)
}
}
if err := os.Remove(plistPath); err != nil {
log.Println("error while removing helper plist: ", err)
}
}
func isHelperRunning() bool {
cmd := exec.Command("ps", "-ceAo", "command")
out, err := cmd.Output()
if err != nil {
log.Println(err)
return false
}
processes := strings.Split(string(out), "\n")
for _, proc := range processes {
if strings.TrimSpace(proc) == "bitmask-helper" {
return true
}
}
return false
}
func loadHelperPlist(plistPath string) error {
cmd := exec.Command("launchctl", "load", plistPath)
_, err := cmd.Output()
if err != nil {
return err
}
return nil
}
func unloadHelperPlist() error {
cmd := exec.Command("launchctl", "unload", plistPath)
_, err := cmd.Output()
if err != nil {
return err
}
cmd = exec.Command("launchctl", "remove", launchdDaemonLabel)
_, _ = cmd.Output()
cmd = exec.Command("pkill", "-9", helperName)
_, err = cmd.Output()
return err
}
func generatePlist() (string, error) {
appPath := struct {
Path string
Label string
Uid int
Gid int
}{
Path: appBundlePath(),
Label: launchdDaemonLabel,
Uid: uid,
Gid: gid,
}
t, err := template.New("plist").Parse(plistTemplate)
if err != nil {
return "", err
}
plistContent := &bytes.Buffer{}
err = t.Execute(plistContent, appPath)
if err != nil {
return "", err
}
return plistContent.String(), nil
}
#!/usr/bin/env python
# Post installation script for BitmaskVPN.
# Please note that this installation will install ONE single helper with administrative privileges.
# This means that, for the time being, you can only install ONE of the BitmaskVPN derivatives at the same time.
# This might change in the future.
import glob
import os
import shutil
import sys
import subprocess
import time
HELPER = "bitmask-helper"
HELPER_PLIST = "/Library/LaunchDaemons/se.leap.bitmask-helper.plist"
_dir = os.path.dirname(os.path.realpath(__file__))
_appdir = glob.glob('{}/*VPN.app'.format(_dir))[0]
def main():
log = open(os.path.join(_dir, 'post-install.log'), 'w')
log.write('Checking for admin privileges...\n')
_id = os.getuid()
if _id != 0:
err = "ERROR: need to run as root. UID: %s\n" % str(_id)
log.write(err)
sys.exit(1)
if isHelperRunning():
log.write("Trying to stop bitmask-helper...\n")
# if this fail, we can check if the HELPER_PLIST is there
ok = unloadHelper()
log.write("success: %s \n" % str(ok))
ok = fixHelperOwner(log)
log.write("chown helper: %s \n" % str(ok))
log.write("Copy launch daemon...\n")
copyLaunchDaemon()
log.write("Trying to launch helper...\n")
out = launchHelper()
log.write("result: %s \n" % str(out))
grantPermissionsOnLogFolder()
# all done
log.write('post-install script: done\n')
sys.exit(0)
def isHelperRunning():
ps = _getProcessList()
return HELPER in ps
def unloadHelper():
out = subprocess.call(["launchctl", "unload", HELPER_PLIST])
time.sleep(0.5)
out2 = subprocess.call(["pkill", "-9", "bitmask-helper"]) # just in case
time.sleep(0.5)
return out == 0
def fixHelperOwner(log):
path = os.path.join(_appdir, HELPER)
try:
os.chown(path, 0, 0)
except OSError as exc:
log.write(str(exc))
return False
return True
def copyLaunchDaemon():
appDir = os.path.join(_dir, _appdir)
plist = "se.leap.bitmask-helper.plist"
plistFile = os.path.join(appDir, plist)
escapedPath = appDir.replace("/", "\/")
subprocess.call(["sed", "-i.back", "s/PATH/%s/g" % escapedPath, plistFile])
shutil.copy(plistFile, HELPER_PLIST)
def launchHelper():
out = subprocess.call(["launchctl", "load", HELPER_PLIST])
return out == 0
def grantPermissionsOnLogFolder():
helperDir = os.path.join(_appdir, 'helper')
try:
os.makedirs(helperDir)
except Exception:
pass
os.chown(helperDir, 0, 0)
def _getProcessList():
_out = []
output = subprocess.Popen(["ps", "-ceA"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = output.communicate()
for line in stdout.split('\n'):
cmd = line.split(' ')[-1]
_out.append(cmd.strip())
return _out
if __name__ == "__main__":
main()
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WorkingDirectory</key>
<string>PATH</string>
<key>StandardOutPath</key>
<string>PATH/helper/bitmask-helper.log</string>
<key>StandardErrorPath</key>
<string>PATH/helper/bitmask-helper-err.log</string>
<key>GroupName</key>
<string>daemon</string>
<key>RunAtLoad</key>
<true/>
<key>SessionCreate</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>ThrottleInterval</key>
<integer>5</integer>
<key>Label</key>
<string>se.leap.BitmaskHelper</string>
<key>Program</key>
<string>PATH/bitmask-helper</string>
</dict>
</plist>
#!/usr/bin/env python
# Uninstall script for BitmaskVPN.
import os
import shutil
import sys
import subprocess
import time
HELPER = "bitmask-helper"
HELPER_PLIST = "/Library/LaunchDaemons/se.leap.bitmask-helper.plist"
_dir = os.path.dirname(os.path.realpath(__file__))
def main(stage="uninstall"):
logfile = "bitmask-{stage}.log".format(stage=stage)
log = open(os.path.join('/tmp', logfile), 'w')
log.write('Checking for admin privileges...\n')
_id = os.getuid()
log.write("UID: %s\n" % str(_id))
if int(_id) != 0:
err = "error: need to run as root. UID: %s\n" % str(_id)
log.write(err)
sys.exit(1)
log.write('Checking if helper is running\n')
if isHelperRunning():
log.write("Trying to stop bitmask-helper...\n")
# if this fail, we can check if the HELPER_PLIST is there
try:
ok = unloadHelper()
except Exception as exc:
log.write('error: %v' % exc)
time.sleep(0.5)
log.write("success: %s \n" % str(ok))
log.write("Removing LaunchDaemon\n")
out = removeLaunchDaemon()
log.write("result: %s \n" % str(out))
# all done
log.write(stage + ' script: done\n')
sys.exit(0)
def isHelperRunning():
try:
pid = subprocess.check_output(['pgrep', HELPER])
if pid.strip() != '':
return True
except subprocess.CalledProcessError:
return False
return False
def unloadHelper():
out = subprocess.call(["launchctl", "unload", HELPER_PLIST])
out2 = subprocess.call(["pkill", "-9", "bitmask-helper"]) # just in case
return out == 0
def removeLaunchDaemon():
return subprocess.call(["rm", "-f", HELPER_PLIST])
if __name__ == "__main__":
stage="uninstall"
if len(sys.argv) == 2 and sys.argv[1] == "pre":
stage="preinstall"
main(stage)
......@@ -9,6 +9,15 @@ function majorVersion(str)
return parseInt(str.split(".", 1));
}
// from: https://forum.qt.io/topic/114975/qt-installerframework-is-altering-my-string-slashes
var Dir = new function () {
this.toNativeSeparator = function (path) {
if (installer.value("os") == "win")
return path.replace(/\//g, '\\');
return path;
}
};
function cancelInstaller(message)
{
installer.setDefaultPageVisible(QInstaller.Introduction, false);
......@@ -24,12 +33,31 @@ function cancelInstaller(message)
}
function Component() {
// Check whether OS is supported.
// start installer with -v to see debug output
if (systemInfo.productType === "macos") {
var uid = installer.execute("/usr/bin/id", ["-u"])[0]
var gid = installer.execute("/usr/bin/id", ["-g"])[0]
installer.setValue("HelperSocketUid", uid.trim())
installer.setValue("HelperSocketGid", gid.trim())
console.log("UID: " + uid)
console.log("GID: " + gid)
}
installer.gainAdminRights();
console.log("OS: " + systemInfo.productType);
console.log("Kernel: " + systemInfo.kernelType + "/" + systemInfo.kernelVersion);
installer.setDefaultPageVisible(QInstaller.TargetDirectory, false);
if (installer.isInstaller()) {
console.log("Checking for existing installation")
component.loaded.connect(this, Component.prototype.installerLoaded);
}
// Check whether OS is supported.
// start installer with -v to see debug output
var validOs = false;
if (systemInfo.kernelType === "winnt") {
......@@ -54,11 +82,14 @@ function Component() {
}
console.log("CPU Architecture: " + systemInfo.currentCpuArchitecture);
if (systemInfo.productType === "windows") {
installer.addWizardPage(component, "InstallForAllUsersCheckBoxForm", QInstaller.LicenseCheck);
}
}
Component.prototype.createOperations = function ()
{
if (systemInfo.productType === "osx") {
if (systemInfo.productType === "macos") {
preInstallOSX();
}
if (systemInfo.productType === "windows") {
......@@ -73,9 +104,13 @@ Component.prototype.createOperations = function ()
// We can also use this to register different components (different architecture for instance)
// See https://doc.qt.io/qtinstallerframework/qt-installer-framework-systeminfo-packages-root-meta-installscript-qs.html
console.log("installForAllUsers value: " + installer.value("installForAllUsers"));
if (systemInfo.productType === "windows") {
postInstallWindows();
} else if (systemInfo.productType === "osx") {
if (installer.value("installForAllUsers") === "true") {
installForAllUsersWindows()
}
} else if (systemInfo.productType === "macos") {
uninstallOSX();
postInstallOSX();
} else {
......@@ -83,39 +118,71 @@ Component.prototype.createOperations = function ()
}
}
Component.prototype.installerLoaded = function () {
var dir = installer.value("TargetDir")
var maintenancetoolPath = Dir.toNativeSeparator(dir + "/uninstall.exe")
if (systemInfo.productType == "macos") {
maintenancetoolPath = Dir.toNativeSeparator(dir + "/uninstall.app" + "/Contents/MacOS/uninstall")
}
if (installer.fileExists(dir) && installer.fileExists(maintenancetoolPath)) {
console.log("Found existing installation at: " + dir)
var result = QMessageBox.warning("uninstallprevious.critical", "Uninstall previous version", "To proceed existing installation needs to be removed. Click OK to remove existing installation.",
QMessageBox.Ok | QMessageBox.Cancel);
if (result == QMessageBox.Ok) {
console.log("Running uninstall using maintenance tool at: " + maintenancetoolPath)
installer.execute(maintenancetoolPath, ["purge", "-c"]);
}
if (result == QMessageBox.Cancel) {
cancelInstaller("Need to removed existing installation to proceed.");
}
}
}
function preInstallWindows() {
console.log("Pre-installation for Windows: check for running bitmask");
component.addOperation(
"Execute", "{1}", "powershell", "-NonInteractive", "-NoProfile", "-command", "try {Get-Process $BINNAME} catch { exit 1}",
"errormessage=It seems that an old RiseupVPN client is running. Please exit the app and run this installer again.",
"Execute", "{1}", "powershell", "-NonInteractive", "-NoProfile", "-command", "try {Get-Process $BINNAME -ErrorAction Stop} catch { exit 1}",
"errormessage=It seems that an old $APPNAME client is running. Please exit the app and run this installer again.",
);
/* Remove-Service only introduced in PS 6.0 */
component.addElevatedOperation(
"Execute", "{0}", "powershell", "-NonInteractive", "-NoProfile", "-command",
"try {Get-Service bitmask-helper-v2} catch {exit 0}; try {Stop-Service bitmask-helper-v2} catch {}; try {$$srv = Get-Service bitmask-helper-v2; if ($$srv.Status -eq 'Running') {exit 1} else {exit 0};} catch {exit 0}",
"errormessage=It seems that bitmask-helper-v2 service is running, and we could not stop it. Please manually uninstall any previous RiseupVPN or CalyxVPN client and run this installer again.",
"errormessage=It seems that bitmask-helper-v2 service is running, and we could not stop it. Please manually uninstall any previous $APPNAME client and run this installer again.",
);
}
function postInstallWindows() {
// TODO - check if we're on Windows10 or older, and use the needed tap-windows installer accordingly.
console.log("Installing OpenVPN tap driver");
component.addElevatedOperation("Execute", "@TargetDir@/tap-windows.exe", "/S", "/SELECT_UTILITIES=1"); /* TODO uninstall */
/* remove an existing service, if it is stopped. Remove-Service is only in PS>6, and sc.exe delete leaves some garbage on the registry, so let's use the binary itself */
console.log("Removing any previously installer helper...");
component.addElevatedOperation("Execute", "{0,1}", "@TargetDir@/helper.exe", "remove");
console.log("Now trying to install latest helper");
component.addElevatedOperation("Execute", "@TargetDir@/helper.exe", "install", "UNDOEXECUTE", "@TargetDir@/helper.exe", "remove");
component.addElevatedOperation("Execute", "@TargetDir@/helper.exe", "start", "UNDOEXECUTE", "@TargetDir@/helper.exe", "stop");
console.log("Adding shortcut entries/...");
// TODO - we probably need to package different flavors of the installer for windows 8, arm, i386 etc, and change the installer we ship too.
var openVpnMsi = Dir.toNativeSeparator(installer.value("TargetDir") + "/openvpn-installer.msi")
console.log("Installing OpenVPN binaries and service");
component.addElevatedOperation("Execute", "{0}", "msiexec", "/i", openVpnMsi, "ADDLOCAL=OpenVPN.Service,OpenVPN,Drivers,Drivers.TAPWindows6,Drivers.Wintun", "/passive")
console.log("Adding shortcut entries...");
component.addElevatedOperation("Mkdir", "@StartMenuDir@");
component.addElevatedOperation("CreateShortcut", "@TargetDir@/$BINNAME.exe", "@StartMenuDir@/$APPNAME.lnk", "workingDirectory=@TargetDir@", "iconPath=@TargetDir@/icon.ico", "description=Start $APPNAME");
component.addElevatedOperation("CreateShortcut", "@TargetDir@\\$BINNAME.exe", "@StartMenuDir@\\$APPNAME.lnk", "workingDirectory=@TargetDir@", "iconPath=@TargetDir@\\icon.ico", "description=Start $APPNAME");
// TODO I think this one is not being created because the path doesn't exist yet. We might want to do this by hooking on the installation finished signal instead.
component.addElevatedOperation(
"CreateShortcut",
"@TargetDir@/Uninstall-$APPNAME.exe",
"@StartMenuDir@/Uninstall.lnk"
"@TargetDir@\\Uninstall-$APPNAME.exe",
"@StartMenuDir@\\Uninstall.lnk"
);
}
function installForAllUsersWindows() {
component.addElevatedOperation(
"Execute", "{0}", "powershell", "-NonInteractive", "-NoProfile", "-command",
"try {New-LocalGroup -Name 'OpenVPN Administrators' -Description 'Group to allow use of openvpn' -ErrorAction Stop} catch [Microsoft.PowerShell.Commands.GroupExistsException] { exit 0 }",
"errormessage=Unable to create the 'OpenVPN Administrators' group.",
"UNDOEXECUTE", "{0}", "powershell", "-NonInteractive", "-NoProfile", "-command",
"try { Remove-LocalGroup -Name 'OpenVPN Administrators' -ErrorAction Stop } catch [Microsoft.PowerShell.Commands.GroupNotFoundException] { exit 0 }",
"errormessage=Unable to remove the 'OpenVPN Administrator' group."
);
component.addElevatedOperation(
"Execute", "{0}", "powershell", "-NonInteractive", "-NoProfile", "-command",
"$$users=(Get-LocalUser | Select-Object Name | where {$$_.Name -NotMatch 'Administrator' -and $$_.Name -NotMatch 'Guest' -and $$_.Name -NotMatch 'DefaultAccount' -and $$_.Name -NotMatch 'WDAGUtilityAccount'}); try {Add-LocalGroupMember -Group 'OpenVPN Administrators' -Member $$users -ErrorAction Stop} catch [Microsoft.PowerShell.Commands.MemberExistsException] {exit 0}",
"errormessage=Unable to add users to the 'OpenVPN Administrators' group."
);
}
......@@ -138,19 +205,21 @@ function uninstallOSX() {
// TODO use installer filepath??
component.addElevatedOperation(
"Execute", "{0}",
"@TargetDir@/uninstall.py", "pre",
"@TargetDir@/post-install", "-action=uninstall", "-stage=preinstall", "-appname=@ProductName@",
"errormessage=There was an error during the pre-installation script, things might be broken. Please report this error and attach /tmp/bitmask-uninstall.log"
);
}
function postInstallOSX() {
var uid = installer.value("HelperSocketUid")
var gid = installer.value("HelperSocketGid")
console.log("Post-installation for OSX");
component.addElevatedOperation(
"Execute", "{0}",
"@TargetDir@/post-install.py",
"@TargetDir@/post-install", "-action=post-install", "-appname=@ProductName@", "-socket-uid=" + uid, "-socket-gid=" + gid,
"errormessage=There was an error during the post-installation script, things might be broken. Please report this error and attach the post-install.log file.",
"UNDOEXECUTE",
"@TargetDir@/uninstall.py"
"@TargetDir@/post-install", "-action=uninstall", "-appname=@ProductName@"
);
}
......@@ -159,3 +228,12 @@ function postInstallLinux() {
console.log("Maybe you want to use your package manager instead?");
component.addOperation("AppendFile", "/tmp/bitmask-installer.log", "this is a test - written from the installer");
}
function uninstallWindows() {
console.log("uninstall for windows: remove openvpn administrators group")
component.addElevatedOperation(
"Execute", "{0}", "powershell", "-NonInteractive", "-NoProfile", "-command",
"Remove-LocalGroup -Name 'OpenVPN Administrator' -ErrorAction Ignore",
);
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>InstallForAllUsersCheckBoxForm</class>
<widget class="QWidget" name="InstallForAllUsersCheckBoxForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>412</width>
<height>179</height>
</rect>
</property>
<property name="windowTitle">
<string>Select Installation Mode</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>10</number>
</property>
<item>
<widget class="QCheckBox" name="installForAllCheckBox">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Install for All Users on this Computer</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="allUsersLabel">
<property name="text">
<string>The application will be installed for all users on this machine. All users will be added to the OpenVPN Administrators group to enable interaction with OpenVPN.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="indent">
<number>25</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources />
<connections />
</ui>
\ No newline at end of file
......@@ -7,5 +7,11 @@
<Default>false</Default>
<RequiresAdminRights>true</RequiresAdminRights>
<Script>install.js</Script>
<Licenses>
<License name="License Agreement" file="LICENSE.txt" />
</Licenses>
<ForcedInstallation>true</ForcedInstallation>
<UserInterfaces>
<UserInterface>installforallcheckbox.ui</UserInterface>
</UserInterfaces>
</Package>
......@@ -10,7 +10,7 @@ from base64 import decodebytes as decode
POLKIT = b'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHBvbGljeWNv\nbmZpZyBQVUJMSUMKICItLy9mcmVlZGVza3RvcC8vRFREIFBvbGljeUtpdCBQb2xpY3kgQ29uZmln\ndXJhdGlvbiAxLjAvL0VOIgogImh0dHA6Ly93d3cuZnJlZWRlc2t0b3Aub3JnL3N0YW5kYXJkcy9Q\nb2xpY3lLaXQvMS9wb2xpY3ljb25maWcuZHRkIj4KPHBvbGljeWNvbmZpZz4KCiAgPHZlbmRvcj5M\nRUFQIFByb2plY3Q8L3ZlbmRvcj4KICA8dmVuZG9yX3VybD5odHRwOi8vbGVhcC5zZS88L3ZlbmRv\ncl91cmw+CgogIDxhY3Rpb24gaWQ9InNlLmxlYXAuYml0bWFzay5yaXNldXB2cG4ucG9saWN5Ij4K\nICAgIDxkZXNjcmlwdGlvbj5SdW5zIGJpdG1hc2sgaGVscGVyIHRvIGxhdW5jaCBmaXJld2FsbCBh\nbmQgb3BlbnZwbiAoUmlzZXVwVlBOKTwvZGVzY3JpcHRpb24+CiAgICA8ZGVzY3JpcHRpb24geG1s\nOmxhbmc9ImVzIj5FamVjdXRhIGVsIGFzaXN0ZW50ZSBkZSBiaXRtYXNrIHBhcmEgbGFuemFyIGVs\nIGZpcmV3YWxsIHkgb3BlbnZwbiAoUmlzZXVwVlBOKTwvZGVzY3JpcHRpb24+CiAgICA8bWVzc2Fn\nZT5SaXNldXBWUE4gbmVlZHMgdGhhdCB5b3UgYXV0aGVudGljYXRlIHRvIHN0YXJ0PC9tZXNzYWdl\nPgogICAgPG1lc3NhZ2UgeG1sOmxhbmc9ImVzIj5SaXNldXBWUE4gbmVjZXNpdGEgYXV0b3JpemFj\naW9uIHBhcmEgY29tZW56YXI8L21lc3NhZ2U+CiAgICA8aWNvbl9uYW1lPnBhY2thZ2UteC1nZW5l\ncmljPC9pY29uX25hbWU+IAogICAgPGRlZmF1bHRzPgogICAgICA8YWxsb3dfYW55PnllczwvYWxs\nb3dfYW55PgogICAgICA8YWxsb3dfaW5hY3RpdmU+eWVzPC9hbGxvd19pbmFjdGl2ZT4KICAgICAg\nPGFsbG93X2FjdGl2ZT55ZXM8L2FsbG93X2FjdGl2ZT4KICAgIDwvZGVmYXVsdHM+CiAgICA8YW5u\nb3RhdGUga2V5PSJvcmcuZnJlZWRlc2t0b3AucG9saWN5a2l0LmV4ZWMucGF0aCI+L3NuYXAvYmlu\nL3Jpc2V1cC12cG4uYml0bWFzay1yb290PC9hbm5vdGF0ZT4KICA8L2FjdGlvbj4KPC9wb2xpY3lj\nb25maWc+Cg==\n'
with open('/usr/share/polkit-1/actions/se.leap.bitmask.riseupvpn.policy', 'w') as polkit:
with open('/usr/share/polkit-1/actions/se.leap.bitmask.riseup-vpn.policy', 'w') as polkit:
lines = decode(POLKIT).split(b"\n")
for line in lines:
polkit.write(line.decode() + "\n")
......
#!/bin/sh
echo "Executing remove hook for RiseupVPN"
rm "/usr/share/polkit-1/actions/se.leap.bitmask.riseupvpn.policy"
rm "/usr/share/polkit-1/actions/se.leap.bitmask.riseup-vpn.policy"
unlink "/usr/share/applications/riseup-vpn.desktop" || echo "did not remove workaround for global desktop entry"
echo "done"
......@@ -8,7 +8,7 @@ description: |
grade: stable
confinement: classic
icon: snap/gui/icon.svg
base: core20
base: core22
compression: lzo
architectures:
......@@ -18,11 +18,11 @@ architectures:
parts:
bitmask-root:
plugin: dump
source: helpers
source: pkg
source-type: local
override-prime: |
mkdir -p bin
cp $SNAPCRAFT_PART_SRC/bitmask-root bin/
cp $SNAPCRAFT_PART_SRC/pickle/helpers/bitmask-root bin/
chmod +x bin/bitmask-root
openvpn:
......@@ -34,8 +34,12 @@ parts:
bitmask-vpn:
plugin: nil
build-attributes:
- enable-patchelf
source: .
source-type: local
build-environment:
- QMAKE: qmake6
stage:
- bin/${binaryName}
override-build: |
......@@ -43,206 +47,121 @@ parts:
# Maybe we just need to put the providers.json in the VENDOR_PATH
# and pass it to gui/providers from some path that snap can access.
# Same for the vendor.qrc
update-alternatives --install /usr/bin/gofmt gofmt /usr/lib/go-1.21/bin/gofmt 0
update-alternatives --install /usr/bin/go go /usr/lib/go-1.21/bin/go 0
ln -s $(qmake6 -query "QT_INSTALL_BINS")/lrelease /usr/local/bin/lrelease
mkdir -p $SNAPCRAFT_PART_INSTALL/snap/
mkdir -p $SNAPCRAFT_PRIME/snap/
echo ${version} > $SNAPCRAFT_PRIME/snap/version.txt
make build_golib
ln -fs /usr/lib/qt5/bin/lrelease /root/parts/qt5/install/usr/lib/qt5/bin/lrelease
QMAKE=/root/parts/qt5/install/usr/lib/qt5/bin/qmake LRELEASE=/usr/lib/qt5/bin/lrelease QT_SELECT=5 XBUILD=no TARGET=${binaryName} make build_gui
make vendor
make build
mkdir -p $SNAPCRAFT_PART_INSTALL/bin
mv build/qt/release/${binaryName} $SNAPCRAFT_PART_INSTALL/bin/
override-prime: |
rm -rf $SNAPCRAFT_PROJECT_DIR/snap/hooks/.mypy_cache
snapcraftctl prime
build-packages:
- pkg-config
- g++
- golang
- golang-1.21-go
- git
- make
- qttools5-dev-tools
- qt6-tools-dev-tools
- qt6-tools-dev
- qml-module-qtquick-controls2
- libqt6qml6
- libqt6svg6-dev
- qt6-l10n-tools
- qt6-base-dev
- qt6-base-dev-tools
- qt6-declarative-dev
- qt6-declarative-dev-tools
- libgl1-mesa-dev
- libqt6core5compat6-dev
- libglu1-mesa-dev
- libqt6opengl6-dev
stage-packages:
- qml-module-qt-labs-platform
after: [desktop-qt5]
desktop-integration:
plugin: nil
stage-packages:
- libx11-data
- libx11-xcb1
- xkb-data
desktop-qt5:
source: https://github.com/desktop-app/snapcraft-desktop-helpers.git
source-subdir: qt
plugin: make
make-parameters: ["FLAVOR=qt5"]
build-packages:
- build-essential
- dpkg-dev
stage-packages:
- libjpeg-turbo8
- qml6-module-qtquick
- qml6-module-qt5compat-graphicaleffects
- qml6-module-qtquick-controls
- qml6-module-qtquick-dialogs
- qml6-module-qtquick-layouts
- qml6-module-qtqml-workerscript
- qml6-module-qtquick-templates
- qml6-module-qtquick-window
- qml6-module-qt-labs-platform
- qml6-module-qtcore
- qt6-wayland
- libopengl0
- libqt6core6
- libqt6dbus6
- libqt6gui6
- libqt6network6
- libqt6qml6
- libqt6widgets6
- libb2-1
- libdouble-conversion3
- libgomp1
- libmd4c0
- libpcre2-16-0
- libproxy1v5
- libxkbcommon0
- ttf-ubuntu-font-family
- dmz-cursor-theme
- light-themes
- adwaita-icon-theme
- gnome-themes-standard
- shared-mime-info
- libgdk-pixbuf2.0-0
- locales-all
- xdg-user-dirs
- fcitx-frontend-qt5
- libglib2.0-bin
stage:
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libjpeg.so.8.2.2
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libQt5Core.so.5
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libQt5DBus.so.5
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libQt5EglFSDeviceIntegration.so.5
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libQt5Gui.so.5
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libQt5Network.so.5
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libQt5XcbQpa.so.5
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/bearer/libqconnmanbearer.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/bearer/libqgenericbearer.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/bearer/libqnmbearer.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/egldeviceintegrations/libqeglfs-emu-integration.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/generic/libqevdevkeyboardplugin.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/generic/libqevdevmouseplugin.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/generic/libqevdevtabletplugin.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/generic/libqevdevtouchplugin.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/generic/libqtuiotouchplugin.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/imageformats/libqgif.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/imageformats/libqico.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/imageformats/libqjpeg.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/platforminputcontexts/libibusplatforminputcontextplugin.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/platforms/libqeglfs.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/platforms/libqlinuxfb.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/platforms/libqminimal.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/platforms/libqminimalegl.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/platforms/libqoffscreen.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/platforms/libqvnc.so
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/platforms/libqxcb.so
after:
- qt5
qt5:
# gsettings, pixbuf and immodules are not needed by all snaps,
# but they are so common a requirement include them here
gsettings+pixbuf+immodules:
plugin: nil
build-packages:
- libdbus-1-dev
- libegl-dev
- libfontconfig1-dev
- libfreetype-dev
- libgl-dev
- libglib2.0-dev
- libharfbuzz-dev
- libicu-dev
- libpcre2-dev
- libpng-dev
- libwayland-dev
- libx11-dev
- libx11-xcb-dev
- libxcb1-dev
- libxcb-glx0-dev
- libxcb-icccm4-dev
- libxcb-image0-dev
- libxcb-keysyms1-dev
- libxcb-randr0-dev
- libxcb-render0-dev
- libxcb-render-util0-dev
- libxcb-shape0-dev
- libxcb-shm0-dev
- libxcb-sync-dev
- libxcb-util-dev
- libxcb-xfixes0-dev
- libxcb-xinerama0-dev
- libxcb-xinput-dev
- libxcb-xkb-dev
- libxcursor-dev
- libxkbcommon-dev
- libxkbcommon-x11-dev
- zlib1g-dev
- libgdk-pixbuf2.0-0
- librsvg2-common
- shared-mime-info
- libgtk-3-0
override-build: |
craftctl default
# Update mime database
update-mime-database ${CRAFT_PART_INSTALL}/usr/share/mime
# build immodules cache
mkdir -p ${CRAFT_PART_INSTALL}/usr/lib/${CRAFT_ARCH_TRIPLET}/gtk-3.0/3.0.0/
/usr/lib/${CRAFT_ARCH_TRIPLET}/libgtk-3-0/gtk-query-immodules-3.0 > ${CRAFT_PART_INSTALL}/usr/lib/${CRAFT_ARCH_TRIPLET}/gtk-3.0/3.0.0/immodules.cache
stage-packages:
- libdbus-1-3
- libegl1
- libfontconfig1
- libfreetype6
- libgl1
- libglib2.0-0
- libharfbuzz0b
- libicu66
- libpcre2-16-0
- libpng16-16
#- libwayland-client0
#- libwayland-cursor0
#- libwayland-egl1
- libx11-6
- libx11-xcb1
- libxcb1
- libxcb-glx0
- libxcb-icccm4
- libxcb-image0
- libxcb-keysyms1
- libxcb-randr0
- libxcb-render0
- libxcb-render-util0
- libxcb-shape0
- libxcb-shm0
- libxcb-sync1
- libxcb-util1
- libxcb-xfixes0
- libxcb-xinerama0
- libxcb-xinput0
- libxcb-xkb1
- libxcursor1
- libxkbcommon0
- libxkbcommon-x11-0
- zlib1g
- try: [appmenu-qt5] # not available on core18
override-pull: |
QT=5_15_2
git clone -b v5.15.2 --depth=1 git://code.qt.io/qt/qt5.git .
perl init-repository --module-subset=qtbase,qtimageformats,qtsvg,qtdeclarative,qtgraphicaleffects,qtquickcontrols,qtquickcontrols2,qtscript
git submodule update qtbase qtimageformats qtsvg qtdeclarative qtgraphicaleffects qtquickcontrols qtquickcontrols2 qtscript
- librsvg2-common
- gsettings-desktop-schemas
- libglib2.0-bin
override-prime: |
craftctl default
# Compile the gsettings schemas
/usr/lib/${CRAFT_ARCH_TRIPLET}/glib-2.0/glib-compile-schemas "$CRAFT_PRIME/usr/share/glib-2.0/schemas"
# Index the pixbuf loaders
LOADERS_PATH=$(echo ${CRAFT_PRIME}/usr/lib/${CRAFT_ARCH_TRIPLET}/gdk-pixbuf-2.0/*/loaders)
QUERY_LOADERS=/usr/lib/${CRAFT_ARCH_TRIPLET}/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders
GDK_PIXBUF_MODULEDIR=${LOADERS_PATH} ${QUERY_LOADERS} > ${LOADERS_PATH}/../loaders.cache
sed s!$CRAFT_PRIME!!g --in-place ${LOADERS_PATH}/../loaders.cache
setup:
plugin: dump
source: https://github.com/canonical/iot-example-graphical-snap.git
source-subdir: wayland-launch
override-build: |
./configure \
-prefix /usr \
-bindir /usr/lib/qt5/bin \
-libdir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET \
-docdir /usr/share/qt5/doc \
-headerdir /usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5 \
-datadir /usr/share/qt5 \
-archdatadir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5 \
-plugindir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins \
-importdir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/imports \
-translationdir /usr/share/qt5/translations \
-hostdatadir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5 \
-sysconfdir /etc/xdg \
-examplesdir /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/examples \
-release \
-opensource \
-confirm-license \
-no-gtk \
-no-feature-xcb-sm \
-no-openssl \
-nomake examples \
-nomake tests \
-opengl desktop \
-I $SNAPCRAFT_STAGE/usr/include \
-L $SNAPCRAFT_STAGE/usr/lib/$SNAPCRAFT_ARCH_TRIPLET
make -j$SNAPCRAFT_PARALLEL_BUILD_COUNT
make INSTALL_ROOT="$SNAPCRAFT_PART_INSTALL" install
stage:
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/libjpeg.so.8.2.2
# The plugs needed to run Wayland. (wayland-launch checks them, setup.sh connects them)
# You may add further plugs here if you want these options
PLUGS="opengl wayland graphics-core22"
sed --in-place "s/%PLUGS%/$PLUGS/g" $CRAFT_PART_BUILD/wayland-launch/bin/wayland-launch
sed --in-place "s/%PLUGS%/$PLUGS/g" $CRAFT_PART_BUILD/wayland-launch/bin/setup.sh
craftctl default
stage-packages:
- inotify-tools
graphics-core22:
after:
# Your application packaging
- gsettings+pixbuf+immodules
- setup
- bitmask-vpn
source: https://github.com/MirServer/graphics-core22.git
plugin: dump
override-prime: |
craftctl default
${CRAFT_PART_SRC}/bin/graphics-core22-cleanup mesa-core22 nvidia-core22
cd "$CRAFT_PRIME/usr/share/"
rm -rf bug drirc.d glvnd libdrm lintian man
rm -rf applications apport bash-completion dbus-1 doc-base doc gtk-doc\
help pkgconfig libthai metainfo themes thumbnailers xml
prime:
- -./usr/include
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/cmake
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pkgconfig
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/bin
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/mkspecs
- -./usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/examples
- -./usr/lib/qt5
- -./usr/share
- bin/graphics-core22-wrapper
apps:
bitmask-root:
......@@ -252,17 +171,69 @@ apps:
command: usr/sbin/openvpn
launcher:
command: bin/${binaryName} -platform xcb
command-chain: &_command-chain
- bin/graphics-core22-wrapper
- bin/wayland-launch
command: &_command bin/${binaryName}
plugs: &_plugs
- opengl
- wayland
environment: &_environment
# These environment variables are typically needed by Qt applications to ensue the snapped version of
# Qt components are found and used
QT_QPA_PLATFORM: wayland
QT_PLUGIN_PATH: ${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/qt6/plugins/
QT_QPA_PLATFORM_PLUGIN_PATH: ${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/qt6/plugins/platforms/
QML2_IMPORT_PATH: ${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/qt6/qml
daemon:
daemon: simple
restart-delay: 3s
restart-condition: always
command-chain: *_command-chain
command: *_command
plugs: *_plugs
environment: *_environment
# This is one of four snippets that relate to providing the userspace graphics needed by your application.
# You can treat this as "magic" so long as you don't need to make changes.
# On the Mir website there's a lot more detail on [the graphics-core22 Snap interface](https://mir-server.io/docs/the-graphics-core22-snap-interface) and it's use.
plugs:
graphics-core22:
interface: content
target: $SNAP/graphics
default-provider: mesa-core22
environment:
QT_PLUGIN_PATH: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/platforms:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/qml:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/qml/QtQuick/Controls.2/:$SNAP/usr/lib/x86_64-linux-gnu/qt5/plugins:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins/xcbglintegrations
QT_QPA_PLATFORM_PLUGIN_PATH: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/plugins:$SNAP/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms
# QT_STYLE_OVERRIDE: Fusion
QML2_IMPORT_PATH: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/qt5/qml
DISABLE_WAYLAND: 1
LD_LIBRARY_PATH: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/dri
# debug -------------
# QT_OPENGL: software
# QT_DEBUG_PLUGINS: 1
SNAP_DESKTOP_DEBUG: 1
# debug -------------
# Other, generally useful environment settings...
# XDG config
XDG_CACHE_HOME: $SNAP_USER_COMMON/.cache
XDG_CONFIG_HOME: $SNAP_USER_DATA/.config
XDG_CONFIG_DIRS: $SNAP/etc/xdg
XDG_DATA_DIRS: $SNAP/usr/local/share:$SNAP/usr/share
# XKB config
XKB_CONFIG_ROOT: $SNAP/usr/share/X11/xkb
# The `layout` ensures that files can be found by applications where they are expected by the toolkit or application.
layout:
/usr/share/libdrm:
bind: $SNAP/graphics/libdrm
/usr/share/drirc.d:
symlink: $SNAP/graphics/drirc.d
# Other, generally useful paths
/usr/share/fonts:
bind: $SNAP/usr/share/fonts
/usr/share/icons:
bind: $SNAP/usr/share/icons
/usr/share/sounds:
bind: $SNAP/usr/share/sounds
/etc/fonts:
bind: $SNAP/etc/fonts
# GTK
/usr/lib/$CRAFT_ARCH_TRIPLET/gdk-pixbuf-2.0:
bind: $SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/gdk-pixbuf-2.0
/usr/lib/${CRAFT_ARCH_TRIPLET}/gtk-3.0:
bind: $SNAP/usr/lib/${CRAFT_ARCH_TRIPLET}/gtk-3.0
/usr/share/mime:
bind: $SNAP/usr/share/mime
/etc/gtk-3.0:
bind: $SNAP/etc/gtk-3.0