Compare commits
6 Commits
c0a5e1f876
...
59c2046463
Author | SHA1 | Date |
---|---|---|
maximstewart | 59c2046463 | |
maximstewart | 9f85d86a52 | |
maximstewart | 94d1f1376e | |
maximstewart | 37c4c15427 | |
maximstewart | 469fefeb50 | |
maximstewart | 144c110b73 |
|
@ -0,0 +1,203 @@
|
|||
# vim: syntax=config
|
||||
|
||||
|
||||
###########
|
||||
# General #
|
||||
###########
|
||||
|
||||
input-ipc-server=/tmp/mpvsocket # listen for IPC on this socket
|
||||
#load-stats-overlay=no # use local stats.lua
|
||||
#save-position-on-quit # handled by a script
|
||||
|
||||
no-border # no window title bar
|
||||
msg-module # prepend module name to log messages
|
||||
msg-color # color log messages on terminal
|
||||
term-osd-bar # display a progress bar on the terminal
|
||||
use-filedir-conf # look for additional config files in the directory of the opened file
|
||||
#pause # no autoplay
|
||||
keep-open # keep the player open when a file's end is reached
|
||||
autofit-larger=100%x95% # resize window in case it's larger than W%xH% of the screen
|
||||
cursor-autohide-fs-only # don't autohide the cursor in window mode, only fullscreen
|
||||
input-media-keys=no # enable/disable OSX media keys
|
||||
cursor-autohide=1000 # autohide the curser after 1s
|
||||
prefetch-playlist=yes
|
||||
force-seekable=yes
|
||||
|
||||
screenshot-format=png
|
||||
screenshot-png-compression=8
|
||||
screenshot-template='~/Desktop/%F (%P) %n'
|
||||
|
||||
hls-bitrate=max # use max quality for HLS streams
|
||||
|
||||
[ytdl-desktop]
|
||||
profile-desc=cond:is_desktop()
|
||||
ytdl-format=bestvideo[height<=?1080]+bestaudio/best
|
||||
|
||||
[ytdl-laptop]
|
||||
profile-desc=cond:is_laptop()
|
||||
ytdl-format=bestvideo[height<=?1080][fps<=?30][vcodec!=?vp9][protocol!=http_dash_segments]+bestaudio/best
|
||||
|
||||
[default]
|
||||
|
||||
|
||||
#########c
|
||||
# Cache #
|
||||
#########
|
||||
|
||||
# Configure the cache to be really big (multiple GBs)
|
||||
# We have a lot of memory, so why not use it for something
|
||||
|
||||
cache=yes
|
||||
cache-default=4000000 # size in KB
|
||||
cache-backbuffer=250000 # size in KB
|
||||
demuxer-max-bytes=1147483647 # ~1 GiB in bytes
|
||||
|
||||
|
||||
#############
|
||||
# OSD / OSC #
|
||||
#############
|
||||
|
||||
osd-level=1 # enable osd and display --osd-status-msg on interaction
|
||||
osd-duration=2500 # hide the osd after x ms
|
||||
osd-status-msg='${time-pos} / ${duration}${?percent-pos: (${percent-pos}%)}${?frame-drop-count:${!frame-drop-count==0: Dropped: ${frame-drop-count}}}\n${?chapter:Chapter: ${chapter}}'
|
||||
|
||||
osd-font='Source Sans Pro'
|
||||
osd-font-size=32
|
||||
osd-color='#CCFFFFFF' # ARGB format
|
||||
osd-border-color='#DD322640' # ARGB format
|
||||
#osd-shadow-offset=1 # pixel width for osd text and progress bar
|
||||
osd-bar-align-y=0 # progress bar y alignment (-1 top, 0 centered, 1 bottom)
|
||||
osd-border-size=2 # size for osd text and progress bar
|
||||
osd-bar-h=2 # height of osd bar as a fractional percentage of your screen height
|
||||
osd-bar-w=60 # width of " " "
|
||||
|
||||
|
||||
#############
|
||||
# Subtitles #
|
||||
#############
|
||||
|
||||
sub-auto=fuzzy # external subs don't have to match the file name exactly to autoload
|
||||
sub-file-paths-append=ass # search for external subs in these relative subdirectories
|
||||
sub-file-paths-append=srt
|
||||
sub-file-paths-append=sub
|
||||
sub-file-paths-append=subs
|
||||
sub-file-paths-append=subtitles
|
||||
|
||||
demuxer-mkv-subtitle-preroll # try to correctly show embedded subs when seeking
|
||||
embeddedfonts=yes # use embedded fonts for SSA/ASS subs
|
||||
sub-fix-timing=no # do not try to fix gaps (which might make it worse in some cases)
|
||||
sub-ass-force-style=Kerning=yes # allows you to override style parameters of ASS scripts
|
||||
sub-use-margins
|
||||
sub-ass-force-margins
|
||||
|
||||
# the following options only apply to subtitles without own styling (i.e. not ASS but e.g. SRT)
|
||||
sub-font="Source Sans Pro Semibold"
|
||||
sub-font-size=36
|
||||
sub-color="#FFFFFFFF"
|
||||
sub-border-color="#FF262626"
|
||||
sub-border-size=3.2
|
||||
sub-shadow-offset=1
|
||||
sub-shadow-color="#33000000"
|
||||
sub-spacing=0.5
|
||||
|
||||
|
||||
#############
|
||||
# Languages #
|
||||
#############
|
||||
|
||||
slang=enm,en,eng,de,deu,ger # automatically select these subtitles (decreasing priority)
|
||||
alang=ja,jp,jpn,en,eng,de,deu,ger # automatically select these audio tracks (decreasing priority)
|
||||
|
||||
|
||||
#########
|
||||
# Audio #
|
||||
#########
|
||||
|
||||
audio-file-auto=fuzzy # external audio doesn't has to match the file name exactly to autoload
|
||||
audio-pitch-correction=yes # automatically insert scaletempo when playing with higher speed
|
||||
volume-max=200 # maximum volume in %, everything above 100 results in amplification
|
||||
volume=45 # default volume, 100 = unchanged
|
||||
|
||||
|
||||
################
|
||||
# Video Output #
|
||||
################
|
||||
|
||||
# Active VOs (and some other options) are set conditionally
|
||||
# See here for more information: https://github.com/wm4/mpv-scripts/blob/master/auto-profiles.lua
|
||||
# on_battery(), is_laptop() and is_dektop() are my own additional functions imported from scripts/auto-profiles-functions.lua
|
||||
|
||||
# Defaults for all profiles
|
||||
#vo=gpu
|
||||
#gpu-api=opengl
|
||||
tscale=oversample # [sharp] oversample <-> linear (triangle) <-> catmull_rom <-> mitchell <-> gaussian <-> bicubic [smooth]
|
||||
opengl-early-flush=no
|
||||
opengl-pbo=no # "yes" is currently bugged: https://github.com/mpv-player/mpv/issues/4988
|
||||
icc-profile-auto
|
||||
|
||||
|
||||
[high-quality]
|
||||
profile-desc=cond:is_high(get('width', math.huge), get('height', math.huge), get('estimated-vf-fps', math.huge))
|
||||
# hanning with this radius is broken on OSX due to OpenGL driver bug
|
||||
#scale=ewa_hanning
|
||||
#scale-radius=3.2383154841662362
|
||||
scale=ewa_lanczossharp
|
||||
cscale=ewa_lanczossoft
|
||||
dscale=mitchell
|
||||
scale-antiring=0
|
||||
cscale-antiring=0
|
||||
dither-depth=auto
|
||||
correct-downscaling=yes
|
||||
sigmoid-upscaling=yes
|
||||
deband=yes
|
||||
hwdec=no
|
||||
|
||||
[mid-quality]
|
||||
profile-desc=cond:is_mid(get('width', math.huge), get('height', math.huge), get('estimated-vf-fps', math.huge))
|
||||
scale=spline36
|
||||
cscale=spline36
|
||||
dscale=mitchell
|
||||
scale-antiring=1.0
|
||||
cscale-antiring=1.0
|
||||
dither-depth=auto
|
||||
correct-downscaling=yes
|
||||
sigmoid-upscaling=yes
|
||||
deband=yes
|
||||
hwdec=no
|
||||
|
||||
[low-quality]
|
||||
profile-desc=cond:is_low(get('width', math.huge), get('height', math.huge), get('estimated-vf-fps', math.huge))
|
||||
scale=bilinear
|
||||
cscale=bilinear
|
||||
dscale=bilinear
|
||||
scale-antiring=0
|
||||
cscale-antiring=0
|
||||
dither-depth=no
|
||||
correct-downscaling=no
|
||||
sigmoid-upscaling=no
|
||||
deband=no
|
||||
hwdec=no
|
||||
|
||||
[4K]
|
||||
profile-desc=cond:get('width', -math.huge) >= 3840
|
||||
vd-lavc-threads=32
|
||||
|
||||
[4K-inverted]
|
||||
profile-desc=cond:get('width', math.huge) < 3840
|
||||
vd-lavc-threads=0
|
||||
|
||||
[default]
|
||||
|
||||
|
||||
###################################
|
||||
# Protocol Specific Configuration #
|
||||
###################################
|
||||
|
||||
|
||||
[protocol.https]
|
||||
cache=yes
|
||||
user-agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:57.0) Gecko/20100101 Firefox/58.0'
|
||||
|
||||
[protocol.http]
|
||||
cache=yes
|
||||
user-agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:57.0) Gecko/20100101 Firefox/58.0'
|
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 2.9 MiB |
After Width: | Height: | Size: 129 KiB |
After Width: | Height: | Size: 129 KiB |
After Width: | Height: | Size: 129 KiB |
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
|
||||
|
||||
from setproctitle import setproctitle
|
||||
import gi, os, faulthandler, signal, inspect, gi, cairo
|
||||
|
||||
gi.require_version('Gtk', '3.0')
|
||||
|
||||
from gi.repository import Gtk as gtk
|
||||
from gi.repository import Gdk as gdk
|
||||
from gi.repository import GdkPixbuf as gbuf
|
||||
|
||||
|
||||
class SupportMixin:
|
||||
def setFile(self):
|
||||
dialog = gtk.FileChooserDialog(title="Please choose a file", action=gtk.FileChooserAction.OPEN)
|
||||
dialog.add_buttons(gtk.STOCK_CANCEL, gtk.ResponseType.CANCEL, gtk.STOCK_OPEN, gtk.ResponseType.OK)
|
||||
|
||||
response = dialog.run()
|
||||
if response == gtk.ResponseType.OK:
|
||||
self.file = dialog.get_filename()
|
||||
self.setupSurfaceData(self.file)
|
||||
elif response == gtk.ResponseType.CANCEL:
|
||||
pass
|
||||
|
||||
dialog.destroy()
|
||||
|
||||
def setupSurfaceData(self, file):
|
||||
pb = gbuf.Pixbuf.new_from_file(file)
|
||||
if pb:
|
||||
self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, pb.get_width(), pb.get_height())
|
||||
context = cairo.Context(self.surface)
|
||||
|
||||
gdk.cairo_set_source_pixbuf(cr=context, pixbuf=pb, pixbuf_x=0, pixbuf_y=0)
|
||||
context.paint()
|
||||
|
||||
self.drawArea.set_size_request(width=pb.get_width(), height=pb.get_height())
|
||||
self.drawArea.queue_draw()
|
||||
|
||||
|
||||
class Main_Draw_Area(SupportMixin):
|
||||
def __init__(self, _builder):
|
||||
self.surface = None
|
||||
self.file = None
|
||||
self.drawArea = _builder.get_object("drawArea1")
|
||||
|
||||
def setMainFile(self, widget):
|
||||
self.setFile()
|
||||
|
||||
def onDraw1(self, area, context):
|
||||
if self.surface is not None:
|
||||
context.set_source_surface(self.surface, 0.0, 0.0)
|
||||
context.paint()
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class File_Select_Draw_Area(SupportMixin):
|
||||
def __init__(self, _builder):
|
||||
self.surface = None
|
||||
self.file = None
|
||||
self.drawArea = _builder.get_object("drawArea2")
|
||||
|
||||
def setPopupFile(self, widget):
|
||||
self.setFile()
|
||||
|
||||
def onDraw2(self, area, context):
|
||||
if self.surface is not None:
|
||||
context.set_source_surface(self.surface, 0.0, 0.0)
|
||||
context.paint()
|
||||
return False
|
||||
|
||||
|
||||
class Window():
|
||||
def __init__(self):
|
||||
setproctitle('double_draw_areas')
|
||||
SCRIPT_PTH = os.path.dirname(os.path.realpath(__file__)) + "/"
|
||||
GLADE_FILE = "main.glade"
|
||||
self.builder = gtk.Builder()
|
||||
|
||||
self.builder.add_from_file(SCRIPT_PTH + GLADE_FILE)
|
||||
handlers = {}
|
||||
classes = [self, Main_Draw_Area(self.builder), File_Select_Draw_Area(self.builder)]
|
||||
for c in classes:
|
||||
methods = None
|
||||
try:
|
||||
methods = inspect.getmembers(c, predicate=inspect.ismethod)
|
||||
handlers.update(methods)
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
self.builder.connect_signals(handlers)
|
||||
self.fileSelectionPopup = self.builder.get_object("fileSelectionPopup")
|
||||
window = self.builder.get_object("main_window")
|
||||
window.connect("delete_event", gtk.main_quit)
|
||||
window.show()
|
||||
|
||||
def openFileSelectionPopup(self, widget):
|
||||
self.fileSelectionPopup.popup()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
faulthandler.enable() # For better debug info
|
||||
window = Window()
|
||||
gtk.main()
|
|
@ -0,0 +1,364 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkWindow" id="main_window">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="default-width">800</property>
|
||||
<property name="default-height">800</property>
|
||||
<child>
|
||||
<!-- n-columns=10 n-rows=10 -->
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="row-homogeneous">True</property>
|
||||
<property name="column-homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="width">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">9</property>
|
||||
<property name="width">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="height">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">9</property>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="height">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<property name="min-content-width">600</property>
|
||||
<property name="min-content-height">600</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="drawArea1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<signal name="draw" handler="onDraw1" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">3</property>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="width">6</property>
|
||||
<property name="height">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Open</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="setMainFile" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="openFileSelection">
|
||||
<property name="label" translatable="yes">File Selection </property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="openFileSelectionPopup" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="fileSelectionPopup">
|
||||
<property name="width-request">500</property>
|
||||
<property name="height-request">500</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="relative-to">openFileSelection</property>
|
||||
<property name="position">right</property>
|
||||
<child>
|
||||
<!-- n-columns=10 n-rows=10 -->
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="row-homogeneous">True</property>
|
||||
<property name="column-homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="height">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">9</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="height">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="width">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">9</property>
|
||||
<property name="width">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="drawArea2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<signal name="draw" handler="onDraw2" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">3</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="width">6</property>
|
||||
<property name="height">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Select File</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="setPopupFile" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="width">2</property>
|
||||
<property name="height">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
After Width: | Height: | Size: 3.5 MiB |
After Width: | Height: | Size: 337 KiB |
After Width: | Height: | Size: 2.7 MiB |
|
@ -0,0 +1,401 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# https://github.com/Nyr/openvpn-install
|
||||
#
|
||||
# Copyright (c) 2013 Nyr. Released under the MIT License.
|
||||
|
||||
|
||||
# Detect Debian users running the script with "sh" instead of bash
|
||||
if readlink /proc/$$/exe | grep -q "dash"; then
|
||||
echo "This script needs to be run with bash, not sh"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ "$EUID" -ne 0 ]]; then
|
||||
echo "Sorry, you need to run this as root"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ ! -e /dev/net/tun ]]; then
|
||||
echo "The TUN device is not available
|
||||
You need to enable TUN before running this script"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ -e /etc/debian_version ]]; then
|
||||
OS=debian
|
||||
GROUPNAME=nogroup
|
||||
RCLOCAL='/etc/rc.local'
|
||||
elif [[ -e /etc/centos-release || -e /etc/redhat-release ]]; then
|
||||
OS=centos
|
||||
GROUPNAME=nobody
|
||||
RCLOCAL='/etc/rc.d/rc.local'
|
||||
else
|
||||
echo "Looks like you aren't running this installer on Debian, Ubuntu or CentOS"
|
||||
exit
|
||||
fi
|
||||
|
||||
newclient () {
|
||||
# Generates the custom client.ovpn
|
||||
cp /etc/openvpn/client-common.txt ~/$1.ovpn
|
||||
echo "<ca>" >> ~/$1.ovpn
|
||||
cat /etc/openvpn/easy-rsa/pki/ca.crt >> ~/$1.ovpn
|
||||
echo "</ca>" >> ~/$1.ovpn
|
||||
echo "<cert>" >> ~/$1.ovpn
|
||||
cat /etc/openvpn/easy-rsa/pki/issued/$1.crt >> ~/$1.ovpn
|
||||
echo "</cert>" >> ~/$1.ovpn
|
||||
echo "<key>" >> ~/$1.ovpn
|
||||
cat /etc/openvpn/easy-rsa/pki/private/$1.key >> ~/$1.ovpn
|
||||
echo "</key>" >> ~/$1.ovpn
|
||||
echo "<tls-auth>" >> ~/$1.ovpn
|
||||
cat /etc/openvpn/ta.key >> ~/$1.ovpn
|
||||
echo "</tls-auth>" >> ~/$1.ovpn
|
||||
}
|
||||
|
||||
if [[ -e /etc/openvpn/server.conf ]]; then
|
||||
while :
|
||||
do
|
||||
clear
|
||||
echo "Looks like OpenVPN is already installed."
|
||||
echo
|
||||
echo "What do you want to do?"
|
||||
echo " 1) Add a new user"
|
||||
echo " 2) Revoke an existing user"
|
||||
echo " 3) Remove OpenVPN"
|
||||
echo " 4) Exit"
|
||||
read -p "Select an option [1-4]: " option
|
||||
case $option in
|
||||
1)
|
||||
echo
|
||||
echo "Tell me a name for the client certificate."
|
||||
echo "Please, use one word only, no special characters."
|
||||
read -p "Client name: " -e CLIENT
|
||||
cd /etc/openvpn/easy-rsa/
|
||||
./easyrsa build-client-full $CLIENT nopass
|
||||
# Generates the custom client.ovpn
|
||||
newclient "$CLIENT"
|
||||
echo
|
||||
echo "Client $CLIENT added, configuration is available at:" ~/"$CLIENT.ovpn"
|
||||
exit
|
||||
;;
|
||||
2)
|
||||
# This option could be documented a bit better and maybe even be simplified
|
||||
# ...but what can I say, I want some sleep too
|
||||
NUMBEROFCLIENTS=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep -c "^V")
|
||||
if [[ "$NUMBEROFCLIENTS" = '0' ]]; then
|
||||
echo
|
||||
echo "You have no existing clients!"
|
||||
exit
|
||||
fi
|
||||
echo
|
||||
echo "Select the existing client certificate you want to revoke:"
|
||||
tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
|
||||
if [[ "$NUMBEROFCLIENTS" = '1' ]]; then
|
||||
read -p "Select one client [1]: " CLIENTNUMBER
|
||||
else
|
||||
read -p "Select one client [1-$NUMBEROFCLIENTS]: " CLIENTNUMBER
|
||||
fi
|
||||
CLIENT=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$CLIENTNUMBER"p)
|
||||
echo
|
||||
read -p "Do you really want to revoke access for client $CLIENT? [y/N]: " -e REVOKE
|
||||
if [[ "$REVOKE" = 'y' || "$REVOKE" = 'Y' ]]; then
|
||||
cd /etc/openvpn/easy-rsa/
|
||||
./easyrsa --batch revoke $CLIENT
|
||||
EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
|
||||
rm -f pki/reqs/$CLIENT.req
|
||||
rm -f pki/private/$CLIENT.key
|
||||
rm -f pki/issued/$CLIENT.crt
|
||||
rm -f /etc/openvpn/crl.pem
|
||||
cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
|
||||
# CRL is read with each client connection, when OpenVPN is dropped to nobody
|
||||
chown nobody:$GROUPNAME /etc/openvpn/crl.pem
|
||||
echo
|
||||
echo "Certificate for client $CLIENT revoked!"
|
||||
else
|
||||
echo
|
||||
echo "Certificate revocation for client $CLIENT aborted!"
|
||||
fi
|
||||
exit
|
||||
;;
|
||||
3)
|
||||
echo
|
||||
read -p "Do you really want to remove OpenVPN? [y/N]: " -e REMOVE
|
||||
if [[ "$REMOVE" = 'y' || "$REMOVE" = 'Y' ]]; then
|
||||
PORT=$(grep '^port ' /etc/openvpn/server.conf | cut -d " " -f 2)
|
||||
PROTOCOL=$(grep '^proto ' /etc/openvpn/server.conf | cut -d " " -f 2)
|
||||
if pgrep firewalld; then
|
||||
IP=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24 -j SNAT --to ' | cut -d " " -f 10)
|
||||
# Using both permanent and not permanent rules to avoid a firewalld reload.
|
||||
firewall-cmd --zone=public --remove-port=$PORT/$PROTOCOL
|
||||
firewall-cmd --zone=trusted --remove-source=10.8.0.0/24
|
||||
firewall-cmd --permanent --zone=public --remove-port=$PORT/$PROTOCOL
|
||||
firewall-cmd --permanent --zone=trusted --remove-source=10.8.0.0/24
|
||||
firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
|
||||
firewall-cmd --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
|
||||
else
|
||||
IP=$(grep 'iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to ' $RCLOCAL | cut -d " " -f 14)
|
||||
iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
|
||||
sed -i '/iptables -t nat -A POSTROUTING -s 10.8.0.0\/24 ! -d 10.8.0.0\/24 -j SNAT --to /d' $RCLOCAL
|
||||
if iptables -L -n | grep -qE '^ACCEPT'; then
|
||||
iptables -D INPUT -p $PROTOCOL --dport $PORT -j ACCEPT
|
||||
iptables -D FORWARD -s 10.8.0.0/24 -j ACCEPT
|
||||
iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
sed -i "/iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT/d" $RCLOCAL
|
||||
sed -i "/iptables -I FORWARD -s 10.8.0.0\/24 -j ACCEPT/d" $RCLOCAL
|
||||
sed -i "/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT/d" $RCLOCAL
|
||||
fi
|
||||
fi
|
||||
if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$PORT" != '1194' ]]; then
|
||||
semanage port -d -t openvpn_port_t -p $PROTOCOL $PORT
|
||||
fi
|
||||
if [[ "$OS" = 'debian' ]]; then
|
||||
apt-get remove --purge -y openvpn
|
||||
else
|
||||
yum remove openvpn -y
|
||||
fi
|
||||
rm -rf /etc/openvpn
|
||||
echo
|
||||
echo "OpenVPN removed!"
|
||||
else
|
||||
echo
|
||||
echo "Removal aborted!"
|
||||
fi
|
||||
exit
|
||||
;;
|
||||
4) exit;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
clear
|
||||
echo 'Welcome to this OpenVPN "road warrior" installer!'
|
||||
echo
|
||||
# OpenVPN setup and first user creation
|
||||
echo "I need to ask you a few questions before starting the setup."
|
||||
echo "You can leave the default options and just press enter if you are ok with them."
|
||||
echo
|
||||
echo "First, provide the IPv4 address of the network interface you want OpenVPN"
|
||||
echo "listening to."
|
||||
# Autodetect IP address and pre-fill for the user
|
||||
IP=$(ip addr | grep 'inet' | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)
|
||||
read -p "IP address: " -e -i $IP IP
|
||||
# If $IP is a private IP address, the server must be behind NAT
|
||||
if echo "$IP" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then
|
||||
echo
|
||||
echo "This server is behind NAT. What is the public IPv4 address or hostname?"
|
||||
read -p "Public IP address / hostname: " -e PUBLICIP
|
||||
fi
|
||||
echo
|
||||
echo "Which protocol do you want for OpenVPN connections?"
|
||||
echo " 1) UDP (recommended)"
|
||||
echo " 2) TCP"
|
||||
read -p "Protocol [1-2]: " -e -i 1 PROTOCOL
|
||||
case $PROTOCOL in
|
||||
1)
|
||||
PROTOCOL=udp
|
||||
;;
|
||||
2)
|
||||
PROTOCOL=tcp
|
||||
;;
|
||||
esac
|
||||
echo
|
||||
echo "What port do you want OpenVPN listening to?"
|
||||
read -p "Port: " -e -i 1194 PORT
|
||||
echo
|
||||
echo "Which DNS do you want to use with the VPN?"
|
||||
echo " 1) Current system resolvers"
|
||||
echo " 2) 1.1.1.1"
|
||||
echo " 3) Google"
|
||||
echo " 4) OpenDNS"
|
||||
echo " 5) Verisign"
|
||||
read -p "DNS [1-5]: " -e -i 1 DNS
|
||||
echo
|
||||
echo "Finally, tell me your name for the client certificate."
|
||||
echo "Please, use one word only, no special characters."
|
||||
read -p "Client name: " -e -i client CLIENT
|
||||
echo
|
||||
echo "Okay, that was all I needed. We are ready to set up your OpenVPN server now."
|
||||
read -n1 -r -p "Press any key to continue..."
|
||||
if [[ "$OS" = 'debian' ]]; then
|
||||
apt-get update
|
||||
apt-get install openvpn iptables openssl ca-certificates -y
|
||||
else
|
||||
# Else, the distro is CentOS
|
||||
yum install epel-release -y
|
||||
yum install openvpn iptables openssl ca-certificates -y
|
||||
fi
|
||||
# Get easy-rsa
|
||||
EASYRSAURL='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.4/EasyRSA-3.0.4.tgz'
|
||||
wget -O ~/easyrsa.tgz "$EASYRSAURL" 2>/dev/null || curl -Lo ~/easyrsa.tgz "$EASYRSAURL"
|
||||
tar xzf ~/easyrsa.tgz -C ~/
|
||||
mv ~/EasyRSA-3.0.4/ /etc/openvpn/
|
||||
mv /etc/openvpn/EasyRSA-3.0.4/ /etc/openvpn/easy-rsa/
|
||||
chown -R root:root /etc/openvpn/easy-rsa/
|
||||
rm -f ~/easyrsa.tgz
|
||||
cd /etc/openvpn/easy-rsa/
|
||||
# Create the PKI, set up the CA, the DH params and the server + client certificates
|
||||
./easyrsa init-pki
|
||||
./easyrsa --batch build-ca nopass
|
||||
./easyrsa gen-dh
|
||||
./easyrsa build-server-full server nopass
|
||||
./easyrsa build-client-full $CLIENT nopass
|
||||
EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
|
||||
# Move the stuff we need
|
||||
cp pki/ca.crt pki/private/ca.key pki/dh.pem pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn
|
||||
# CRL is read with each client connection, when OpenVPN is dropped to nobody
|
||||
chown nobody:$GROUPNAME /etc/openvpn/crl.pem
|
||||
# Generate key for tls-auth
|
||||
openvpn --genkey --secret /etc/openvpn/ta.key
|
||||
# Generate server.conf
|
||||
echo "port $PORT
|
||||
proto $PROTOCOL
|
||||
dev tun
|
||||
sndbuf 0
|
||||
rcvbuf 0
|
||||
ca ca.crt
|
||||
cert server.crt
|
||||
key server.key
|
||||
dh dh.pem
|
||||
auth SHA512
|
||||
tls-auth ta.key 0
|
||||
topology subnet
|
||||
server 10.8.0.0 255.255.255.0
|
||||
ifconfig-pool-persist ipp.txt" > /etc/openvpn/server.conf
|
||||
echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf
|
||||
# DNS
|
||||
case $DNS in
|
||||
1)
|
||||
# Locate the proper resolv.conf
|
||||
# Needed for systems running systemd-resolved
|
||||
if grep -q "127.0.0.53" "/etc/resolv.conf"; then
|
||||
RESOLVCONF='/run/systemd/resolve/resolv.conf'
|
||||
else
|
||||
RESOLVCONF='/etc/resolv.conf'
|
||||
fi
|
||||
# Obtain the resolvers from resolv.conf and use them for OpenVPN
|
||||
grep -v '#' $RESOLVCONF | grep 'nameserver' | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read line; do
|
||||
echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server.conf
|
||||
done
|
||||
;;
|
||||
2)
|
||||
echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server.conf
|
||||
echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server.conf
|
||||
;;
|
||||
3)
|
||||
echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server.conf
|
||||
echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server.conf
|
||||
;;
|
||||
4)
|
||||
echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server.conf
|
||||
echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server.conf
|
||||
;;
|
||||
5)
|
||||
echo 'push "dhcp-option DNS 64.6.64.6"' >> /etc/openvpn/server.conf
|
||||
echo 'push "dhcp-option DNS 64.6.65.6"' >> /etc/openvpn/server.conf
|
||||
;;
|
||||
esac
|
||||
echo "keepalive 10 120
|
||||
cipher AES-256-CBC
|
||||
comp-lzo
|
||||
user nobody
|
||||
group $GROUPNAME
|
||||
persist-key
|
||||
persist-tun
|
||||
status openvpn-status.log
|
||||
verb 3
|
||||
crl-verify crl.pem" >> /etc/openvpn/server.conf
|
||||
# Enable net.ipv4.ip_forward for the system
|
||||
sed -i '/\<net.ipv4.ip_forward\>/c\net.ipv4.ip_forward=1' /etc/sysctl.conf
|
||||
if ! grep -q "\<net.ipv4.ip_forward\>" /etc/sysctl.conf; then
|
||||
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
|
||||
fi
|
||||
# Avoid an unneeded reboot
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
if pgrep firewalld; then
|
||||
# Using both permanent and not permanent rules to avoid a firewalld
|
||||
# reload.
|
||||
# We don't use --add-service=openvpn because that would only work with
|
||||
# the default port and protocol.
|
||||
firewall-cmd --zone=public --add-port=$PORT/$PROTOCOL
|
||||
firewall-cmd --zone=trusted --add-source=10.8.0.0/24
|
||||
firewall-cmd --permanent --zone=public --add-port=$PORT/$PROTOCOL
|
||||
firewall-cmd --permanent --zone=trusted --add-source=10.8.0.0/24
|
||||
# Set NAT for the VPN subnet
|
||||
firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
|
||||
else
|
||||
# Needed to use rc.local with some systemd distros
|
||||
if [[ "$OS" = 'debian' && ! -e $RCLOCAL ]]; then
|
||||
echo '#!/bin/sh -e
|
||||
exit 0' > $RCLOCAL
|
||||
fi
|
||||
chmod +x $RCLOCAL
|
||||
# Set NAT for the VPN subnet
|
||||
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
|
||||
sed -i "1 a\iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP" $RCLOCAL
|
||||
if iptables -L -n | grep -qE '^(REJECT|DROP)'; then
|
||||
# If iptables has at least one REJECT rule, we asume this is needed.
|
||||
# Not the best approach but I can't think of other and this shouldn't
|
||||
# cause problems.
|
||||
iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT
|
||||
iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
|
||||
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
sed -i "1 a\iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT" $RCLOCAL
|
||||
sed -i "1 a\iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT" $RCLOCAL
|
||||
sed -i "1 a\iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" $RCLOCAL
|
||||
fi
|
||||
fi
|
||||
# If SELinux is enabled and a custom port was selected, we need this
|
||||
if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$PORT" != '1194' ]]; then
|
||||
# Install semanage if not already present
|
||||
if ! hash semanage 2>/dev/null; then
|
||||
yum install policycoreutils-python -y
|
||||
fi
|
||||
semanage port -a -t openvpn_port_t -p $PROTOCOL $PORT
|
||||
fi
|
||||
# And finally, restart OpenVPN
|
||||
if [[ "$OS" = 'debian' ]]; then
|
||||
# Little hack to check for systemd
|
||||
if pgrep systemd-journal; then
|
||||
systemctl restart openvpn@server.service
|
||||
else
|
||||
/etc/init.d/openvpn restart
|
||||
fi
|
||||
else
|
||||
if pgrep systemd-journal; then
|
||||
systemctl restart openvpn@server.service
|
||||
systemctl enable openvpn@server.service
|
||||
else
|
||||
service openvpn restart
|
||||
chkconfig openvpn on
|
||||
fi
|
||||
fi
|
||||
# If the server is behind a NAT, use the correct IP address
|
||||
if [[ "$PUBLICIP" != "" ]]; then
|
||||
IP=$PUBLICIP
|
||||
fi
|
||||
# client-common.txt is created so we have a template to add further users later
|
||||
echo "client
|
||||
dev tun
|
||||
proto $PROTOCOL
|
||||
sndbuf 0
|
||||
rcvbuf 0
|
||||
remote $IP $PORT
|
||||
resolv-retry infinite
|
||||
nobind
|
||||
persist-key
|
||||
persist-tun
|
||||
remote-cert-tls server
|
||||
auth SHA512
|
||||
cipher AES-256-CBC
|
||||
comp-lzo
|
||||
setenv opt block-outside-dns
|
||||
key-direction 1
|
||||
verb 3" > /etc/openvpn/client-common.txt
|
||||
# Generates the custom client.ovpn
|
||||
newclient "$CLIENT"
|
||||
echo
|
||||
echo "Finished!"
|
||||
echo
|
||||
echo "Your client configuration is available at:" ~/"$CLIENT.ovpn"
|
||||
echo "If you want to add more clients, you simply need to run this script again!"
|
||||
fi
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
|
||||
# . CONFIG.sh
|
||||
|
||||
# set -o xtrace ## To debug scripts
|
||||
# set -o errexit ## To exit on error
|
||||
# set -o errunset ## To exit if a variable is referenced but not set
|
||||
|
||||
|
||||
function main() {
|
||||
SCRIPTPATH="$( cd "$(dirname "")" >/dev/null 2>&1 ; pwd -P )"
|
||||
cd "${SCRIPTPATH}"
|
||||
echo "Working Dir: " $(pwd)
|
||||
|
||||
sudo apt-get purge -y docker-engine docker docker.io docker-ce
|
||||
sudo apt-get autoremove -y --purge docker-engine docker docker.io docker-ce
|
||||
sudo umount /var/lib/docker/
|
||||
sudo rm -rf /var/lib/docker /etc/docker
|
||||
sudo rm /etc/apparmor.d/docker
|
||||
sudo groupdel docker
|
||||
sudo rm -rf /var/run/docker.sock
|
||||
sudo rm -rf /usr/bin/docker-compose
|
||||
}
|
||||
main $@;
|
|
@ -0,0 +1,30 @@
|
|||
# Passthrough Helper for Manjaro
|
||||
|
||||
Run this script using su instead of sudo. The ">" redirects of echo will not work otherwise.
|
||||
|
||||
|
||||
# Edit /etc/default/grub
|
||||
|
||||
intel_iommu=on (or) amd_iommu=on\
|
||||
rd.driver.pre=vfio-pci\
|
||||
kvm.ignore_msrs=1
|
||||
|
||||
|
||||
# Edit /etc/mkinitcpio.conf
|
||||
|
||||
MODULES="vfio_pci vfio vfio_iommu_type1 vfio_virqfd"\
|
||||
FILES="/usr/bin/vfio-pci-override.sh"\
|
||||
Hooks="... vfio ...."
|
||||
|
||||
|
||||
# Tutorial
|
||||
|
||||
* https://www.youtube.com/watch?v=QlGx0XvWuag
|
||||
|
||||
# "Error 43: Driver failed to load" on Nvidia GPUs passed to Windows VMs
|
||||
* https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF#%22Error_43:_Driver_failed_to_load%22_on_Nvidia_GPUs_passed_to_Windows_VMs
|
||||
|
||||
# Sources
|
||||
|
||||
* https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF#Using_identical_guest_and_host_GPUs
|
||||
* https://forum.manjaro.org/t/virt-manager-fails-to-detect-ovmf-uefi-firmware/110072
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
|
||||
# . CONFIG.sh
|
||||
|
||||
# set -o xtrace ## To debug scripts
|
||||
# set -o errexit ## To exit on error
|
||||
# set -o errunset ## To exit if a variable is referenced but not set
|
||||
|
||||
|
||||
function main() {
|
||||
SCRIPTPATH="$( cd "$(dirname "")" >/dev/null 2>&1 ; pwd -P )"
|
||||
cd "${SCRIPTPATH}"
|
||||
echo "Working Dir: " $(pwd)
|
||||
|
||||
shopt -s nullglob
|
||||
for d in /sys/kernel/iommu_groups/*/devices/*; do
|
||||
n=${d#*/iommu_groups/*}; n=${n%%/*}
|
||||
printf 'IOMMU Group %s ' "$n"
|
||||
lspci -nns "${d##*/}"
|
||||
done;
|
||||
}
|
||||
main $@;
|
|
@ -0,0 +1,54 @@
|
|||
# Sources:
|
||||
# https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF#Using_identical_guest_and_host_GPUs
|
||||
# https://forum.manjaro.org/t/virt-manager-fails-to-detect-ovmf-uefi-firmware/110072
|
||||
|
||||
VERSION=`lsb_release -r | cut -d ' ' -f 2 | cut -d '.' -f 1`
|
||||
|
||||
# Backup files
|
||||
|
||||
mkdir Backup
|
||||
chmod +x uninstall.sh
|
||||
|
||||
cp /etc/default/grub Backup
|
||||
cp /etc/mkinitcpio.conf Backup
|
||||
|
||||
# Edit grub amd_iommu=on or intel_iommu=on rd.driver.pre=vfio-pci kvm.ignore_msrs=1
|
||||
|
||||
nano /etc/default/grub
|
||||
update-grub
|
||||
|
||||
# Install required packages
|
||||
|
||||
pacman -S vim qemu virt-manager ovmf dnsmasq ebtables iptables
|
||||
|
||||
# Allow libvirt to autostart
|
||||
|
||||
systemctl enable libvirtd.service
|
||||
|
||||
# Copy necessary files
|
||||
|
||||
cp vfio-pci-override.sh /usr/bin/vfio-pci-override.sh
|
||||
chmod +x /usr/bin/vfio-pci-override.sh
|
||||
cp vfio-install /etc/initcpio/install/vfio
|
||||
cp vfio-hooks /etc/initcpio/hooks/vfio
|
||||
cp vfio.conf /etc/modprobe.d/
|
||||
|
||||
# Edit mkinitcpio.conf
|
||||
|
||||
# MODULES="vfio_pci vfio vfio_iommu_type1 vfio_virqfd"
|
||||
# FILES="/usr/bin/vfio-pci-override.sh"
|
||||
# HOOKS="... vfio ...."
|
||||
|
||||
nano /etc/mkinitcpio.conf
|
||||
mkinitcpio -P
|
||||
|
||||
# Workaround libvirt bug in previous versions of Manjaro:
|
||||
# https://forum.manjaro.org/t/virt-manager-fails-to-detect-ovmf-uefi-firmware/110072
|
||||
|
||||
if [ $VERSION -lt 20 ]
|
||||
then
|
||||
echo 'nvram = [ "/usr/share/ovmf/x64/OVMF_CODE.fd:/usr/share/ovmf/x64/OVMF_VARS.fd" ]' >> /etc/libvirt/qemu.conf
|
||||
mkdir -p /etc/qemu/firmware
|
||||
sed 's#qemu/edk2-x86_64-code.fd#ovmf/x64/OVMF_CODE.fd#;s#qemu/edk2-i386-vars.fd#ovmf/x64/OVMF_VARS.fd#' < /usr/share/qemu/firmware/60-edk2-x86_64.json > /etc/qemu/firmware/10-ovmf-workaround.json
|
||||
systemctl restart libvirtd
|
||||
fi
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/bash
|
||||
|
||||
# . CONFIG.sh
|
||||
|
||||
# set -o xtrace ## To debug scripts
|
||||
# set -o errexit ## To exit on error
|
||||
# set -o errunset ## To exit if a variable is referenced but not set
|
||||
|
||||
|
||||
function main() {
|
||||
SCRIPTPATH="$( cd "$(dirname "")" >/dev/null 2>&1 ; pwd -P )"
|
||||
cd "${SCRIPTPATH}"
|
||||
echo "Working Dir: " $(pwd)
|
||||
|
||||
|
||||
rm /usr/bin/vfio-pci-override.sh
|
||||
rm /etc/initcpio/install/vfio
|
||||
rm /etc/initcpio/hooks/vfio
|
||||
rm /etc/modprobe.d/vfio.conf
|
||||
|
||||
|
||||
if [ -a Backup/grub ]
|
||||
then
|
||||
rm /etc/default/grub
|
||||
cp Backup/grub /etc/default/
|
||||
fi
|
||||
|
||||
if [ -a Backup/mkinitcpio.conf ]
|
||||
then
|
||||
rm /etc/mkinitcpio.conf
|
||||
cp Backup/mkinitcpio.conf /etc/
|
||||
fi
|
||||
|
||||
mkinitcpio -P
|
||||
}
|
||||
main $@;
|
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/bash
|
||||
|
||||
run_hook() {
|
||||
msg ":: Triggering vfio-pci override"
|
||||
/bin/sh /usr/bin/vfio-pci-override.sh
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
# . CONFIG.sh
|
||||
|
||||
# set -o xtrace ## To debug scripts
|
||||
# set -o errexit ## To exit on error
|
||||
# set -o errunset ## To exit if a variable is referenced but not set
|
||||
|
||||
|
||||
build() {
|
||||
add_file /usr/bin/vfio-pci-override.sh
|
||||
add_runscript
|
||||
}
|
||||
|
||||
function main() {
|
||||
SCRIPTPATH="$( cd "$(dirname "")" >/dev/null 2>&1 ; pwd -P )"
|
||||
cd "${SCRIPTPATH}"
|
||||
echo "Working Dir: " $(pwd)
|
||||
|
||||
build
|
||||
|
||||
}
|
||||
main $@;
|
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
|
||||
# . CONFIG.sh
|
||||
|
||||
# set -o xtrace ## To debug scripts
|
||||
# set -o errexit ## To exit on error
|
||||
# set -o errunset ## To exit if a variable is referenced but not set
|
||||
|
||||
|
||||
function main() {
|
||||
SCRIPTPATH="$( cd "$(dirname "")" >/dev/null 2>&1 ; pwd -P )"
|
||||
cd "${SCRIPTPATH}"
|
||||
echo "Working Dir: " $(pwd)
|
||||
|
||||
|
||||
for i in /sys/bus/pci/devices/*/boot_vga; do
|
||||
if [ $(cat "$i") -eq 0 ]; then
|
||||
GPU="${i%/boot_vga}"
|
||||
AUDIO="$(echo "$GPU" | sed -e "s/0$/1/")"
|
||||
echo "vfio-pci" > "$GPU/driver_override"
|
||||
if [ -d "$AUDIO" ]; then
|
||||
echo "vfio-pci" > "$AUDIO/driver_override"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
modprobe -i vfio-pci
|
||||
}
|
||||
main $@;
|
|
@ -0,0 +1,2 @@
|
|||
install vfio-pci /usr/bin/vfio-pci-override.sh
|
||||
options vfio-pci disable_vga=1 allow_unsafe_interrupts=1
|