Merge branch 'fvs'
This commit is contained in:
commit
92bacc4dd3
71 changed files with 4036 additions and 0 deletions
152
inventory.yml
Normal file
152
inventory.yml
Normal file
|
@ -0,0 +1,152 @@
|
|||
$ANSIBLE_VAULT;1.1;AES256
|
||||
63633264306266356564663836343363656536353265653630623231313232316232373364396234
|
||||
3236316538656536366265323139396261613363653261620a336663633534646530613832646330
|
||||
37636232373730363966333835333935346534373737373366333137393336343333386638373236
|
||||
3761336362363136320a313937373361636337613464383266643763356436623163353164373133
|
||||
66653337346637633231663433653465353963656561633037633131643931363439323737303636
|
||||
37313630326337313333633632343232373562363662396161343866393031383564383239626461
|
||||
35316334333464393064643534626166333264663932316533303963343038653162656232656165
|
||||
33346162393633633736623532386333653464646335626236356466343439633130653836623462
|
||||
34613337623034313834663231343830623836313037313435306633356131326235346364643234
|
||||
65646361336234343937653139303034333438626238366531656230653639373636346565643035
|
||||
65306130386331643037633165613635393433653537333238393365343736623932363432663166
|
||||
36376266313936393931366333303863353033643962303861393536383966343932373233356234
|
||||
64663834663965373038333265616532313161656337613035393736653864393562656630326561
|
||||
66343634383139386133326463633333313164303638313636663361373036396235636332323563
|
||||
31383337636535313139636661306430396335323237653364333838616434363931333861656262
|
||||
35366431646161396234666135343663343266626538363833356666613932303766373238363030
|
||||
64353666363662633836383135313738376235653565323039323962326665323334303731393535
|
||||
35303161636133376631386437626432363463383536343530396533316330393537643036346438
|
||||
34373939373938356466363261643936323964313232313331623237643564326239353861666636
|
||||
31363462336137373365333366383635303639643263303633386637303839363531336133353035
|
||||
66643039313764353935346133396233373735626163383734333736383062663038643464323137
|
||||
30613239393864333365663331313634373338616238303735646532386135336664623635373934
|
||||
34633366303736316438613733316230343039373434653565313631623931646363333139363332
|
||||
66353934396632613330313061336336626531656334633237633536613138393938353364623137
|
||||
34636231643565316435356334663736326463643131393135636366373338326233636564326165
|
||||
31646632326430353036363163303839336638393962373665346237373831393639376231396362
|
||||
38366438656236646436653634356235386238366233666433656161316636643035353165373837
|
||||
30653036346236306162626536393937653235306236313036633135653139656261666361316336
|
||||
66333835343735333937396362353330383139663635386236373531653837383231356535326330
|
||||
64323735383833306463636461373061376133366261356166626466656365663730383133353062
|
||||
35356136623464656662613438313535316466323538313438313963383532616232336564346534
|
||||
64333736316238393232623763306539373034366566306561336161336630613133633762636131
|
||||
34653565353031373436666363613164343964626164366537646438363965396366623765383333
|
||||
39656630383564623735666663643836363963356563303137343064373434343336663536353562
|
||||
30636165623032343136363534373761626638346432323661653730633264323837356163656132
|
||||
66323533316130356364353536303536613365663536346431306634623938613531373465323738
|
||||
33336132663431613338653432613863323665393532346130313332316366633439323664363361
|
||||
61323233303732393637303366336336626638353931663365326266386632666235343164623336
|
||||
65653861353133353661646463383133613733653561333136656665333338636331616262346661
|
||||
66383862323664626632613865663933313338633839313864303366306631613565633734353564
|
||||
38333137633933323538313632393233373836653365333531356336616265396163353365356162
|
||||
66636637646436343834313165363830346339636532343362333133666437323862636439323438
|
||||
39363934623766666464623838396465323539366433653334636365653665356237373235646661
|
||||
63316135626430363637383637363366313563326165393263393539353738313936373365346364
|
||||
62393931353138656633343933313337306266623834653038383437313238643530333130623666
|
||||
37653532333966666564343131316463383836373831393964333664653538616662383733623462
|
||||
31393131666662323236623838343630316434303961323663346262656538313464393564323132
|
||||
39623037323334613632666536366363306139646431646465376535393331333366333537343561
|
||||
66333862353036393930623632313737333062363464353437663966313438636261306165353032
|
||||
32306533363463316661653334306261336236323366353037353461613632633934333734373038
|
||||
37356230613336353938633562343632633031616635343461316333373062646137396163653235
|
||||
65653661386637376330313438323630353432353064383263626339333262363566366633613531
|
||||
66636237363265313266323038376163356437376532656362626436366235393335646165323061
|
||||
61663162313463613431393762633165653035343061333035333439616165646237356633323631
|
||||
65333861663236633064646563346233653231656430623564666265363834633635336163313864
|
||||
39646538613164393161306137393065623935643937393935313438363434623538373963663461
|
||||
39636530373739306333346132636533633861363530613437663632303963336634376639366134
|
||||
31323032393135336136636338366634393236303334633664343865613839663966373339373239
|
||||
61643765393539626337303264373133366265643438333935666633343738653761626437323861
|
||||
38633030653931313762333764316134393566306435303338623832653035393766663539663164
|
||||
64643136656338343334396234363139363337323033333163323261356431356362636435363838
|
||||
64333866313031333937353034376337346631343338626364343034616635633138313039613464
|
||||
33336439356438616234306666646132623230646161373938656239323134653435663734653235
|
||||
64646338343161363364316639336538646439313939326337346339376466666136333165636161
|
||||
64393732313538373334363431363836626364643834333265653135653035636330656464613731
|
||||
36316266316430336166393564306462363232336335626335616165313734633466636534353035
|
||||
37626637633534656235363530633866633062626537383935313763373562633737313032643462
|
||||
61353561366639306437626332643633626463313663366561646331373735393032616332326562
|
||||
36626266316236363930616662636134623865356632303465316266616663353039616261396663
|
||||
34373037623763393263316166343131643531663134616165386636653562336135346333326461
|
||||
39623964656137323439316166666132616561666235633439326464383937653738336435646134
|
||||
64383661363962333838376135323864633234386662643864336132343231366266363632313666
|
||||
31356339633938316636616537633335333564396631336238383063383164393238656438646131
|
||||
31373164313062623930636438346437623736353830396533343730366162343164393661396263
|
||||
63383837633335366534343137663634646631366234656365383235353532626163393537376537
|
||||
37643661666464303133313362366230313132363738643765613735613462333861633736643664
|
||||
38303537303338626139323566306536616236353563613862323435636165373434316432663864
|
||||
39373033326134626530663932623230396531636433346432653262666430653866656330613861
|
||||
64646265363562623663353532616663383830383633366462323235383966383263396535363536
|
||||
30633266386339656230326365303330376138313432653132323138333863663961613538623566
|
||||
62636565613130633166656639653264376461663737356162336331313834613662353430656431
|
||||
35313237633837623562396539623336313562313765383035373036333233356461366336383838
|
||||
65616164623762303033633130636364666630633465633435616666313031343863386261373033
|
||||
39623638313761393434333431646638363062303437373765666435386531343339323862666132
|
||||
38666635363431613530313766386165633032643836663861653434656231383333666633643266
|
||||
32333336383334303763323237653934313032643261326233376335616230386234346161353431
|
||||
63643733643634313133336332663933656363393861633831346261353334376464633562326534
|
||||
31663066656130363965656361626464613463323764383036623063386166653839366637376135
|
||||
34646466313836353234383762376165356439626532646430313730326166313839356263633966
|
||||
39643731613363613564356337653931626666363337356138333335393463393865666636393532
|
||||
33353366633465303765373936316334633331323930653235313231343039616238663433613365
|
||||
31373866666466363965346637656435383433626563313330316132376364366532316331343534
|
||||
32353462646536343538346130383139663334313331323935396537313835366161613539653164
|
||||
38666265306664623666396530383464653661356562613037323362303361323537326239323661
|
||||
66383230386437656132653966333062343536623861373461326333646266366430613563306436
|
||||
32623132303966323638643639343537643135396566323630313038636465353830636439343465
|
||||
34333136613435653037303437646439623035643539623663633561616137656138373063653662
|
||||
35643830613235663931386634626463333331313864666662313534626464663635616437313061
|
||||
66373039396333336639623637353839656333386635363733636636306132333130643131656438
|
||||
64333561323464333631356465393665613635356265343764346531613538633137366231343032
|
||||
30323832346266653238633432383334393661333737383761303238613734623534646232633562
|
||||
63643066663363306432366662643362663665313431616665653239386666623864633639383431
|
||||
37393630636363303438383665326663323561653335396238353138616533323965353031336465
|
||||
39383132666564333661383831323539313334393632653865353662373439663438656534653133
|
||||
63353562373637323436316530666639613637353866633931343536306230323765643335376563
|
||||
33626661366339663161653334666232626464636134623537336237663662343833613564306366
|
||||
64613132313038663761626562323832343937316136363666393438656165653666326463656565
|
||||
39663032656537313563346138323731626562396566646535633830636638643463323334356365
|
||||
65396564633530386237626664353734366336363339336162373139373036666339313531316265
|
||||
63313266316238383363333262373038653062653561656466643837343863633562633530366433
|
||||
61333663366361306233353463646636386335343131396461613562653264306432326663313436
|
||||
37656538356534393065386263373264623664333738306363373465323663313831323665323862
|
||||
37613366313361376137363663393334623237326663383766663736333133353931356264663163
|
||||
65653439356463393938626331323835383232386638323531326661613433343833343130626531
|
||||
61656461333565666633353739626266653138316163326565336461333934376235376639623338
|
||||
66396662323338663966653731386633623331626339653664383366316466653661366630333966
|
||||
63343930363565343464373731386237396363353562633634663935373733373663356537333134
|
||||
38623362633936616533646535626533376366663535626364646536333333313664356532356130
|
||||
33366164303836643730656439386537633761653032333061306261646364373961323334623831
|
||||
35393832323830336633303030653963393532376466353966333039313661373263303136636534
|
||||
65623830646662396236626263313763623833346236343361373465633434366131326362663034
|
||||
64323161383832663765636566363932613434353031653031633262363233653630343736653436
|
||||
35333435663562303135646531663033373538376366323638333031653962306563383733393235
|
||||
64333763663163306537346638633763363932336337633039633865633931656136356537366466
|
||||
66373639303037623066383239383335643664666362303364396465633361396536383133653939
|
||||
31336438646531376364303731313430396464373432646234356637663966333665636136653761
|
||||
39396138343439353565343139643165313864643132386633643836366564636130623666303933
|
||||
36623563326434656439333962336132343662663936653866316163633339336361376633396530
|
||||
66356639366330613335353633613831303535633538633233306666383761633864386538666266
|
||||
61383861393863626434613333633430396636666433306533623432356464633764663433373931
|
||||
38636538313830366438313964666430353237656639633763386332613636636462653634343831
|
||||
62626638633863353165366438656465376466633966356133366263636666343632313761653766
|
||||
65336461346531356631376462623737316538373363353230333436303532333835396435646634
|
||||
39306438663436636532373063643138366531313936306135666466333765646630336532313238
|
||||
64623530626334303638626364343864613164353732386262323439343735383164333232363434
|
||||
34666165353366343566656163373738663065643132303734623533326634346238343630643838
|
||||
64393833646132613761356334306539303233323466336533363938313633343834356239613034
|
||||
64653935373761396331323936616334303561613762623733613637653031623564366538373630
|
||||
61313733333863303630633036353535393532326134636139343532396163346537383665663838
|
||||
61386637353566306134393430366633636437616565343465393333306138376462633131623332
|
||||
65343035653066396533336238393365663432393537323431366532353232333036353662386363
|
||||
35313162646432626632633032636162343764343463366236386438323131623766363937336436
|
||||
31333332373731643164626137643162393964393334643237393133366237323562623839356534
|
||||
31343163656366616638663265323939663765666563333239306563653265343765613432633430
|
||||
63613231326333313437313166326236346538656236373933313262616334656264376430626263
|
||||
65396261386439646562343235326630353265356362666131316664343430343534353062613232
|
||||
64313234323430396139373331356434363663646339653566303638623839383330623630613662
|
||||
33653863333534656665313362326338346338303434363932323635666463323536343865386235
|
||||
31366134643263303630653534306364616466323538626335366231333762643961656165316534
|
||||
34626532393730323034663434386234313939336262333266656134613938613433396337376531
|
||||
343631376663336639636437653165333163
|
313
lmn-client.yml
Normal file
313
lmn-client.yml
Normal file
|
@ -0,0 +1,313 @@
|
|||
## This playbook deploys a client for LinuxMuster.
|
||||
#
|
||||
# Use the following in the installer's preseed file:
|
||||
#
|
||||
# d-i preseed/late_command string \
|
||||
# mkdir -p /target/home/ansible/.ssh && \
|
||||
# echo "ssh-ed25519 A...YOUR.KEY...Z" >> /target/home/ansible/.ssh/authorized_keys ; \
|
||||
# in-target chown -R ansible:ansible /home/ansible/.ssh/ ; \
|
||||
# in-target chmod -R og= /home/ansible/.ssh/ ; \
|
||||
# if [ -n "$playbook" ] ; then \
|
||||
# mkdir -v /target/dev/shm ; \
|
||||
# in-target mount -v -t tmpfs tmpfs /dev/shm ; \
|
||||
# echo "$vaultpw" > /target/dev/shm/vaultpw ; \
|
||||
# in-target ansible-pull --verbose --purge --extra-vars="run_in_installer=true" \
|
||||
# --vault-password-file /dev/shm/vaultpw \
|
||||
# -i localhost, --url=git://ansible.example.org/.git -C YOUR_BRANCH $playbook ; \
|
||||
# fi
|
||||
#
|
||||
---
|
||||
- name: Apply common configuration to the machines
|
||||
hosts: all # desktop:laptop
|
||||
remote_user: ansible
|
||||
become: yes
|
||||
pre_tasks:
|
||||
- pause:
|
||||
prompt: "Enter global-admin AD password. Leave empty to skip domain join"
|
||||
echo: false
|
||||
register: adpw
|
||||
no_log: true
|
||||
when: "ansible_cmdline.adpw is not defined"
|
||||
- name: Preseed apparmor
|
||||
debconf:
|
||||
name: apparmor
|
||||
question: apparmor/homedirs
|
||||
value: >-
|
||||
/srv/samba/schools/default-school/teachers/
|
||||
/srv/samba/schools/default-school/students/*/
|
||||
/srv/samba/schools/default-school/examusers/
|
||||
vtype: string
|
||||
|
||||
vars_files: lmn-vault
|
||||
vars:
|
||||
domain: "{{ ansible_domain }}"
|
||||
kerberize_uris: "{{ vault_kerberize_uris }}" ## example.org
|
||||
apt_conf: "{{ vault_apt_conf }}" ## Acquire::http::Proxy "http://aptcache.example.org:3142/";
|
||||
ntp_serv: "{{ vault_ntp_serv }}" ## ntp.example.org
|
||||
proxy: "{{ vault_proxy }}" ## http://firewall.example.org:3128
|
||||
no_proxy: "{{ vault_no_proxy }}" ## firewall.example.org,server.example.org,idam.example.org,dw.example.org
|
||||
printservers: "{{ vault_printservers }}" ## ['10.0.0.1', '10.0.0.15']
|
||||
|
||||
## PAM mount nextcloud, remove or leave empty to skip:
|
||||
web_dav: "{{ vault_web_dav }}" ## https://nc.example.org/remote.php/dav/files/%(USER)
|
||||
|
||||
## Local mirror for mscorefonts. Remove or leave empty to use no mirror:
|
||||
mirror_msfonts: "{{ vault_mirror_msfonts }}" ## http://livebox.example.org/mscorefonts/
|
||||
|
||||
## Local mirror for libdvdcss. Remove or leave empty to use no mirror:
|
||||
mirror_dvdcss: "{{ vault_mirror_dvdcss }}" ## http://livebox.example.org/libdvdcss/
|
||||
|
||||
uploadseed_pwd: "{{ vault_uploadseed_pwd }}"
|
||||
rsyncsecret: "{{ vault_rsyncsecret }}"
|
||||
keys2deploy: "{{ vault_keys2deploy }}" ## ['ssh-ed25519 AAAAC…uYlnS0', 'ssh-ed25519 AAAA…KTM']
|
||||
localuser: "{{ vault_localuser }}" ## needed here for the (universal) pam-mount configuration
|
||||
|
||||
## Use grub-mkpasswd-pbkdf2 to calculate the password hash:
|
||||
grub_pwd: "{{ vault_grub_pwd }}"
|
||||
nfs4: false
|
||||
extra_pkgs:
|
||||
- vim
|
||||
- mc
|
||||
- tmux
|
||||
- krb5-user
|
||||
- debconf-utils
|
||||
extra_pkgs_bpo: [] # [ linux-image-amd64 ]
|
||||
|
||||
roles:
|
||||
- lmn_network
|
||||
- role: up2date_debian
|
||||
tags: upgrade
|
||||
- lmn_sssd
|
||||
- lmn_mount
|
||||
- lmn_kde
|
||||
- lmn_fvs ## school specific customization
|
||||
- lmn_vm
|
||||
- lmn_printer
|
||||
- kerberize
|
||||
- lmn_security
|
||||
|
||||
tasks:
|
||||
## Temporary fixes and quirks:
|
||||
- name: Fix 8086:4909 external graphics card
|
||||
replace:
|
||||
dest: "/etc/default/grub"
|
||||
regexp: 'GRUB_CMDLINE_LINUX=""$'
|
||||
replace: 'GRUB_CMDLINE_LINUX="i915.force_probe=4909"'
|
||||
notify: Run update-grub
|
||||
when: ansible_board_vendor == "LENOVO" and ansible_board_name == "32CB"
|
||||
|
||||
- name: Fix sound on 312A
|
||||
replace:
|
||||
dest: "/etc/default/grub"
|
||||
regexp: 'GRUB_CMDLINE_LINUX="snd-intel-dspcfg.dsp_driver=1"$'
|
||||
replace: 'GRUB_CMDLINE_LINUX=""'
|
||||
notify: Run update-grub
|
||||
when: ansible_board_vendor == "LENOVO" and ansible_board_name == "312A"
|
||||
|
||||
- name: Fix sound on 312A and 312D
|
||||
apt:
|
||||
name: firmware-sof-signed
|
||||
state: latest
|
||||
when: >
|
||||
ansible_board_vendor == "LENOVO" and
|
||||
(ansible_board_name == "312D" or ansible_board_name == "312A")
|
||||
|
||||
- name: Install customized CodeBlocks packages
|
||||
block:
|
||||
- name: Check for old CodeBlocks
|
||||
command:
|
||||
cmd: dpkg -l codeblocks
|
||||
register: codeblocks_version
|
||||
changed_when: False
|
||||
|
||||
- name: Download codeblocks zip archive
|
||||
ansible.builtin.get_url:
|
||||
url: "http://livebox.pn.steinbeis.schule/codeblocks/CodeBlocks.zip"
|
||||
dest: /tmp/CodeBlocks.zip
|
||||
use_proxy: False
|
||||
when: codeblocks_version.stdout is not search('svn13456')
|
||||
|
||||
- name: Unpack zip archive and install packages manually
|
||||
shell:
|
||||
cmd: unzip -d /tmp/cb/ CodeBlocks.zip && dpkg -i cb/*.deb
|
||||
chdir: /tmp/
|
||||
when: codeblocks_version.stdout is not search('svn13456')
|
||||
when: groups.PCroom is defined and inventory_hostname in groups.PCroom
|
||||
|
||||
## Temporarily fix boot order
|
||||
- name: Check for the buggy kernel
|
||||
stat:
|
||||
path: /boot/vmlinuz-6.1.0-17-amd64
|
||||
register: bug
|
||||
|
||||
- name: Check for the fixed kernel
|
||||
stat:
|
||||
path: /boot/vmlinuz-6.1.0-18-amd64
|
||||
register: fix
|
||||
|
||||
- name: Work around kernel with CIFS regression
|
||||
block:
|
||||
- name: Make sure kernel package -16 is available
|
||||
ansible.builtin.apt:
|
||||
name: linux-image-6.1.0-16-amd64
|
||||
state: present
|
||||
- name: Set 6.1.0-16 as default kernel in grub
|
||||
lineinfile:
|
||||
dest: /etc/default/grub
|
||||
regexp: '^(GRUB_DEFAULT=).*'
|
||||
line: '\g<1>"Debian GNU/Linux, with Linux 6.1.0-16-amd64"'
|
||||
backrefs: yes
|
||||
notify: Run update-grub
|
||||
when: bug.stat.exists and not fix.stat.exists
|
||||
|
||||
- name: Set latest kernel in grub
|
||||
lineinfile:
|
||||
dest: /etc/default/grub
|
||||
regexp: '^(GRUB_DEFAULT=).*'
|
||||
line: '\g<1>0'
|
||||
backrefs: yes
|
||||
when: fix.stat.exists or not bug.stat.exists
|
||||
notify: Run update-grub
|
||||
|
||||
## Clean up stuff from obsolete/faulty tasks:
|
||||
- name: Remove packages we do not need anymore
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- unattended-upgrades
|
||||
- cachefilesd
|
||||
state: absent
|
||||
purge: True
|
||||
|
||||
- name: Remove virtiofs service
|
||||
file:
|
||||
path: /etc/systemd/system/virtiofs@.service
|
||||
state: absent
|
||||
|
||||
- name: Fix mount point permissions and owner
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
loop:
|
||||
- /srv/samba
|
||||
- /srv/samba/schools
|
||||
|
||||
- name: Remove pam_mount sysvol mount
|
||||
blockinfile:
|
||||
dest: /etc/security/pam_mount.conf.xml
|
||||
marker: "<!-- {mark} ANSIBLE MANAGED BLOCK (SysVol) -->"
|
||||
block: |
|
||||
<volume
|
||||
fstype="cifs"
|
||||
server="{{ smb_server }}"
|
||||
path="sysvol/"
|
||||
mountpoint="/srv/samba/%(USER)/sysvol"
|
||||
options="sec=krb5i,cruid=%(USERUID),user=%(USER),gid=1010,file_mode=0770,dir_mode=0770,mfsymlinks"
|
||||
><not><or><user>root</user><user>ansible</user><user>Debian-gdm</user><user>sddm</user><user>{{ localuser }}</user></or></not>
|
||||
</volume>
|
||||
state: absent
|
||||
|
||||
- name: check if rmlpr.timer is installed
|
||||
stat: path=/etc/systemd/system/rmlpr.timer
|
||||
register: rmlpr
|
||||
|
||||
- name: disable rmlpr.timer
|
||||
systemd:
|
||||
name: rmlpr.timer
|
||||
enabled: false
|
||||
when: rmlpr.stat.exists
|
||||
|
||||
- name: check if vmimage-torrent.service is installed
|
||||
stat: path=/etc/systemd/system/vmimage-torrent.service
|
||||
register: vmimagetorrent
|
||||
|
||||
- name: disable vmimage-torrent.service
|
||||
systemd:
|
||||
name: vmimage-torrent.service
|
||||
enabled: false
|
||||
when: vmimagetorrent.stat.exists
|
||||
|
||||
- name: Remove deprecated files and directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
with_items:
|
||||
- /etc/linuxmuster-linuxclient7
|
||||
- /usr/lib/python3/dist-packages/linuxmusterLinuxclient7
|
||||
- /usr/share/linuxmuster-linuxclient7
|
||||
- /usr/local/bin/onLogin
|
||||
- /etc/sudoers.d/90-lmn-sudotools
|
||||
- /etc/systemd/system/rmlpr.service
|
||||
- /etc/systemd/system/rmlpr.timer
|
||||
- /usr/local/bin/sync-vm.sh
|
||||
- /usr/local/bin/run-vm.sh
|
||||
- /usr/local/bin/rebase-vm.sh
|
||||
- /usr/local/bin/create-vm.sh
|
||||
- /usr/local/bin/upload-vm.sh
|
||||
- /usr/local/bin/vmimage-torrent
|
||||
- /etc/systemd/system/vmimage-torrent.service
|
||||
- /usr/local/bin/linbo-torrenthelper.sh
|
||||
- /usr/local/bin/link-images.sh
|
||||
- /usr/local/bin/start-virtiofsd.sh
|
||||
- /etc/sudoers.d/90-lmn-upload-vm
|
||||
- /etc/sudoers.d/90-lmn-sync-vm
|
||||
- /etc/sudoers.d/90-lmn-startvirtiofsd
|
||||
- /etc/sudoers.d/90-lmn-link-images
|
||||
- /etc/rsync.secret
|
||||
|
||||
- name: check if vm_usage_information.txt exists
|
||||
stat: path=/lmn/vm/vm_usage_information.txt
|
||||
register: vm_usage_information
|
||||
|
||||
- name: pre-fill vm_usage_information.txt
|
||||
shell:
|
||||
cmd: |
|
||||
ls -tr *.qcow2 > vm_usage_information.txt || touchvm_usage_information.txt
|
||||
chown lmnsynci:lmnsynci vm_usage_information.txt
|
||||
chdir: /lmn/vm/
|
||||
when: not vm_usage_information.stat.exists
|
||||
|
||||
## bookworm fixes/hacks:
|
||||
- name: Work around sddm hang on shutdown
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/systemd/system.conf
|
||||
line: DefaultTimeoutStopSec=5s
|
||||
insertafter: '^#DefaultTimeoutStopSec=.*'
|
||||
|
||||
#################
|
||||
|
||||
- name: Timestamp successfull run and send up-to-date report
|
||||
ansible.builtin.shell:
|
||||
cmd: date --iso-8601=seconds >> /root/.ansible/stamps && /usr/local/sbin/reporter
|
||||
changed_when: False
|
||||
tags: upgrade
|
||||
|
||||
#################
|
||||
|
||||
- name: Apply additional laptop configuration
|
||||
hosts: laptop
|
||||
remote_user: ansible
|
||||
become: yes
|
||||
vars_files: lmn-vault
|
||||
vars:
|
||||
ssid: "{{ vault_ssid }}"
|
||||
wifipasswd: "{{ vault_wifipasswd }}"
|
||||
localuser: "{{ vault_localuser }}"
|
||||
localuser_pwd: "{{ vault_localuser_pwd }}"
|
||||
roles:
|
||||
- role: lmn_wlan_iwd
|
||||
when: ansible_interfaces | select('search', 'wl.+') | first is defined
|
||||
- lmn_networkd
|
||||
- lmn_localuser
|
||||
tasks:
|
||||
- name: Remove deprecated files and directories (laptop-class)
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
with_items:
|
||||
- /etc/systemd/network/80-wlan-dhcp.network
|
||||
- /etc/systemd/network/wlan-dhcp.network
|
||||
- /etc/systemd/network/virbr1.netdev
|
||||
- /etc/systemd/network/virbr1.network
|
||||
- /etc/systemd/network/wlan-dhcp.network
|
112
lmn-vault
Normal file
112
lmn-vault
Normal file
|
@ -0,0 +1,112 @@
|
|||
$ANSIBLE_VAULT;1.1;AES256
|
||||
65646637366132333430346461646331313431363233363736306264633633396665626332623934
|
||||
6439363764316132383635626137313764633162636362340a613832323934646431663632396361
|
||||
36323539663238363738393131363034333561343233383238396234613434633334323235626637
|
||||
6266326166333334650a353637383131313136613635333237616361353732663734613833306538
|
||||
35643831653332346634616139363032656433623032383832363837653231306465353766343961
|
||||
65313134303434333635306634633731313462396535383662616134653762343732366431373032
|
||||
65346564663335633936636662626162636134636339343463376166666333346133616136626665
|
||||
66373064303562323564363864366363663336383862336632373436666330373465636135623762
|
||||
36656632346664326463646666313663343662363865343166376363313866663536623234383561
|
||||
61616637653630316230626337653135396134323636303538346435663639643662646133383363
|
||||
39393234333934656166366633356663326162396431383362306339623534646162613339383836
|
||||
39666464666163633033653434306365393933383232653364363062356133356239626538633338
|
||||
32303030626538373637323533303964643838383331366365326465666530623965613731663261
|
||||
33626563386262353531353635356430333633633665393230613561633836653636636639313663
|
||||
37373736346234313134313232376164633332386563383863343266626231373237643063663533
|
||||
39343939393331653665633335653264376531383364376565646239616231343531336134626531
|
||||
38396630363865376161313835376261646637383438323537626433323232353632386439393933
|
||||
32306238643436653666333561643764633831343962643165356232663932633763396437383634
|
||||
35313763323633643439376333643836613637613339343731636633313064386231613135623832
|
||||
32643934376233663865326534313735633535316635393932646263313135373633636333333737
|
||||
33386365363830336139323763303734383966616165356462333734333666343830356234616662
|
||||
30616434623237653138623538643331373432663137323333376632343065316431313734333965
|
||||
64333237396236666664613466623039626634343238363136363438663730626132646562646536
|
||||
61653562666636613164373464663931356565623862306332653230396230326636363638393862
|
||||
62663765373436303831613435383866323138316633336532336632383065343537326332653235
|
||||
30383764396361396565323035346531396365623130636538396238613037353438346365363331
|
||||
64383636376566306136653033613638323865653266383136373231353063303434636332363166
|
||||
37373462353530326663386139333536616138386431373763383838336365336634366339636637
|
||||
32356263653964343461393162396539303534343562653032643461626235373339666363646637
|
||||
37633934393036356331363563303330316234393535376338646235663235383966396634383166
|
||||
37656633373562643530663037333735396638363963323837653831396233653962356536616236
|
||||
37323139306131323561303061633136303234316335363361633766623530303762663465353163
|
||||
33313733386265346333663065366536616533326364613231313330373137616130373539313131
|
||||
37316637653934653035373965636633626262626561313338646261313530356163356364663834
|
||||
64663037666133626261386266666633336666323362373237626639373535333937336331353039
|
||||
30313833353766626332376432326531616464643364313232386633613361623234653536313830
|
||||
61626666333037393564303738646333643534623138366264353339326331386433343733623837
|
||||
63646431646533383331356334656466316465623735613537646536623364636632323566626233
|
||||
31663263623539343562383836366134366236346539386532373735633237373363636438366632
|
||||
39613330336365626137363765313930623262666263393835626532333262343265313761356333
|
||||
34623663633636373734326662363865396635613933393464356436393161303132663564366437
|
||||
35323166643762333862656561306239343034643562316534316236636362363162306131633961
|
||||
31653736613732643930666338333131373634333166633466656663636163396266306538626666
|
||||
65326163646137373236633363663063383162393435356163366665653033666161333037303035
|
||||
35396334663135373863646664613137666565356161353865316164633939323037323664346331
|
||||
63313230333565336232663166616465363038326663633066623531363338623430313332333138
|
||||
34363532643036343831353463356665646363363239643835396661356665393035303561653337
|
||||
62663335636533366334643636653366303231353630633166343832313133303663393836623036
|
||||
33616563636266356130356635663538343236356632376461626532626436616334386330356430
|
||||
62323864323534333032643737656164343633636365623664336236626239633138626230383536
|
||||
39306534383933326638666130383139316334373530373335633238316238353038643136366533
|
||||
38396661626661373964363630633963373732343161663065386539306637313633303534663466
|
||||
66396361373163313865373131636239613930333963663462306636626431363934343136616330
|
||||
30643763343838316338643463323833666639616437336361303363393361356431356266353233
|
||||
63366366336231386530313961356538613136366530343338353063343332333165323763613566
|
||||
34653133633532613332376634616234383237666261363038613437646366356332636530623534
|
||||
30613735663666636232623230633161663064666436333161633334356336383038386535336133
|
||||
39663963333031383961643232636539313137346132336462336165313862653366303135353730
|
||||
63303834313462646633333232646661623731613439633434663266303834376635346438356438
|
||||
39303066663633656234633131366330356363636535373034613037363837326562306562663538
|
||||
61316666643230626662663266373330643865393938313232306130376333306536393930363037
|
||||
66636562396339633763656431653036646361313632313932636231626333303337366266623238
|
||||
39616336656537363439373231643132363264306135346437386465326265666137353032336261
|
||||
61323234643662653233353737346661373630376630343635383834313038373162643135343434
|
||||
37613634333330326132623437623834363539343037643764303631613463343863643065643063
|
||||
33326537376130346365323361343266663331343038663037623438666362656236613065366235
|
||||
65363130356133353739623733376531636438643535633731646431653837343531313531373436
|
||||
31356139393363646262623664663261613931636330663436336466633038643763336337336330
|
||||
33393433346332623538653262303462636363363338346538376463373838363036343634363131
|
||||
31636332343931643436393464656165616631373339336537623130343630346164383830313165
|
||||
36316364653739646330663762356332393262653931613933643963626433633532353766663632
|
||||
65616262666433383763363636303131373064636261616661613139373766336639376336393962
|
||||
65336332303164353763636332323031363363653262386331313038646564393131303366653834
|
||||
33303464303566656363343464336164363264626436306465633261386464663764636431353037
|
||||
31363034323331333235346137653139323835326135653337323339346239383038363861313638
|
||||
31363136353037396634326239306665303230616131363965653439656361356538623135613238
|
||||
66366639333331306337323562343934313532323633613034353863623839636135393465383832
|
||||
34323031326262306161613439323836646538363136336537313266343662383935373762666138
|
||||
64336132356662366436326664653234303034623066313736353439396334653630643136336431
|
||||
31386330326636303334313535363564383964623538656666376136366365633538386139333862
|
||||
65336662653965343035306534393962616438636366646664383231316365366435663763643663
|
||||
64383034336565663561626262636263616336303066396164633464313830363338303932356638
|
||||
32373162313330303935316137366435373532346363386461303933643237383830623335626639
|
||||
33383335653436353831303163656530613962303439383563376534663738383035346433303834
|
||||
31663863343864656463643433383938393464613865356134346261663333616537663066333965
|
||||
32366466373165633936323232333237383638313434366437376237653837363532393564323035
|
||||
64623234376538666237653938346634346532656135333165353864383739353737643965636539
|
||||
63626134376330346538656539333362633765363735656161323635323164323038633139653663
|
||||
64616466353137623937333237633163646266326437663833393437336662356465336566353832
|
||||
30653063666261613534393439663664326336353338393439336137386662316137666236636337
|
||||
32326336396430633136333064383164373033366230333832333564616364663931653233333233
|
||||
62353264343865663865323461643032633465336564646161303039356266303738306435353131
|
||||
30376431616631613463313666383664343962306265613361376365353361303162653834623631
|
||||
33643762306232636134666366373637353234353265303437306261383861333235383530383638
|
||||
62353338323535333438376335636339386161326564623037323861343134396637366362646335
|
||||
66633865386339666265396438353362333463376361306666313331353063313331636539343835
|
||||
66326661386532343865653365356531663365663865666439653039643333363363653838616436
|
||||
38333037353333373866316333613538373263386334626665363239353162376335373238613737
|
||||
31616465326138663934356530353263653133636232396134316163343131316664633964643437
|
||||
37353937653665326638663631383733646563336162643361643366633564663439396639373966
|
||||
66356163343731353430626537326466393538363939313134343464643666323037356639323538
|
||||
35626137303439316233313664326535396234326432396132646361663936636362626232383530
|
||||
37366334333035656638383161663732393864333562373761303031353262303666626436373065
|
||||
66396233393864373463363065373461353538626135663937656330326632663863353438643838
|
||||
63663438356663313039616135393833623838366530353735333161663739366431393139623737
|
||||
63306464353039323065623765363665663266393934653962303761383362646364373239313062
|
||||
38353737663434646138303562303835373439653137656234653333313234366436623963386636
|
||||
66313837393636373537663030393331613633306531306339306261636366343362333736363465
|
||||
32316662666664636437393736383130663235373266393263623131643339323266633633336334
|
||||
30643737396364303462363262653332346637643466323339633435323436366430626339393537
|
||||
633439343732646238343833663731646631
|
43
lmn-www-server.yml
Normal file
43
lmn-www-server.yml
Normal file
|
@ -0,0 +1,43 @@
|
|||
## This playbook deploys a FvS web server machine.
|
||||
---
|
||||
- name: apply configuration to the web server
|
||||
hosts: all
|
||||
remote_user: ansible
|
||||
become: yes
|
||||
pre_tasks:
|
||||
- pause:
|
||||
prompt: "Enter global-admin AD password. Leave empty to skip domain join"
|
||||
echo: false
|
||||
register: adpw
|
||||
no_log: true
|
||||
when: "ansible_cmdline.adpw is not defined"
|
||||
vars:
|
||||
domain: "pn.steinbeis.schule"
|
||||
extra_pkgs:
|
||||
- vim
|
||||
- apache2
|
||||
- python3-flask
|
||||
|
||||
extra_pkgs_bpo: [ ] # [ libreoffice ]
|
||||
|
||||
roles:
|
||||
- up2date_debian
|
||||
- lmn_sssd
|
||||
- kerberize
|
||||
|
||||
tasks:
|
||||
- name: Override home dir location
|
||||
lineinfile:
|
||||
dest: /etc/sssd/sssd.conf
|
||||
line: override_homedir = /home/%u
|
||||
|
||||
- name: enable pam_mkhomedir.so
|
||||
lineinfile:
|
||||
dest: /etc/pam.d/common-session
|
||||
line: "session optional pam_mkhomedir.so umask=0026"
|
||||
insertbefore: "session optional pam_mount.so"
|
||||
|
||||
- name: enable apache mod userdir
|
||||
apache2_module:
|
||||
state: present
|
||||
name: userdir
|
5
roles/kerberize/handlers/main.yml
Normal file
5
roles/kerberize/handlers/main.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
- name: reload sshd
|
||||
systemd:
|
||||
name: sshd
|
||||
state: reloaded
|
||||
when: not run_in_installer|default(false)|bool
|
45
roles/kerberize/tasks/main.yml
Normal file
45
roles/kerberize/tasks/main.yml
Normal file
|
@ -0,0 +1,45 @@
|
|||
- name: Install kerberos packages
|
||||
apt:
|
||||
name: krb5-user
|
||||
state: latest
|
||||
|
||||
- name: Kerberize sshd server
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/ssh/sshd_config.d/kerberize.conf
|
||||
content: |
|
||||
GSSAPIAuthentication yes
|
||||
notify: "reload sshd"
|
||||
|
||||
- name: Kerberize ssh client, authenticate and delegate credentials
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/ssh/ssh_config.d/kerberize.conf
|
||||
content: |
|
||||
GSSAPIAuthentication yes
|
||||
GSSAPIDelegateCredentials yes
|
||||
|
||||
- name: Check if firefox is available
|
||||
stat: path=/etc/firefox-esr/firefox-esr.js
|
||||
register: firefox
|
||||
|
||||
- name: Kerberize firefox for sites in the local domain
|
||||
lineinfile:
|
||||
dest: /etc/firefox-esr/firefox-esr.js
|
||||
line: "{{ item }}"
|
||||
with_items:
|
||||
- '// kerberize for sites in the local domain:'
|
||||
- 'pref("network.negotiate-auth.delegation-uris", "{{ kerberize_uris | default(ansible_domain) }}");'
|
||||
- 'pref("network.negotiate-auth.trusted-uris", "{{ kerberize_uris | default(ansible_domain) }}");'
|
||||
when: firefox.stat.exists
|
||||
|
||||
- name: Ensures /etc/chromium/policies/managed dir exists
|
||||
file:
|
||||
path: "/etc/chromium/policies/managed"
|
||||
state: directory
|
||||
|
||||
- name: Kerberize chromium for sites in the local domain
|
||||
copy:
|
||||
dest: /etc/chromium/policies/managed/idam.json
|
||||
content: |
|
||||
{
|
||||
"AuthServerAllowlist": "idam.steinbeis.schule"
|
||||
}
|
18
roles/lmn_fvs/files/bootorder.sh
Normal file
18
roles/lmn_fvs/files/bootorder.sh
Normal file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/bash
|
||||
#
|
||||
# fix boot order: first PXE, then Debian
|
||||
#
|
||||
set -eu
|
||||
|
||||
cur="$(efibootmgr | grep -Ei 'BootOrder:' | \
|
||||
sed -E 's/^BootOrder: ([[:xdigit:]]{4}),.+$/\1/')"
|
||||
pxeip4="$(efibootmgr | grep -Ei "IP.*4" | \
|
||||
sed -E 's/^Boot([[:xdigit:]]{4}).+$/\1/')"
|
||||
debian="$(efibootmgr | grep -Ei "debian" | \
|
||||
sed -E 's/^Boot([[:xdigit:]]{4}).+$/\1/')"
|
||||
|
||||
if [[ "$cur" != "$pxeip4" ]] && [[ -n "$pxeip4" ]] && [[ -n "$debian" ]] ; then
|
||||
efibootmgr -o $pxeip4,$debian
|
||||
else
|
||||
echo "Nothing to do."
|
||||
fi
|
113
roles/lmn_fvs/files/fvs-config.js
Normal file
113
roles/lmn_fvs/files/fvs-config.js
Normal file
|
@ -0,0 +1,113 @@
|
|||
// configure plasma defaults
|
||||
|
||||
function forEachWidgetInContainmentList(containmentList, callback) {
|
||||
for (var containmentIndex = 0; containmentIndex < containmentList.length; containmentIndex++) {
|
||||
var containment = containmentList[containmentIndex];
|
||||
|
||||
var widgets = containment.widgets();
|
||||
for (var widgetIndex = 0; widgetIndex < widgets.length; widgetIndex++) {
|
||||
var widget = widgets[widgetIndex];
|
||||
callback(widget, containment);
|
||||
if (widget.type === "org.kde.plasma.systemtray") {
|
||||
systemtrayId = widget.readConfig("SystrayContainmentId");
|
||||
if (systemtrayId) {
|
||||
forEachWidgetInContainmentList([desktopById(systemtrayId)], callback)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function forEachWidget(callback) {
|
||||
forEachWidgetInContainmentList(desktops(), callback);
|
||||
forEachWidgetInContainmentList(panels(), callback);
|
||||
}
|
||||
|
||||
function forEachWidgetByType(type, callback) {
|
||||
forEachWidget(function(widget, containment) {
|
||||
if (widget.type == type) {
|
||||
callback(widget, containment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function widgetSetProperty(args) {
|
||||
if (!(args.widgetType && args.configGroup && args.configKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
forEachWidgetByType(args.widgetType, function(widget){
|
||||
widget.currentConfigGroup = [args.configGroup];
|
||||
/*
|
||||
//--- Delete when done debugging
|
||||
const oldValue = widget.readConfig(args.configKey);
|
||||
print("" + widget.type + " (id: " + widget.id + "):");
|
||||
print("\t[" + args.configGroup + "] " + args.configKey + ": " +
|
||||
oldValue + " => " + args.configValue + "\n");
|
||||
//--- End Debug
|
||||
*/
|
||||
widget.writeConfig(args.configKey, args.configValue);
|
||||
});
|
||||
}
|
||||
|
||||
// configure task bar starters:
|
||||
widgetSetProperty({
|
||||
widgetType: "org.kde.plasma.icontasks",
|
||||
configGroup: "General",
|
||||
configKey: "launchers",
|
||||
configValue: [
|
||||
"applications:systemsettings.desktop",
|
||||
"preferred://browser",
|
||||
"applications:thunderbird.desktop",
|
||||
"applications:libreoffice-startcenter.desktop",
|
||||
"preferred://filemanager"
|
||||
//"applications:org.kde.konsole.desktop",
|
||||
//"applications:org.kde.discover.desktop"
|
||||
],
|
||||
|
||||
});
|
||||
|
||||
// kickoff is the default menu:
|
||||
/* this does not work (anymore?)
|
||||
widgetSetProperty({
|
||||
widgetType: "org.kde.plasma.kickoff",
|
||||
configGroup: "General",
|
||||
configKey: "favorites",
|
||||
configValue: ["applications:libreoffice-startcenter.desktop",],
|
||||
});
|
||||
*/
|
||||
|
||||
widgetSetProperty({
|
||||
widgetType: "org.kde.plasma.kickoff",
|
||||
configGroup: "General",
|
||||
configKey: "systemFavorites",
|
||||
configValue: ["reboot", "shutdown", "logout"],
|
||||
//configValue: ["logout"],
|
||||
});
|
||||
|
||||
|
||||
// prepare a folder view on the desktop:
|
||||
/* 20230917 disabled for now
|
||||
var allDesktops = desktops();
|
||||
for (var desktopIndex = 0; desktopIndex < allDesktops.length; desktopIndex++) {
|
||||
var d = allDesktops[desktopIndex];
|
||||
d.addWidget("org.kde.plasma.folder", 50, 50, 456, 600)
|
||||
print("Folder app generated!\n")
|
||||
}
|
||||
|
||||
widgetSetProperty({
|
||||
widgetType: "org.kde.plasma.folder",
|
||||
configGroup: "General",
|
||||
configKey: "url",
|
||||
configValue: "/lmn/media/",
|
||||
});
|
||||
|
||||
widgetSetProperty({
|
||||
widgetType: "org.kde.plasma.folder",
|
||||
configGroup: "General",
|
||||
configKey: "labelMode",
|
||||
configValue: "0",
|
||||
});
|
||||
*/
|
||||
|
||||
// /usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/fvs-config.js
|
3
roles/lmn_fvs/files/lmn-dolphin.sh
Normal file
3
roles/lmn_fvs/files/lmn-dolphin.sh
Normal file
|
@ -0,0 +1,3 @@
|
|||
if [[ "$UID" -gt 10000 ]] && [[ ! -f ~/.local/share/user-places.xbel.lmn ]] ; then
|
||||
(sleep 30 ; lmn-patch-dolphin.sh) &
|
||||
fi
|
63
roles/lmn_fvs/files/lmn-patch-dolphin.sh
Executable file
63
roles/lmn_fvs/files/lmn-patch-dolphin.sh
Executable file
|
@ -0,0 +1,63 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# patch 'Tausch' and 'Nextcloud' into dolphin's bookmarks
|
||||
#
|
||||
set -eu
|
||||
|
||||
file="${1:-$HOME/.local/share/user-places.xbel}"
|
||||
|
||||
[[ -e "$file" ]] || exit 0
|
||||
|
||||
if grep -q "Tausch\|Nextcloud" "$file" ; then
|
||||
echo "Your Dolphin seems to already contain 'Tausch' and/or 'Nextcloud'." | tee "$file.lmn"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
id="$(grep ID "$file" | sed -E "s|^.+ID>([[:digit:]]+)/([[:digit:]]+)</ID.+$|\1:\2|" \
|
||||
| sort -n -t: -k2 | tail -1 )"
|
||||
|
||||
IDENTITY="${id%%:*}"
|
||||
NUM0="${id##*:}"
|
||||
NUM1=$(( NUM0 + 1 ))
|
||||
NUM2=$(( NUM0 + 2 ))
|
||||
|
||||
patch="
|
||||
--- a/$file
|
||||
+++ b/$file
|
||||
@@ -98,9 +98,33 @@
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
+ <bookmark href=\"file:///srv/samba/schools/default-school/share\">
|
||||
+ <title>Tausch</title>
|
||||
+ <info>
|
||||
+ <metadata owner=\"http://freedesktop.org\">
|
||||
+ <bookmark:icon name=\"folder-publicshare\"/>
|
||||
+ </metadata>
|
||||
+ <metadata owner=\"http://www.kde.org\">
|
||||
+ <ID>$IDENTITY/${NUM1}</ID>
|
||||
+ <isSystemItem>true</isSystemItem>
|
||||
+ </metadata>
|
||||
+ </info>
|
||||
+ </bookmark>
|
||||
+ <bookmark href=\"file:///lmn/media/$USER/nextcloud\">
|
||||
+ <title>Nextcloud</title>
|
||||
+ <info>
|
||||
+ <metadata owner=\"http://freedesktop.org\">
|
||||
+ <bookmark:icon name=\"folder-cloud\"/>
|
||||
+ </metadata>
|
||||
+ <metadata owner=\"http://www.kde.org\">
|
||||
+ <ID>$IDENTITY/${NUM2}</ID>
|
||||
+ <isSystemItem>true</isSystemItem>
|
||||
+ </metadata>
|
||||
+ </info>
|
||||
+ </bookmark>
|
||||
<bookmark href=\"remote:/\">
|
||||
<title>Network</title>
|
||||
<info>
|
||||
<metadata owner=\"http://freedesktop.org\">
|
||||
<bookmark:icon name=\"folder-network\"/>
|
||||
"
|
||||
|
||||
echo "$patch" | patch -z '.lmn' --fuzz=0 --backup "$file"
|
222
roles/lmn_fvs/files/lmn-reset-dolphin.sh
Executable file
222
roles/lmn_fvs/files/lmn-reset-dolphin.sh
Executable file
|
@ -0,0 +1,222 @@
|
|||
#!/bin/bash
|
||||
|
||||
sed -e "s|HOME|/${HOME##/srv/samba/schools/default-school/}|g" -e "s|USER|${USER}|g" > ~/.local/share/user-places.xbel <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xbel>
|
||||
<xbel xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info" xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks" xmlns:kdepriv="http://www.kde.org/kdepriv">
|
||||
<info>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<kde_places_version>4</kde_places_version>
|
||||
<GroupState-Places-IsHidden>false</GroupState-Places-IsHidden>
|
||||
<GroupState-Remote-IsHidden>false</GroupState-Remote-IsHidden>
|
||||
<GroupState-Devices-IsHidden>false</GroupState-Devices-IsHidden>
|
||||
<GroupState-RemovableDevices-IsHidden>false</GroupState-RemovableDevices-IsHidden>
|
||||
<GroupState-Tags-IsHidden>false</GroupState-Tags-IsHidden>
|
||||
<withRecentlyUsed>true</withRecentlyUsed>
|
||||
<GroupState-RecentlySaved-IsHidden>false</GroupState-RecentlySaved-IsHidden>
|
||||
<withBaloo>true</withBaloo>
|
||||
<GroupState-SearchFor-IsHidden>false</GroupState-SearchFor-IsHidden>
|
||||
</metadata>
|
||||
</info>
|
||||
<bookmark href="file:///srv/samba/schools/default-schoolHOME">
|
||||
<title>Home</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="user-home"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/0</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="file:///srv/samba/schools/default-schoolHOME/Schreibtisch">
|
||||
<title>Desktop</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="user-desktop"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/1</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="file:///srv/samba/schools/default-schoolHOME/Dokumente">
|
||||
<title>Documents</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="folder-documents"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/2</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="file:///srv/samba/schools/default-schoolHOME/Downloads">
|
||||
<title>Downloads</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="folder-downloads"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/3</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="file:///srv/samba/schools/default-schoolHOME/Musik">
|
||||
<title>Music</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="folder-music"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/6</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="file:///srv/samba/schools/default-schoolHOME/Bilder">
|
||||
<title>Pictures</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="folder-pictures"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/7</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="file:///srv/samba/schools/default-schoolHOME/Videos">
|
||||
<title>Videos</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="folder-videos"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/8</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="file:///srv/samba/schools/default-school/share">
|
||||
<title>Tausch</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="folder-publicshare"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/9</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="file:///lmn/media/USER/nextcloud">
|
||||
<title>Nextcloud</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="folder-cloud"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/10</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="remote:/">
|
||||
<title>Network</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="folder-network"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/4</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="trash:/">
|
||||
<title>Trash</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="user-trash"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/5</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="recentlyused:/files">
|
||||
<title>Recent Files</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="document-open-recent"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/9</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<bookmark href="recentlyused:/locations">
|
||||
<title>Recent Locations</title>
|
||||
<info>
|
||||
<metadata owner="http://freedesktop.org">
|
||||
<bookmark:icon name="folder-open-recent"/>
|
||||
</metadata>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<ID>1682498425/10</ID>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</bookmark>
|
||||
<separator>
|
||||
<info>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<UDI>/org/kde/fstab///server/default-school/:/srv/samba/schools/default-school</UDI>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
<IsHidden>true</IsHidden>
|
||||
</metadata>
|
||||
</info>
|
||||
</separator>
|
||||
<separator>
|
||||
<info>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<UDI>/org/kde/fstab///server/default-school/:/lmn/media/USER/home</UDI>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
<IsHidden>true</IsHidden>
|
||||
</metadata>
|
||||
</info>
|
||||
</separator>
|
||||
<separator>
|
||||
<info>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<UDI>/org/kde/fstab///server/sysvol/:/srv/samba/USER/sysvol</UDI>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
<IsHidden>true</IsHidden>
|
||||
</metadata>
|
||||
</info>
|
||||
</separator>
|
||||
<separator>
|
||||
<info>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<UDI>/org/kde/fstab///server/default-school/:/lmn/media/USER/share</UDI>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
<IsHidden>true</IsHidden>
|
||||
</metadata>
|
||||
</info>
|
||||
</separator>
|
||||
<separator>
|
||||
<info>
|
||||
<metadata owner="http://www.kde.org">
|
||||
<UDI>/org/freedesktop/UDisks2/block_devices/sda2</UDI>
|
||||
<isSystemItem>true</isSystemItem>
|
||||
</metadata>
|
||||
</info>
|
||||
</separator>
|
||||
</xbel>
|
||||
EOF
|
82
roles/lmn_fvs/files/policies.json
Normal file
82
roles/lmn_fvs/files/policies.json
Normal file
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"policies": {
|
||||
"Proxy": {
|
||||
"Mode": "system"
|
||||
},
|
||||
"OverrideFirstRunPage": "https://www.steinbeisschule-reutlingen.de",
|
||||
"Homepage": {
|
||||
"URL": "https://www.debian.org",
|
||||
"Locked": false,
|
||||
"StartPage": "previous-session"
|
||||
},
|
||||
"DisplayBookmarksToolbar": true,
|
||||
"ManagedBookmarks": [
|
||||
{
|
||||
"toplevel_name": "FvS-Reutlingen"
|
||||
},
|
||||
{
|
||||
"url": "https://www.steinbeisschule-reutlingen.de",
|
||||
"name": "FvS-Homepage"
|
||||
},
|
||||
{
|
||||
"url": "https://server.pn.steinbeis.schule",
|
||||
"name": "Schulkonsole/Passwort ändern"
|
||||
},
|
||||
{
|
||||
"url": "https://dw.steinbeis.schule",
|
||||
"name": "FvS-Hilfesystem"
|
||||
},
|
||||
{
|
||||
"url": "https://mail.steinbeis.schule",
|
||||
"name": "FvS-eMail"
|
||||
},
|
||||
{
|
||||
"url": "https://nc.steinbeis.schule",
|
||||
"name": "FvS-Nextcloud"
|
||||
},
|
||||
{
|
||||
"url": "https://moodle.steinbeis.schule",
|
||||
"name": "FvS-Moodle"
|
||||
},
|
||||
{
|
||||
"name": "Debian",
|
||||
"children": [
|
||||
{
|
||||
"url": "https://www.debian.org",
|
||||
"name": "Debian Homepage"
|
||||
},
|
||||
{
|
||||
"url": "https://wiki.debian.org",
|
||||
"name": "Debian Wiki"
|
||||
},
|
||||
{
|
||||
"name": "Debian LAN/Live",
|
||||
"children": [
|
||||
{
|
||||
"url": "https://salsa.debian.org/andi/debian-lan-ansible",
|
||||
"name": "Debian LAN Ansible"
|
||||
},
|
||||
{
|
||||
"url": "https://wiki.debian.org/DebianLive",
|
||||
"name": "Debian Live"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"SearchEngines": {
|
||||
"Add": [
|
||||
{
|
||||
"Name": "Startpage",
|
||||
"URLTemplate": "https://www.startpage.com/sp/search?query={searchTerms}",
|
||||
"Method": "GET",
|
||||
"IconURL": "https://www.startpage.com/sp/cdn/favicons/favicon--default.ico",
|
||||
"Alias": "sp",
|
||||
"Description": "Startpage Search Engine"
|
||||
}
|
||||
],
|
||||
"Default": "Startpage"
|
||||
}
|
||||
}
|
||||
}
|
48
roles/lmn_fvs/files/pwroff
Executable file
48
roles/lmn_fvs/files/pwroff
Executable file
|
@ -0,0 +1,48 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# logout idle users and shutdown machine
|
||||
#
|
||||
set -eu
|
||||
|
||||
action="systemctl poweroff"
|
||||
uptime=$(cat /proc/uptime | cut -f1 -d.)
|
||||
maxidle=3600 ## seconds
|
||||
|
||||
u=($(loginctl list-users --no-legend | sort -hr | head -1))
|
||||
una=${u[1]:-''}
|
||||
uid=${u[0]:-''}
|
||||
|
||||
talk2dbus() {
|
||||
local display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"
|
||||
sudo -u $una DISPLAY=$display \
|
||||
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus "$@"
|
||||
}
|
||||
|
||||
########
|
||||
|
||||
## shutdown if nobody is loged in:
|
||||
if [[ -z "$una" ]] || [[ $uid -lt 1000 ]] ; then
|
||||
exec $action
|
||||
fi
|
||||
|
||||
# FIXME: find idle time independent of running screensaver
|
||||
if ! t=$(talk2dbus qdbus org.kde.screensaver /ScreenSaver GetActiveTime) ; then
|
||||
echo "No graphical logins found."
|
||||
else
|
||||
idle=$(( t / 1000 ))
|
||||
if [[ $idle -gt $maxidle ]] && [[ ! -d "/srv/samba/schools/default-school/teachers/" ]] ; then
|
||||
talk2dbus notify-send -i system-shutdown -u critical -a 'Important System Information' \
|
||||
'Please log out, the system will shut down soon!' \
|
||||
'There has been no activity for too long.'
|
||||
## shutdown:
|
||||
#talk2dbus qdbus org.kde.ksmserver /KSMServer logout 1 2 0
|
||||
## logout:
|
||||
talk2dbus qdbus org.kde.ksmserver /KSMServer logout 1 0 0 || \
|
||||
loginctl terminate-user $una
|
||||
echo "Log-out user $una after being idle for $idle seconds."
|
||||
else
|
||||
echo "The user $una has been idle for $idle seconds."
|
||||
fi
|
||||
fi
|
||||
|
||||
#w -s | grep tty | sed "s/[[:space:]]\+/ /g" | cut -f4 -d ' '
|
6
roles/lmn_fvs/files/pwroff.service
Normal file
6
roles/lmn_fvs/files/pwroff.service
Normal file
|
@ -0,0 +1,6 @@
|
|||
[Unit]
|
||||
Description=Run pwroff script
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/sbin/pwroff
|
9
roles/lmn_fvs/files/pwroff.timer
Normal file
9
roles/lmn_fvs/files/pwroff.timer
Normal file
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Run pwroff script every 15 min after 90 min uptime
|
||||
|
||||
[Timer]
|
||||
OnBootSec=90min
|
||||
OnUnitActiveSec=15min
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
33
roles/lmn_fvs/files/reporter
Executable file
33
roles/lmn_fvs/files/reporter
Executable file
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/bash
|
||||
#
|
||||
# Send stdout of some commands to monitoring server.
|
||||
# Collect the reports with 'nc -u -k -l 1234' on 'sendto'.
|
||||
# Use /bin/nc.openbsd, /bin/nc.traditional seems not to work.
|
||||
#
|
||||
set -eu
|
||||
|
||||
sendto="collector.steinbeis.schule 1234"
|
||||
n=0
|
||||
|
||||
cmds=(
|
||||
'uname -a'
|
||||
'tail -1 /root/.ansible/stamps'
|
||||
'ip route list default'
|
||||
'ip link show | \
|
||||
sed -nE -e "s/^[2-9]: (\S+): .+/\1/p" -e "s/.+ether ([0-9a-f:]+) .+/\1/p" | \
|
||||
paste - -'
|
||||
)
|
||||
# 'w'
|
||||
# 'uptime'
|
||||
# 'ls -d --full-time /home/ansible/.ansible/tmp/'
|
||||
# 'ip addr show'
|
||||
# 'apt list --upgradeable -o Apt::Cmd::Disable-Script-Warning=true'
|
||||
|
||||
r="$HOSTNAME ------- $(date --rfc-3339=seconds) -------
|
||||
$(for c in "${cmds[@]}" ; do
|
||||
n=$(( n + 1 ))
|
||||
echo -n "$n"
|
||||
eval "$c" | sed 's/^/\t/'
|
||||
done | sed "s/^/$HOSTNAME /")
|
||||
## -------------------------------------------------"
|
||||
echo "$r" | nc -w 1 -u $sendto
|
6
roles/lmn_fvs/files/reporter.service
Normal file
6
roles/lmn_fvs/files/reporter.service
Normal file
|
@ -0,0 +1,6 @@
|
|||
[Unit]
|
||||
Description=Run reporting script
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/sbin/reporter
|
9
roles/lmn_fvs/files/reporter.timer
Normal file
9
roles/lmn_fvs/files/reporter.timer
Normal file
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Run reporter script every 15 min
|
||||
|
||||
[Timer]
|
||||
OnBootSec=5min
|
||||
OnUnitActiveSec=15min
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
258
roles/lmn_fvs/tasks/main.yml
Normal file
258
roles/lmn_fvs/tasks/main.yml
Normal file
|
@ -0,0 +1,258 @@
|
|||
---
|
||||
- name: Preseed wireshark to allow users sniffing packets
|
||||
ansible.builtin.debconf:
|
||||
name: wireshark-common
|
||||
question: wireshark-common/install-setuid
|
||||
value: 'true'
|
||||
vtype: boolean
|
||||
|
||||
- name: Preseed ttf-mscorefonts-installer
|
||||
ansible.builtin.debconf:
|
||||
name: ttf-mscorefonts-installer
|
||||
question: msttcorefonts/dlurl
|
||||
value: "{{ mirror_msfonts }}"
|
||||
vtype: string
|
||||
when: mirror_msfonts is defined and mirror_msfonts | length > 0
|
||||
|
||||
|
||||
- name: Install desktop EDU packages and some more
|
||||
apt:
|
||||
name:
|
||||
- atftp
|
||||
- calligraplan
|
||||
- cmake ## for kdevelop
|
||||
- codelite
|
||||
- codelite-plugins
|
||||
- curl
|
||||
- elpa-color-theme-modern
|
||||
- elpa-magit
|
||||
- emacs
|
||||
- filezilla
|
||||
- freeplane
|
||||
- git
|
||||
- gitg
|
||||
- gitk
|
||||
- htop
|
||||
- jupyter
|
||||
- kdevelop
|
||||
- kdevelop-php
|
||||
- kdevelop-python
|
||||
- krita
|
||||
- libnotify-bin ## needed for pwroff script
|
||||
- links2
|
||||
- minder
|
||||
- neovim
|
||||
- net-tools
|
||||
- netcat-openbsd
|
||||
- nmap
|
||||
- pdf-presenter-console
|
||||
- php-cli
|
||||
- pipx
|
||||
- planner
|
||||
- pulseview
|
||||
- python3-websockets
|
||||
- qpdfview
|
||||
- shellcheck
|
||||
- sigrok
|
||||
- sigrok-cli
|
||||
- texlive-latex-recommended
|
||||
- tmux
|
||||
- tree
|
||||
- ttf-mscorefonts-installer
|
||||
- twinkle
|
||||
- unison-gtk
|
||||
- w3m
|
||||
- wireshark
|
||||
- zulucrypt-gui
|
||||
autoremove: true
|
||||
state: latest
|
||||
environment:
|
||||
http_proxy: '' # this is needed to avoid ttf-mscorefonts-installer picking up aptcacher
|
||||
|
||||
- name: Remove update notifications from plasma-discover
|
||||
apt:
|
||||
name:
|
||||
- plasma-discover
|
||||
autoremove: true
|
||||
state: absent
|
||||
|
||||
- name: Make sure wireshark works for all users after installation and upgrades
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/apt/apt.conf.d/92wireshark4all
|
||||
content: |
|
||||
## Modify permissions after installation/upgrade to allow all
|
||||
## users dumping packages on network interfaces for wireshark
|
||||
DPkg::Post-Invoke {"/usr/bin/chmod o+x /usr/bin/dumpcap || true"; };
|
||||
|
||||
|
||||
- name: Create firefox policies directory
|
||||
ansible.builtin.file:
|
||||
path: /etc/firefox-esr/policies
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Create a symbolic link firefox to firefox-esr
|
||||
ansible.builtin.file:
|
||||
src: /etc/firefox-esr
|
||||
dest: /etc/firefox
|
||||
state: link
|
||||
|
||||
- name: Copy firefox policy
|
||||
ansible.builtin.copy:
|
||||
src: policies.json
|
||||
dest: /etc/firefox-esr/policies/
|
||||
|
||||
|
||||
- name: Copy some scripts
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: /usr/local/sbin/
|
||||
mode: 0755
|
||||
loop:
|
||||
- pwroff
|
||||
- bootorder.sh
|
||||
- reporter
|
||||
|
||||
- name: Provide services and timers for some scripts
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "/etc/systemd/system/{{ item }}"
|
||||
mode: 0644
|
||||
loop:
|
||||
- pwroff.service
|
||||
- pwroff.timer
|
||||
- reporter.service
|
||||
- reporter.timer
|
||||
|
||||
- name: Enable pwroff.timer
|
||||
systemd:
|
||||
name: "{{ item }}"
|
||||
enabled: true
|
||||
loop:
|
||||
- pwroff.timer
|
||||
- reporter.timer
|
||||
|
||||
- name: PXE first boot order
|
||||
command: /usr/local/sbin/bootorder.sh
|
||||
register: cmd_result
|
||||
changed_when: cmd_result.stdout is not search('Nothing to do.')
|
||||
when: groups.PCroom is defined and inventory_hostname in groups.PCroom
|
||||
|
||||
- name: Copy dolphin config scripts
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item }}"
|
||||
dest: /usr/local/bin/
|
||||
mode: 0755
|
||||
loop:
|
||||
- lmn-reset-dolphin.sh
|
||||
- lmn-patch-dolphin.sh
|
||||
|
||||
- name: Configure KDE dolphin menu
|
||||
ansible.builtin.copy:
|
||||
src: lmn-dolphin.sh
|
||||
dest: /etc/profile.d/
|
||||
|
||||
|
||||
- name: Copy fvs-config.js to configure plasma
|
||||
ansible.builtin.copy:
|
||||
src: fvs-config.js
|
||||
dest: /usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/fvs-config.js
|
||||
mode: 0644
|
||||
|
||||
|
||||
- name: Configure some KDE aspects
|
||||
blockinfile:
|
||||
path: /etc/xdg/kdeglobals
|
||||
create: true
|
||||
block: |
|
||||
[KDE]
|
||||
SingleClick=false
|
||||
|
||||
[KDE Action Restrictions][$i]
|
||||
action/start_new_session=false
|
||||
#action/switch_user=false
|
||||
#action/lock_screen=false
|
||||
|
||||
- name: Shut down when idle for too long
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/xdg/powermanagementprofilesrc
|
||||
content: |
|
||||
[AC][SuspendSession][$i]
|
||||
idleTime=7200000
|
||||
suspendType=8
|
||||
|
||||
- name: Start with empty session by default
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/xdg/ksmserverrc
|
||||
content: |
|
||||
[General]
|
||||
loginMode=emptySession
|
||||
|
||||
- name: Fix primary screen for class room PCs with projector
|
||||
block:
|
||||
- name: Switch projector off for login
|
||||
lineinfile:
|
||||
dest: /usr/share/sddm/scripts/Xsetup
|
||||
line: 'xrandr --output {{ dual_screen[0] }} --off'
|
||||
- name: Deploy fix-screen script
|
||||
ansible.builtin.template:
|
||||
src: lmn-fix-screen.j2
|
||||
dest: /usr/local/bin/lmn-fix-screen
|
||||
mode: '0755'
|
||||
- name: Deploy fix-screen autostarter
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/xdg/autostart/lmn-fix-screen.desktop
|
||||
content: |
|
||||
[Desktop Entry]
|
||||
Name=fix-screen
|
||||
Exec=lmn-fix-screen
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
when: dual_screen is defined
|
||||
|
||||
#- name: Avoid starting kscreen (confusing autodetection)
|
||||
# ansible.builtin.copy:
|
||||
# dest: /etc/xdg/kded5rc
|
||||
# content: |
|
||||
# [Module-kscreen]
|
||||
# autoload=false
|
||||
#
|
||||
#- name: Disable automatic lock screen and user specific modifications
|
||||
# ansible.builtin.copy:
|
||||
# path: /etc/xdg/kscreenlockerrc
|
||||
# content: |
|
||||
# [Daemon][$i]
|
||||
# Autolock=false
|
||||
# LockOnResume=false
|
||||
#
|
||||
|
||||
- name: Download libdvdcss from mirror
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ mirror_dvdcss }}/libdvdcss.so.2.2.0"
|
||||
dest: /usr/lib/x86_64-linux-gnu/libdvdcss.so.2.2.0
|
||||
use_proxy: False
|
||||
when: mirror_dvdcss is defined and mirror_dvdcss | length > 0
|
||||
|
||||
- name: Link library so name
|
||||
ansible.builtin.file:
|
||||
src: libdvdcss.so.2.2.0
|
||||
dest: /usr/lib/x86_64-linux-gnu/libdvdcss.so.2
|
||||
state: link
|
||||
when: mirror_dvdcss is defined and mirror_dvdcss | length > 0
|
||||
|
||||
- name: Patch sddm login screen to show hostname
|
||||
blockinfile:
|
||||
path: /usr/share/sddm/themes/debian-breeze/Main.qml
|
||||
marker: // {mark} ANSIBLE MANAGED BLOCK
|
||||
insertbefore: '\s+//Footer'
|
||||
block: |
|
||||
Text {
|
||||
id: hostname
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 10
|
||||
anchors.rightMargin: 15
|
||||
color: "#ffffff"
|
||||
text: sddm.hostName + " | <{{ ansible_date_time['date'] }}>"
|
||||
font.pointSize: config.fontSize
|
||||
}
|
10
roles/lmn_fvs/templates/lmn-fix-screen.j2
Normal file
10
roles/lmn_fvs/templates/lmn-fix-screen.j2
Normal file
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/bash
|
||||
#
|
||||
# Set the primary screen after login
|
||||
#
|
||||
set -eu
|
||||
|
||||
sleep 5
|
||||
if [[ "$XDG_SESSION_TYPE" = wayland ]] ; then
|
||||
kscreen-doctor output.{{ dual_screen[1] }}.priority.1
|
||||
fi
|
32
roles/lmn_kde/files/lmn-fix-dolphin.sh
Executable file
32
roles/lmn_kde/files/lmn-fix-dolphin.sh
Executable file
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/bash
|
||||
#
|
||||
# Dolphin keeps old paths after modifications.
|
||||
# Run with '--do-it' to really make the change.
|
||||
#
|
||||
set -eu
|
||||
|
||||
do="${1:-}"
|
||||
|
||||
bmk=".local/share/user-places.xbel"
|
||||
rt="/srv/samba/schools/default-school/students"
|
||||
|
||||
extract() {
|
||||
local grp="$1"
|
||||
grp="${grp##*${rt}/}"
|
||||
grp="${grp%%/*}"
|
||||
echo $grp
|
||||
}
|
||||
|
||||
for f in $(find $rt/*/*/$bmk) ; do
|
||||
cor="$(extract $f)"
|
||||
for l in "$(grep "$rt" "$f")" ; do
|
||||
fnd="$(extract "$l")"
|
||||
if [[ "$cor" != "$fnd" ]] ; then
|
||||
echo "Check ${f##*${rt}/}: '$cor' != '$fnd'."
|
||||
if [[ "$do" = "--do-it" ]] ; then
|
||||
sed -i.lmn-fix-path "s|$rt/$fnd|$rt/$cor|g" "$f"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
2
roles/lmn_kde/handlers/main.yml
Normal file
2
roles/lmn_kde/handlers/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
- name: Run update-grub
|
||||
command: update-grub
|
170
roles/lmn_kde/tasks/main.yml
Normal file
170
roles/lmn_kde/tasks/main.yml
Normal file
|
@ -0,0 +1,170 @@
|
|||
---
|
||||
- name: Install desktop and educational packages
|
||||
apt:
|
||||
name:
|
||||
- akonadi-backend-sqlite
|
||||
- arduino
|
||||
- bluefish
|
||||
- calligra
|
||||
- codeblocks
|
||||
- dia
|
||||
- flameshot
|
||||
- freecad
|
||||
- fritzing
|
||||
- ghex
|
||||
- gimp
|
||||
- inkscape
|
||||
- kde-full
|
||||
- keepassxc
|
||||
- librecad
|
||||
- mu-editor
|
||||
- openboard
|
||||
- qtcreator
|
||||
- spyder
|
||||
- sqlite3
|
||||
- sqlitebrowser
|
||||
- task-german-desktop
|
||||
- task-german-kde-desktop
|
||||
- task-kde-desktop
|
||||
- thonny
|
||||
- thunderbird-l10n-de
|
||||
- vlc
|
||||
- vym
|
||||
- webext-privacy-badger
|
||||
- webext-ublock-origin-chromium
|
||||
- webext-ublock-origin-firefox
|
||||
- xdg-desktop-portal-kde
|
||||
- xdg-desktop-portal-wlr # share screen in browser
|
||||
- xournalpp
|
||||
autoremove: true
|
||||
state: latest
|
||||
|
||||
- name: Add {{ ansible_distribution_release }}-backports
|
||||
apt_repository:
|
||||
repo: deb http://deb.debian.org/debian/ {{ ansible_distribution_release }}-backports main non-free-firmware
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Install extra packages from backports
|
||||
apt:
|
||||
name:
|
||||
- filius
|
||||
- kicad
|
||||
- kicad-doc-de
|
||||
- libreoffice
|
||||
- libreoffice-l10n-de
|
||||
state: latest # noqa package-latest
|
||||
autoremove: true
|
||||
default_release: "{{ ansible_distribution_release }}-backports"
|
||||
|
||||
|
||||
- name: Create akonadi config dir
|
||||
ansible.builtin.file:
|
||||
path: /etc/xdg/akonadi/
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Use sqlite in akonadi
|
||||
blockinfile:
|
||||
path: /etc/xdg/akonadi/akonadiserverrc
|
||||
create: true
|
||||
block: |
|
||||
[%General]
|
||||
Driver=QSQLITE3
|
||||
|
||||
## Akonadi complains if not set:
|
||||
- name: Add home dirs to apparmor
|
||||
lineinfile:
|
||||
dest: /etc/apparmor.d/tunables/home.d/ubuntu
|
||||
line: >-
|
||||
@{HOMEDIRS}+=/srv/samba/schools/default-school/teachers/
|
||||
/srv/samba/schools/default-school/students/*/
|
||||
/srv/samba/schools/default-school/examusers/
|
||||
|
||||
|
||||
- name: tune SDDM login
|
||||
blockinfile:
|
||||
path: /etc/sddm.conf
|
||||
create: true
|
||||
block: |
|
||||
[Users]
|
||||
MaximumUid=999
|
||||
RememberLastUser=false
|
||||
RememberLastSession=false
|
||||
|
||||
- name: Enable wake-on-lan for all ethernet connections
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/NetworkManager/conf.d/wake-on-lan.conf
|
||||
content: |
|
||||
[connection]
|
||||
ethernet.wake-on-lan=64
|
||||
|
||||
- name: Create directory to avoid suspend
|
||||
ansible.builtin.file:
|
||||
path: /etc/systemd/sleep.conf.d/
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Avoid suspending
|
||||
blockinfile:
|
||||
path: /etc/systemd/sleep.conf.d/nosuspend.conf
|
||||
create: true
|
||||
block: |
|
||||
[Sleep]
|
||||
AllowSuspend=no
|
||||
AllowHibernation=no
|
||||
AllowSuspendThenHibernate=no
|
||||
AllowHybridSleep=no
|
||||
|
||||
- name: Deploy dolphin script
|
||||
copy:
|
||||
src: lmn-fix-dolphin.sh
|
||||
dest: /usr/local/bin/
|
||||
mode: '0755'
|
||||
|
||||
################# general settings ##################
|
||||
- name: Enable boot splash screen
|
||||
replace:
|
||||
dest: "/etc/default/grub"
|
||||
regexp: '"quiet"$'
|
||||
replace: '"quiet splash"'
|
||||
notify: Run update-grub
|
||||
|
||||
- name: Protect editing grub menu entries
|
||||
blockinfile:
|
||||
path: /etc/grub.d/40_custom
|
||||
block: |
|
||||
set superusers='root'
|
||||
export superusers
|
||||
password_pbkdf2 root {{ grub_pwd }}
|
||||
notify: Run update-grub
|
||||
|
||||
- name: Allow booting grub menu entries
|
||||
lineinfile:
|
||||
dest: /etc/grub.d/10_linux
|
||||
line: CLASS="${CLASS} --unrestricted"
|
||||
insertafter: '^CLASS=.*'
|
||||
firstmatch: true
|
||||
notify: Run update-grub
|
||||
|
||||
- name: Disable Grub submenus
|
||||
lineinfile:
|
||||
dest: /etc/default/grub
|
||||
line: 'GRUB_DISABLE_SUBMENU=true'
|
||||
insertafter: '^GRUB_TIMEOUT=.*'
|
||||
notify: Run update-grub
|
||||
|
||||
- name: Grub timeout
|
||||
lineinfile:
|
||||
dest: /etc/default/grub
|
||||
regexp: '^(GRUB_TIMEOUT=).*'
|
||||
line: '\g<1>1'
|
||||
backrefs: yes
|
||||
notify: Run update-grub
|
||||
|
||||
- name: Keyboard compose key
|
||||
lineinfile:
|
||||
dest: /etc/default/keyboard
|
||||
regexp: '^(XKBOPTIONS=).*'
|
||||
line: '\1"compose:caps"'
|
||||
backrefs: yes
|
28
roles/lmn_localuser/tasks/main.yml
Normal file
28
roles/lmn_localuser/tasks/main.yml
Normal file
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
- name: Mount tmpfs on /home/{{ localuser }}
|
||||
ansible.posix.mount:
|
||||
name: /home/{{ localuser }}
|
||||
src: tmpfs
|
||||
fstype: tmpfs
|
||||
opts: uid=1001,gid=1001,mode=755,size=4G
|
||||
state: mounted
|
||||
|
||||
- name: Add local guest user
|
||||
ansible.builtin.user:
|
||||
name: "{{ localuser }}"
|
||||
comment: "Local Guest User,,,"
|
||||
shell: /bin/bash
|
||||
uid: 1001
|
||||
password_expire_min: 99999
|
||||
createhome: false
|
||||
password: "{{ localuser_pwd }}"
|
||||
|
||||
- name: Prepare generator for local guest user
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/user-environment-generators/60-guest-user.sh
|
||||
content: |
|
||||
#!/usr/bin/bash
|
||||
set -eu
|
||||
[[ "$UID" -ne 1001 ]] && exit 0
|
||||
cp -r -n /etc/skel/.* "$HOME"
|
||||
mode: "0755"
|
2
roles/lmn_mount/defaults/main.yml
Normal file
2
roles/lmn_mount/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
smb_server: "server"
|
||||
smb_share: "default-school/"
|
4
roles/lmn_mount/files/lmn-linkhome.sh
Normal file
4
roles/lmn_mount/files/lmn-linkhome.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
if [[ "${UID}" -gt 60000 ]]; then
|
||||
[[ -L "/lmn/media/${USER}/share" ]] || ln -s .default-school/share "/lmn/media/${USER}/share"
|
||||
[[ -L "/lmn/media/${USER}/home" ]] || ln -s ".default-school/${HOME##/srv/samba/schools/default-school/}" "/lmn/media/${USER}/home"
|
||||
fi
|
3
roles/lmn_mount/files/lmn-mounthome.sh
Normal file
3
roles/lmn_mount/files/lmn-mounthome.sh
Normal file
|
@ -0,0 +1,3 @@
|
|||
if [[ "${UID}" -gt 60000 ]]; then
|
||||
sudo /usr/local/bin/mounthome.sh &
|
||||
fi
|
102
roles/lmn_mount/tasks/main.yml
Normal file
102
roles/lmn_mount/tasks/main.yml
Normal file
|
@ -0,0 +1,102 @@
|
|||
---
|
||||
- name: Install needed packages
|
||||
apt:
|
||||
name:
|
||||
- libpam-mount
|
||||
- cifs-utils
|
||||
- nfs-common
|
||||
- hxtools
|
||||
- davfs2
|
||||
state: latest
|
||||
|
||||
- name: Configure pam_mount for Webdav Nextcloud
|
||||
blockinfile:
|
||||
dest: /etc/security/pam_mount.conf.xml
|
||||
marker: "<!-- {mark} ANSIBLE MANAGED BLOCK (mount Nextcloud) -->"
|
||||
block: |
|
||||
<volume
|
||||
fstype="davfs"
|
||||
path="{{ web_dav }}"
|
||||
mountpoint="/lmn/media/%(USER)/nextcloud"
|
||||
options="username=%(USER),nosuid,nodev,uid=%(USER),gid=1010,grpid,file_mode=0770,dir_mode=0770,forceuid,forcegid"
|
||||
><not><or><user>root</user><user>ansible</user><user>Debian-gdm</user><user>sddm</user><user>{{ localuser }}</user></or></not>
|
||||
</volume>
|
||||
insertafter: "<!-- Volume definitions -->"
|
||||
when: web_dav is defined and web_dav | length > 0
|
||||
|
||||
- name: Configure pam_mount for LMN homes
|
||||
blockinfile:
|
||||
dest: /etc/security/pam_mount.conf.xml
|
||||
marker: "<!-- {mark} ANSIBLE MANAGED BLOCK (mount LMN home) -->"
|
||||
block: |
|
||||
<volume
|
||||
fstype="cifs"
|
||||
server="{{ smb_server }}"
|
||||
path="{{ smb_share }}"
|
||||
mountpoint="/srv/samba/schools/default-school"
|
||||
options="sec=krb5i,cruid=%(USERUID),user=%(USER),gid=1010,file_mode=0770,dir_mode=0770,mfsymlinks,nobrl,actimeo=600{{ cifsopt | default(",cache=loose") }}"
|
||||
><not><or><user>root</user><user>ansible</user><user>Debian-gdm</user><user>sddm</user><user>{{ localuser }}</user></or></not>
|
||||
</volume>
|
||||
insertafter: "<!-- Volume definitions -->"
|
||||
|
||||
- name: Prepare mount point for homes
|
||||
ansible.builtin.file:
|
||||
path: /srv/samba/schools/default-school/
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Prepare persistent user cache base directory
|
||||
ansible.builtin.file:
|
||||
path: /var/cache/user/
|
||||
state: directory
|
||||
mode: '1777'
|
||||
|
||||
- name: Create user-environment-generator directory
|
||||
ansible.builtin.file:
|
||||
path: /etc/systemd/user-environment-generators/
|
||||
state: directory
|
||||
|
||||
- name: Prepare generator for persistent user cache directory
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/user-environment-generators/50-xdg-cache-home.sh
|
||||
content: |
|
||||
#!/usr/bin/bash
|
||||
set -eu
|
||||
## local users do not need the extra cache dir:
|
||||
[[ "$UID" -le 60000 ]] && exit 0
|
||||
cp -r -n /etc/skel/.* "$HOME"
|
||||
DIR="/var/cache/user/${UID}/"
|
||||
[[ -d "$DIR" ]] || mkdir -m 0700 "$DIR"
|
||||
echo XDG_CACHE_HOME="$DIR"
|
||||
echo JUPYTER_ALLOW_INSECURE_WRITES=1
|
||||
mode: "0755"
|
||||
|
||||
|
||||
- name: Clean up all user processes after logout
|
||||
ansible.builtin.replace:
|
||||
path: /etc/security/pam_mount.conf.xml
|
||||
regexp: '^(<logout wait="0" hup="no" term="no" kill="no" />)$'
|
||||
replace: '<!-- \1 -->\n<logout wait="1000" hup="yes" term="yes" kill="yes" />'
|
||||
|
||||
- name: Kill all user processes on logout
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/systemd/logind.conf
|
||||
line: KillUserProcesses=yes
|
||||
insertafter: '#KillUserProcesses=no'
|
||||
|
||||
- name: Bind mount /lmn/media with nosuid directory
|
||||
ansible.posix.mount:
|
||||
src: /lmn/media
|
||||
path: /lmn/media
|
||||
opts: nosuid,bind
|
||||
state: present
|
||||
fstype: none
|
||||
|
||||
- name: Mount NFSv4 home directory
|
||||
ansible.posix.mount:
|
||||
src: server:/default-school
|
||||
path: /srv/samba/schools/default-school
|
||||
opts: sec=krb5p,_netdev,x-systemd.automount,x-systemd.idle-timeout=60
|
||||
state: present
|
||||
fstype: nfs4
|
||||
when: nfs4
|
29
roles/lmn_network/tasks/main.yml
Normal file
29
roles/lmn_network/tasks/main.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
- name: Deploy http proxy config
|
||||
copy:
|
||||
dest: /etc/environment.d/10-lmn-proxy.conf
|
||||
content: |
|
||||
http_proxy="{{ proxy }}"
|
||||
https_proxy="{{ proxy }}"
|
||||
ftp_proxy="{{ proxy }}"
|
||||
no_proxy="{{ no_proxy }}"
|
||||
|
||||
- name: Set aptcache
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/apt/apt.conf
|
||||
content: >
|
||||
{{ apt_conf }}
|
||||
|
||||
- name: Set NTP server
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/systemd/timesyncd.conf
|
||||
insertafter: '^#NTP='
|
||||
line: NTP={{ ntp_serv }}
|
||||
|
||||
- name: Add proposed-updates repository
|
||||
apt_repository:
|
||||
repo: >
|
||||
deb http://deb.debian.org/debian/ {{ ansible_distribution_release }}-proposed-updates
|
||||
main non-free-firmware
|
||||
state: present
|
||||
when: groups.R202 is defined and inventory_hostname in groups.R202
|
90
roles/lmn_networkd/tasks/main.yml
Normal file
90
roles/lmn_networkd/tasks/main.yml
Normal file
|
@ -0,0 +1,90 @@
|
|||
---
|
||||
# temporary disable network manager
|
||||
- name: Use iwd but ignore interfaces managed by systemd-networkd (wlan0,en*)
|
||||
blockinfile:
|
||||
dest: /etc/NetworkManager/NetworkManager.conf
|
||||
block: |
|
||||
[device]
|
||||
match-device=interface-name:wlx*
|
||||
wifi.backend=iwd
|
||||
[connection]
|
||||
match-device=interface-name:wlx*
|
||||
ipv4.route-metric=2048
|
||||
[keyfile]
|
||||
unmanaged-devices=interface-name:wlan0;interface-name:en*;interface-name:vm*
|
||||
|
||||
- name: Enable Networkmanager
|
||||
ansible.builtin.systemd:
|
||||
name: NetworkManager.service
|
||||
#state: started
|
||||
enabled: true
|
||||
|
||||
- name: Configure systemd-networkd virbr1.netdev
|
||||
ansible.builtin.copy:
|
||||
dest: "/etc/systemd/network/30-{{ item }}.netdev"
|
||||
content: |
|
||||
[NetDev]
|
||||
Name={{ item }}
|
||||
Kind=bridge
|
||||
loop:
|
||||
- virbr1
|
||||
- virbr2
|
||||
|
||||
- name: Set MAC-Address of virtio1 to ethernet nic
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/systemd/network/30-virbr1.netdev
|
||||
line: "MACAddress={{ ansible_facts[ansible_interfaces | select('search', '^en.*') | first].macaddress }}"
|
||||
when: ansible_interfaces | select('search', '^en.*')
|
||||
|
||||
- name: Configure systemd-networkd ethernet.network
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/network/40-ethernet.network
|
||||
content: |
|
||||
[Match]
|
||||
Name=enp*
|
||||
[Network]
|
||||
Bridge=virbr1
|
||||
|
||||
- name: Configure systemd-networkd ethernet-usb.network
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/network/40-ethernet-usb.network
|
||||
content: |
|
||||
[Match]
|
||||
Name=enx*
|
||||
[Network]
|
||||
Bridge=virbr2
|
||||
|
||||
- name: Configure systemd-networkd virbr1.network
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/network/50-virbr1.network
|
||||
content: |
|
||||
[Match]
|
||||
Name=virbr1
|
||||
[Network]
|
||||
DHCP=yes
|
||||
[DHCPv4]
|
||||
UseDomains=true
|
||||
RouteMetric=512
|
||||
|
||||
- name: Configure systemd-networkd virbr2.network
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/network/50-virbr2.network
|
||||
content: |
|
||||
[Match]
|
||||
Name=virbr2
|
||||
[Network]
|
||||
DHCP=yes
|
||||
[DHCPv4]
|
||||
UseDomains=false
|
||||
RouteMetric=2048
|
||||
|
||||
- name: Configure systemd-networkd wlan.network
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/network/60-wlan0-dhcp.network
|
||||
content: |
|
||||
[Match]
|
||||
Name=wlan0
|
||||
[Network]
|
||||
DHCP=yes
|
||||
[DHCPv4]
|
||||
UseDomains=true
|
3
roles/lmn_printer/files/90-lmn-install-printers
Normal file
3
roles/lmn_printer/files/90-lmn-install-printers
Normal file
|
@ -0,0 +1,3 @@
|
|||
%examusers ALL=(root) NOPASSWD: /usr/local/bin/install-printers.sh
|
||||
%role-student ALL=(root) NOPASSWD: /usr/local/bin/install-printers.sh
|
||||
%role-teacher ALL=(root) NOPASSWD: /usr/local/bin/install-printers.sh
|
59
roles/lmn_printer/tasks/main.yml
Normal file
59
roles/lmn_printer/tasks/main.yml
Normal file
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
- name: Install cups
|
||||
apt:
|
||||
name:
|
||||
- cups
|
||||
state: latest
|
||||
|
||||
- name: Disable cups printer browsing
|
||||
lineinfile:
|
||||
dest: /etc/cups/cupsd.conf
|
||||
regexp: '^(Browsing ).*'
|
||||
line: '\1No'
|
||||
backrefs: yes
|
||||
|
||||
- name: Listen on VMBridge
|
||||
lineinfile:
|
||||
dest: /etc/cups/cupsd.conf
|
||||
line: 'Listen 192.168.122.1:631'
|
||||
insertafter: 'Listen localhost:631'
|
||||
state: present
|
||||
|
||||
- name: Allow access from localhost and from VM
|
||||
blockinfile:
|
||||
dest: /etc/cups/cupsd.conf
|
||||
block: |
|
||||
Allow localhost
|
||||
Allow 192.168.122.0/24
|
||||
insertafter: "<Location {{ item }}>"
|
||||
marker: "# {mark} ANSIBLE MANAGED BLOCK {{ item }}"
|
||||
state: present
|
||||
loop:
|
||||
- "/"
|
||||
- "/admin"
|
||||
|
||||
- name: Disable cups-browsed
|
||||
ansible.builtin.systemd:
|
||||
name: cups-browsed.service
|
||||
state: stopped
|
||||
enabled: no
|
||||
|
||||
- name: Install install-printers.sh
|
||||
template:
|
||||
src: install-printers.sh.j2
|
||||
dest: /usr/local/bin/install-printers.sh
|
||||
mode: 0755
|
||||
|
||||
- name: Install lmn-install-printers sudoers
|
||||
copy:
|
||||
src: 90-lmn-install-printers
|
||||
dest: /etc/sudoers.d/
|
||||
mode: 0660
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Run printer script from /etc/profile.d/
|
||||
copy:
|
||||
dest: /etc/profile.d/lmn-printer.sh
|
||||
content: |
|
||||
[[ "${UID}" -gt 10000 ]] && (sudo /usr/local/bin/install-printers.sh > /dev/null &)
|
48
roles/lmn_printer/templates/install-printers.sh.j2
Normal file
48
roles/lmn_printer/templates/install-printers.sh.j2
Normal file
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
printservers="{{ printservers | join(' ') }}"
|
||||
hostgroup="$(id -Gn "${HOSTNAME^^}$")"
|
||||
usergroup="$(id -Gn "${SUDO_USER}")"
|
||||
installedprinters="$(lpstat -p | cut -f 2 -d" ")"
|
||||
|
||||
cat <<EOF
|
||||
Hostgroups: ${hostgroup}
|
||||
Usergroups: ${usergroup}
|
||||
Local print queues:
|
||||
${installedprinters}
|
||||
|
||||
EOF
|
||||
|
||||
## Remove all printers not wanted:
|
||||
for p in $installedprinters ; do
|
||||
if [[ ! "${hostgroup}" =~ "$p" ]] && [[ ! "${usergroup}" =~ "$p" ]] ; then
|
||||
echo "Removing print queue '$p'."
|
||||
lpadmin -x "$p"
|
||||
fi
|
||||
done
|
||||
|
||||
## Prepare .printerlist.csv
|
||||
mkdir -p "/lmn/media/${SUDO_USER}"
|
||||
echo "Name;IppURL" > "/lmn/media/${SUDO_USER}/.printerlist.csv"
|
||||
|
||||
## Add all printers needed:
|
||||
for ps in $printservers ; do
|
||||
echo "Checking print server '$ps' for available printers:"
|
||||
printers="$(lpstat -h "$ps" -U "${SUDO_USER}" -v | sed -E 's/^.+ (\w+): .+$/\1/')"
|
||||
echo -e "$printers\n"
|
||||
for p in $printers; do
|
||||
if [[ "${hostgroup}" =~ "$p" ]] || [[ "${usergroup}" =~ "$p" ]] ; then
|
||||
if [[ "$installedprinters" =~ "$p" ]] ; then
|
||||
echo "Print queue '$p' already available."
|
||||
else
|
||||
echo "Adding print queue '$p'."
|
||||
timeout 10 lpadmin -p "$p" -E -v \
|
||||
"ipp://$ps/printers/$p" \
|
||||
-m "driverless:ipp://$ps/printers/$p" || echo "Adding queue '$p' failed."
|
||||
fi
|
||||
echo "$p;ipp://192.168.122.1/printers/$p" >> "/lmn/media/${SUDO_USER}/.printerlist.csv"
|
||||
fi
|
||||
done
|
||||
done
|
5
roles/lmn_security/handlers/main.yml
Normal file
5
roles/lmn_security/handlers/main.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
- name: Reload sshd
|
||||
systemd:
|
||||
name: sshd
|
||||
state: reloaded
|
||||
when: not run_in_installer|default(false)|bool
|
29
roles/lmn_security/tasks/main.yml
Normal file
29
roles/lmn_security/tasks/main.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
- name: Deploy SSH keys
|
||||
ansible.posix.authorized_key:
|
||||
user: ansible
|
||||
key: "{{ item }}"
|
||||
loop: "{{ keys2deploy }}"
|
||||
|
||||
- name: Allow sudo without password for ansible
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/sudoers.d/95-lmn-ansible
|
||||
line: 'ansible ALL=(root) NOPASSWD: ALL'
|
||||
create: True
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0700'
|
||||
|
||||
- name: Disable ansible user login
|
||||
ansible.builtin.user:
|
||||
name: ansible
|
||||
password_lock: True
|
||||
|
||||
- name: Limit SSH access to user ansible
|
||||
ansible.builtin.blockinfile:
|
||||
dest: /etc/ssh/sshd_config.d/local.conf
|
||||
create: true
|
||||
block: |
|
||||
PasswordAuthentication no
|
||||
AllowUsers ansible
|
||||
notify: Reload sshd
|
3
roles/lmn_sssd/handlers/main.yml
Normal file
3
roles/lmn_sssd/handlers/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
- name: restart sssd
|
||||
service: name=sssd state=restarted enabled=yes
|
||||
listen: "restart sssd"
|
25
roles/lmn_sssd/tasks/main.yml
Normal file
25
roles/lmn_sssd/tasks/main.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
- name: Install needed packages
|
||||
apt:
|
||||
name:
|
||||
- sssd-ad
|
||||
- sssd-tools
|
||||
- adcli
|
||||
state: latest
|
||||
|
||||
- name: Provide user identities from AD
|
||||
template:
|
||||
src: sssd.conf.j2
|
||||
dest: /etc/sssd/sssd.conf
|
||||
mode: 0600
|
||||
notify: restart sssd
|
||||
|
||||
## Either one of the variables is defined:
|
||||
- name: Join the domain
|
||||
shell:
|
||||
cmd: >
|
||||
echo "{{ ansible_cmdline.adpw | default('') + adpw.user_input | default('') }}" |
|
||||
adcli join --stdin-password -U global-admin {{ domain | upper }}
|
||||
when: >
|
||||
ansible_cmdline.adpw | default('') | length > 0 or
|
||||
adpw.user_input | default('') | length > 0
|
19
roles/lmn_sssd/templates/sssd.conf.j2
Normal file
19
roles/lmn_sssd/templates/sssd.conf.j2
Normal file
|
@ -0,0 +1,19 @@
|
|||
[sssd]
|
||||
domains = {{ domain }}
|
||||
config_file_version = 2
|
||||
implicit_pac_responder = False
|
||||
|
||||
[domain/{{ domain }}]
|
||||
krb5_realm = {{ domain | upper }}
|
||||
ad_domain = {{ domain }}
|
||||
id_provider = ad
|
||||
access_provider = ad
|
||||
use_fully_qualified_names = False
|
||||
cache_credentials = True
|
||||
krb5_store_password_if_offline = True
|
||||
default_shell = /usr/bin/bash
|
||||
# default: # ldap_id_mapping = True
|
||||
ad_gpo_access_control = disabled
|
||||
ad_gpo_ignore_unreadable = True
|
||||
ad_maximum_machine_account_password_age = 0
|
||||
ignore_group_members = True
|
14
roles/lmn_vm/files/desktop-sync
Normal file
14
roles/lmn_vm/files/desktop-sync
Normal file
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/bash
|
||||
#
|
||||
# Synchronize desktop starters
|
||||
#
|
||||
set -eu
|
||||
|
||||
source /etc/lmn/vm.conf
|
||||
RSYNC_COMMAND=$(rsync -ai --delete --exclude=mimeinfo.cache \
|
||||
--chown=root:root --chmod=F644,D755 "${DESKTOPSTARTERDIR}" \
|
||||
/usr/local/share/applications/ | sed '/ \.\//d')
|
||||
if [[ $? -eq 0 ]] && [[ -n "${RSYNC_COMMAND}" ]]; then
|
||||
echo "${RSYNC_COMMAND}"
|
||||
update-desktop-database /usr/local/share/applications
|
||||
fi
|
5
roles/lmn_vm/files/fvs.directory
Normal file
5
roles/lmn_vm/files/fvs.directory
Normal file
|
@ -0,0 +1,5 @@
|
|||
[Desktop Entry]
|
||||
Type=Directory
|
||||
Name=FvS
|
||||
Icon=face-smile-big
|
||||
#X-KDE-BaseGroup=info
|
12
roles/lmn_vm/files/fvs.menu
Normal file
12
roles/lmn_vm/files/fvs.menu
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">
|
||||
<Menu>
|
||||
<Name>Applications</Name>
|
||||
<Menu>
|
||||
<Name>FvS</Name>
|
||||
<Directory>fvs.directory</Directory>
|
||||
<Include>
|
||||
<Category>fvs</Category>
|
||||
</Include>
|
||||
</Menu>
|
||||
</Menu>
|
3
roles/lmn_vm/files/lmn-mounthome
Normal file
3
roles/lmn_vm/files/lmn-mounthome
Normal file
|
@ -0,0 +1,3 @@
|
|||
%examusers ALL=(root) NOPASSWD: /usr/local/bin/mounthome.sh
|
||||
%role-student ALL=(root) NOPASSWD: /usr/local/bin/mounthome.sh
|
||||
%role-teacher ALL=(root) NOPASSWD: /usr/local/bin/mounthome.sh
|
25
roles/lmn_vm/files/lmn-vm
Normal file
25
roles/lmn_vm/files/lmn-vm
Normal file
|
@ -0,0 +1,25 @@
|
|||
# vm-sync: Download and synchronize VM-Images and xml-Files
|
||||
%role-teacher ALL=(lmnsynci) NOPASSWD: /usr/local/bin/vm-sync
|
||||
%role-student ALL=(lmnsynci) NOPASSWD: /usr/local/bin/vm-sync
|
||||
%examusers ALL=(lmnsynci) NOPASSWD: /usr/local/bin/vm-sync
|
||||
|
||||
# vm-aria2: Start/Stop aria2 as systemd-service for VM-Images
|
||||
lmnsynci ALL=(root) NOPASSWD: /usr/local/bin/vm-aria2
|
||||
|
||||
# vm-link-images: Link VM-Images to User-tmp-directory
|
||||
%examusers ALL=(root) NOPASSWD: /usr/local/bin/vm-link-images
|
||||
%role-student ALL=(root) NOPASSWD: /usr/local/bin/vm-link-images
|
||||
%role-teacher ALL=(root) NOPASSWD: /usr/local/bin/vm-link-images
|
||||
|
||||
# vm-virtiofsd: Start Virtiofsd as systemd-service
|
||||
%examusers ALL=(root) NOPASSWD: /usr/local/bin/vm-virtiofsd
|
||||
%role-student ALL=(root) NOPASSWD: /usr/local/bin/vm-virtiofsd
|
||||
%role-teacher ALL=(root) NOPASSWD: /usr/local/bin/vm-virtiofsd
|
||||
|
||||
# desktop-sync:
|
||||
%examusers ALL=(root) NOPASSWD: /usr/local/bin/desktop-sync
|
||||
%role-student ALL=(root) NOPASSWD: /usr/local/bin/desktop-sync
|
||||
%role-teacher ALL=(root) NOPASSWD: /usr/local/bin/desktop-sync
|
||||
|
||||
# vm-upload:
|
||||
%role-teacher ALL=(root) NOPASSWD: /usr/local/bin/vm-upload
|
66
roles/lmn_vm/files/mounthome.sh
Executable file
66
roles/lmn_vm/files/mounthome.sh
Executable file
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/bash
|
||||
set -eu
|
||||
|
||||
home="$(getent passwd "$SUDO_UID" | cut -d : -f 6 | sed 's|/srv/samba/schools/default-school/||')"
|
||||
|
||||
exit_script() {
|
||||
echo "unmounting media - terminated by trap!" >> "/tmp/${SUDO_UID}-exit-mount.log"
|
||||
findmnt "/lmn/media/${SUDO_USER}/oldhome" && umount "/lmn/media/${SUDO_USER}/oldhome" && rmdir "/lmn/media/${SUDO_USER}/oldhome"
|
||||
findmnt "/lmn/media/${SUDO_USER}/oldprojects" && umount "/lmn/media/${SUDO_USER}/oldprojects" && rmdir "/lmn/media/${SUDO_USER}/oldprojects"
|
||||
findmnt "/lmn/media/${SUDO_USER}/linuxhome" && umount "/lmn/media/${SUDO_USER}/linuxhome" && rmdir "/lmn/media/${SUDO_USER}/linuxhome"
|
||||
trap - SIGHUP SIGINT SIGTERM # clear the trap
|
||||
kill -- -$$ # Sends SIGTERM to child/sub processes
|
||||
}
|
||||
|
||||
exit_script_home() {
|
||||
echo "unmounting media - terminated by trap!" >> "/tmp/${SUDO_UID}-exit-mount.log"
|
||||
umount "/lmn/media/${SUDO_USER}/home"
|
||||
trap - SIGHUP SIGINT SIGTERM # clear the trap
|
||||
kill -- -$$ # Sends SIGTERM to child/sub processes
|
||||
}
|
||||
|
||||
##########################
|
||||
|
||||
if [[ "$#" -gt 0 ]] && [[ "$1" = '-u' ]]; then
|
||||
findmnt "/lmn/media/${SUDO_USER}/home" && umount "/lmn/media/${SUDO_USER}/home" && rmdir "/lmn/media/${SUDO_USER}/home"
|
||||
#findmnt "/lmn/media/${SUDO_USER}/share" && umount "/lmn/media/${SUDO_USER}/share" && rmdir "/lmn/media/${SUDO_USER}/share"
|
||||
findmnt "/lmn/media/${SUDO_USER}/oldhome" && umount "/lmn/media/${SUDO_USER}/oldhome" && rmdir "/lmn/media/${SUDO_USER}/oldhome"
|
||||
findmnt "/lmn/media/${SUDO_USER}/oldprojects" && umount "/lmn/media/${SUDO_USER}/oldprojects" && rmdir "/lmn/media/${SUDO_USER}/oldprojects"
|
||||
findmnt "/lmn/media/${SUDO_USER}/linuxhome" && umount "/lmn/media/${SUDO_USER}/linuxhome" && rmdir "/lmn/media/${SUDO_USER}/linuxhome"
|
||||
elif [ "$#" -gt 0 ] && [ "$1" = '-o' ]; then
|
||||
echo "Einbinden der Daten des alten/bisherigen Systems (PaedML Novell)."
|
||||
echo "Bitte den Username und Passwort aus dem ALTEN System eingeben."
|
||||
read -rp "Username: " username
|
||||
read -srp "Passwort: " PASSWD
|
||||
export PASSWD
|
||||
echo
|
||||
mkdir -p "/lmn/media/${SUDO_USER}/oldhome"
|
||||
mkdir -p "/lmn/media/${SUDO_USER}/oldprojects"
|
||||
#errcode=$(mount -t cifs -o "username=${username},uid=${SUDO_UID},gid=1010,file_mode=0770,dir_mode=0770,forceuid,forcegid" \
|
||||
# "//192.168.1.2/DOCS/fvs" "/lmn/media/${SUDO_USER}/oldhome")
|
||||
#if [[ ! "${errcode}" ]]; then
|
||||
mount -t cifs -o "username=${username},uid=${SUDO_UID},gid=1010,file_mode=0770,dir_mode=0770,forceuid,forcegid,nobrl,mfsymlinks" \
|
||||
"//192.168.1.2/DOCS/fvs" "/lmn/media/${SUDO_USER}/oldhome"
|
||||
mount -t cifs -o "username=${username},uid=${SUDO_UID},gid=1010,file_mode=0770,dir_mode=0770,forceuid,forcegid,nobrl,mfsymlinks" \
|
||||
"//192.168.1.2/DATA/fvs/projekte" "/lmn/media/${SUDO_USER}/oldprojects"
|
||||
#echo "Mounting successfull!"
|
||||
echo "Einbindung erfolgreich!"
|
||||
echo "Dieses Fenster bitte nicht schließen!"
|
||||
#echo "Um weiter zu arbeiten: <Strg> + <Z>"
|
||||
trap exit_script SIGHUP SIGINT SIGTERM
|
||||
sleep infinity
|
||||
elif [ "$#" -gt 0 ] && [ "$1" = '-l' ]; then
|
||||
echo "Einbinden des Netboot-Home-Verzeichnises. Daten des alten/bisherigen Systems (PaedML Novell)."
|
||||
echo "Bitte den Username und Passwort aus dem ALTEN System (PaedML Novell) eingeben."
|
||||
echo "Bitte auch Groß- und Kleinschreibung achten."
|
||||
read -rp "Username: " username
|
||||
mkdir -p "/lmn/media/${SUDO_USER}/linuxhome"
|
||||
mount -t fuse -o "allow_other,uid=${SUDO_UID},gid=1010,reconnect" \
|
||||
"sshfs#${username}@home.steinbeisschule-reutlingen.de:" "/lmn/media/${SUDO_USER}/linuxhome"
|
||||
#echo "Mounting successfull!"
|
||||
echo "Einbindung erfolgreich!"
|
||||
echo "Dieses Fenster bitte nicht schließen!"
|
||||
#echo "Um weiter zu arbeiten: <Strg> + <Z>"
|
||||
trap exit_script SIGHUP SIGINT SIGTERM
|
||||
sleep infinity
|
||||
fi
|
42
roles/lmn_vm/files/pam-umount.sh
Normal file
42
roles/lmn_vm/files/pam-umount.sh
Normal file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/bash
|
||||
#
|
||||
# <umount>/usr/local/sbin/pam-umount.sh %(USER) %(USERUID) %(MNTPT)</umount>'
|
||||
|
||||
set -eu
|
||||
|
||||
usr="$1"
|
||||
uid="$2"
|
||||
mtp="$3"
|
||||
slce="system-virtiofs.slice"
|
||||
slp=false
|
||||
|
||||
shutdownVMs(){
|
||||
local VM
|
||||
for VM in $(sudo -u $usr XDG_RUNTIME_DIR="/run/user/$uid" \
|
||||
XDG_CONFIG_HOME="/tmp/$uid/.config/" \
|
||||
XDG_CACHE_HOME="/var/cache/user/$uid/" \
|
||||
virsh list --state-running | \
|
||||
sed -nE "s/.*\s+(\S+)\s+running/\1/p") ; do
|
||||
sudo -u $usr XDG_RUNTIME_DIR="/run/user/$uid" \
|
||||
XDG_CONFIG_HOME="/tmp/$uid/.config/" \
|
||||
XDG_CACHE_HOME="/var/cache/user/$uid/" \
|
||||
virsh destroy "$VM" 2>&1 | systemd-cat || true
|
||||
slp=true
|
||||
done
|
||||
}
|
||||
|
||||
######################
|
||||
|
||||
## This is the first mount we need to get rid of:
|
||||
if [[ "$mtp" =~ "/lmn/media/$usr/share" ]] && [[ -d "/run/user/$uid" ]] ; then
|
||||
shutdownVMs
|
||||
[[ "$slp" = true ]] && sleep 5 # leave some time to write caches …
|
||||
sudo -u ${usr} killall gvfsd | systemd-cat
|
||||
sudo -u ${usr} killall dbus-daemon | systemd-cat
|
||||
systemctl -q is-active "$slce" && systemctl kill "$slce"
|
||||
# debug to find processes blocking umount:
|
||||
# lsof >> /var/log/lsof.log
|
||||
fi
|
||||
|
||||
## Just umount:
|
||||
exec umount "$mtp"
|
2
roles/lmn_vm/files/pulseaudio-override.conf
Normal file
2
roles/lmn_vm/files/pulseaudio-override.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
[Service]
|
||||
Environment=HOME=/tmp/pulse.%u
|
158
roles/lmn_vm/files/sync-vm.sh
Executable file
158
roles/lmn_vm/files/sync-vm.sh
Executable file
|
@ -0,0 +1,158 @@
|
|||
#!/usr/bin/bash
|
||||
# Push VM-Disk-Image on server
|
||||
set -eu
|
||||
|
||||
show_help() {
|
||||
cat << EOF >&2
|
||||
Usage: $(basename "$0") [-d] [-a] [-t] [vmnames]"
|
||||
Images from vmnames-List will be synced from server. Default by torrent.
|
||||
Using flag -d VMs will be synced by rsync
|
||||
Using flag -a images from images.list and xml-directory will be synced from server.
|
||||
Using flag -t all torrents and xml-VM-Definitions will be synced
|
||||
EOF
|
||||
}
|
||||
|
||||
download_image() {
|
||||
rsync -av "rsync://server:/vmimages-download/${VM_NAME}.qcow2" \
|
||||
/lmn/vm/
|
||||
rsync -av "rsync://server:/vmimages-download/${VM_NAME}.xml" \
|
||||
/lmn/vm/
|
||||
rsync -av "rsync://server:/vmimages-download/${VM_NAME}.qcow2.torrent" \
|
||||
/lmn/vm/
|
||||
/usr/local/bin/vmimage-torrent restart "${VM_NAME}.qcow2"
|
||||
}
|
||||
|
||||
torrent_image() {
|
||||
if [[ ! -f "/lmn/vm/${VM_NAME}.qcow2.torrent" ]]; then
|
||||
echo "No torrent-File found"
|
||||
exit 1
|
||||
fi
|
||||
lockfile="/tmp/sync-vm-${VM_NAME}.lock"
|
||||
if ! flock -n "$lockfile" echo "try to acquire lock"; then
|
||||
echo torrent seems to be in process.
|
||||
echo waiting for completion ...
|
||||
flock -w 3600 "$lockfile" echo "...completed"
|
||||
sleep 5
|
||||
else
|
||||
(
|
||||
if ! flock -n 200; then
|
||||
echo "failed to acquire lock"
|
||||
echo "Bitte noch einmal starten."
|
||||
echo "Beliebige Taste zum Beenden."
|
||||
read -n 1
|
||||
exit 1
|
||||
fi
|
||||
torrent="${VM_NAME}.qcow2.torrent"
|
||||
session="${torrent//./_}"
|
||||
if vmimage-torrent status | grep -qw ^"$session"; then
|
||||
vmimage-torrent stop "${VM_NAME}.qcow2"
|
||||
fi
|
||||
cd /lmn/vm
|
||||
ctorrent -e 0 "${VM_NAME}.qcow2.torrent"
|
||||
/usr/local/bin/vmimage-torrent restart "${VM_NAME}.qcow2"
|
||||
if ! flock -u 200; then
|
||||
echo failed to drop lock
|
||||
exit 1
|
||||
fi
|
||||
) 200>"$lockfile"
|
||||
fi
|
||||
}
|
||||
|
||||
sync_all_images() {
|
||||
rsync -av --files-from=/lmn/vm/images.list \
|
||||
rsync://server:/vmimages-download/ /lmn/vm/
|
||||
rsync -av rsync://server:/vmimages-download/*.xml \
|
||||
/lmn/vm/
|
||||
}
|
||||
|
||||
delete_old_qcows() {
|
||||
cd /lmn/vm
|
||||
for qcow2 in $(find . -maxdepth 1 -name "*.qcow2" -exec basename {} ';'); do
|
||||
qcowsize=$(stat -c%s "${qcow2}")
|
||||
if [[ -f "${qcow2}.size" ]] && [[ "${qcowsize}" != $(<"${qcow2}.size") ]]; then
|
||||
torrent="${qcow2}.torrent"
|
||||
session="${torrent//./_}"
|
||||
if vmimage-torrent status | grep -qw ^"$session"; then
|
||||
vmimage-torrent stop "${qcow2}"
|
||||
fi
|
||||
mv "${qcow2}" /tmp/
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
sync_all_torrents() {
|
||||
rsync -ai rsync://server:/vmimages-download/*.torrent /lmn/vm/
|
||||
rsync -ai rsync://server:/vmimages-download/*.size /lmn/vm/
|
||||
delete_old_qcows
|
||||
rsync -ai rsync://server:/vmimages-download/*.xml /lmn/vm/
|
||||
RSYNC_COMMAND=$(rsync -ai --delete --exclude=mimeinfo.cache rsync://server:/vmimages-download/desktop/ /usr/local/share/applications/ | sed '/ \.\//d')
|
||||
if [[ $? -eq 0 ]] && [[ -n "${RSYNC_COMMAND}" ]]; then
|
||||
echo "${RSYNC_COMMAND}"
|
||||
update-desktop-database /usr/local/share/applications
|
||||
fi
|
||||
}
|
||||
|
||||
create_starter() {
|
||||
if [[ ! -f "/usr/share/applications/VM_${VM_NAME}_starter.desktop" ]]; then
|
||||
cat << EOF >"/usr/share/applications/VM_${VM_NAME}_starter.desktop"
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=VMstart: ${VM_NAME}
|
||||
GenericName=VM starter ${VM_NAME}
|
||||
Comment=Start VM ${VM_NAME}
|
||||
#TryExec=konsole
|
||||
Exec=/usr/local/bin/run-vm.sh ${VM_NAME}
|
||||
Icon=clementine
|
||||
Categories=VM;Engineering;
|
||||
MimeType=image/vnd.dxf;
|
||||
Keywords=design;VM;diagrams;graphics
|
||||
Terminal=true
|
||||
EOF
|
||||
update-desktop-database /usr/share/applications
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$(id -nu)" != "lmnsynci" ]]; then
|
||||
echo "$(basename "$0") must be run as lmnsynci user"
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while getopts ':dat' OPTION; do
|
||||
case "$OPTION" in
|
||||
d)
|
||||
DOWNLOAD=1
|
||||
;;
|
||||
a)
|
||||
sync_all_images
|
||||
exit 0
|
||||
;;
|
||||
t)
|
||||
sync_all_torrents
|
||||
exit 0
|
||||
;;
|
||||
?)
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift "$((OPTIND -1))"
|
||||
|
||||
# if less than one arguments supplied, display usage
|
||||
if [[ $# -lt 1 ]]; then
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for VM_NAME in "$@"; do
|
||||
if [[ -v "DOWNLOAD" ]]; then
|
||||
echo "Downloading $VM_NAME"
|
||||
download_image
|
||||
else
|
||||
echo "Torrenting $VM_NAME"
|
||||
torrent_image
|
||||
fi
|
||||
done
|
13
roles/lmn_vm/files/sync.desktop
Normal file
13
roles/lmn_vm/files/sync.desktop
Normal file
|
@ -0,0 +1,13 @@
|
|||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Sync Starters
|
||||
GenericName=Aktualisiert Info über vorhandene VMs
|
||||
Comment=Sync VM Image information
|
||||
#TryExec=konsole
|
||||
Exec=if sudo /usr/local/bin/desktop-sync; then echo 'sync erfolgreich.\nFenster schließt sich in 3 Sekunden.'; sleep 3; else echo "Fehler - sollte nicht vorkommen."; read; fi
|
||||
Icon=bittorrent-sync
|
||||
Categories=fvs;
|
||||
MimeType=image/vnd.dxf;
|
||||
Keywords=design;VM;diagrams;graphics
|
||||
Terminal=true
|
93
roles/lmn_vm/files/uploadseed
Executable file
93
roles/lmn_vm/files/uploadseed
Executable file
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import os, sys
|
||||
import subprocess
|
||||
import xmlrpc.client as xc
|
||||
import ssl
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Upload a file to the bittorrent seeder.')
|
||||
parser.add_argument('--server', required=True,
|
||||
help="the server address and RPC port like 'IPaddress:port'")
|
||||
parser.add_argument('--dht-port', required=True,
|
||||
help='the DHT port the RPC server is listening on')
|
||||
pwgrp = parser.add_mutually_exclusive_group(required=True)
|
||||
pwgrp.add_argument('--passwd',
|
||||
help='the RPC secret. Either this or --pwdfile needs to be ' \
|
||||
'provided')
|
||||
pwgrp.add_argument('--pwdfile',
|
||||
help="file containing the RPC secret in the form " \
|
||||
"'secret = \"token:SECRET\"'. " \
|
||||
'Either this or --secret needs to be provided')
|
||||
certgrp = parser.add_mutually_exclusive_group(required=True)
|
||||
certgrp.add_argument('--no-cert', action='store_true',
|
||||
help='do not use SSL certificate')
|
||||
certgrp.add_argument('--cert', help='the certificate to use for verification')
|
||||
parser.add_argument('FILE', help='the file to upload')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
rpcseeder = 'https://' + args.server + '/rpc'
|
||||
dhtentry = args.server.split(':')[0] + ':' + args.dht_port
|
||||
file2send = args.FILE
|
||||
torrent = '/tmp/' + os.path.basename(file2send) + '.torrent'
|
||||
if args.passwd:
|
||||
secret = 'token:' + args.passwd
|
||||
else:
|
||||
exec(open(args.pwdfile).read())
|
||||
|
||||
ssl_ctx = ssl.create_default_context()
|
||||
if args.no_cert:
|
||||
ssl_ctx.check_hostname = False
|
||||
ssl_ctx.verify_mode = ssl.CERT_NONE
|
||||
print("Certificate verification disabled.")
|
||||
elif args.cert is not None:
|
||||
ssl_ctx.load_verify_locations(args.cert)
|
||||
|
||||
s = xc.ServerProxy(rpcseeder, context = ssl_ctx)
|
||||
|
||||
def make_torrent():
|
||||
if os.path.isfile(torrent):
|
||||
print("Torrent file", torrent, "exists already, please (re)move it.")
|
||||
sys.exit(1)
|
||||
|
||||
subprocess.run(["/usr/bin/mktorrent", "-l 24", "-v", "-o", torrent, file2send], check=True)
|
||||
h = subprocess.check_output(["/usr/bin/aria2c", "-S ", torrent])
|
||||
for line in h.decode().splitlines():
|
||||
if "Info Hash" in line:
|
||||
return line.split(': ')[1]
|
||||
|
||||
def check_seeds(bthash):
|
||||
active_seeds = s.aria2.tellActive(secret)
|
||||
for seed in active_seeds:
|
||||
f = seed['bittorrent']['info']['name']
|
||||
gid = seed['gid']
|
||||
ihash = seed['infoHash']
|
||||
if f == os.path.basename(file2send):
|
||||
print(file2send, "is already seeded with GID:", gid)
|
||||
print("Info Hash is:", ihash)
|
||||
if bthash == ihash:
|
||||
print("The torrent file has not changed, exiting.")
|
||||
return False
|
||||
else:
|
||||
print("The torrent file has changed, replacing torrent.")
|
||||
s.aria2.remove(secret, gid)
|
||||
return True
|
||||
print("="*19, " Uploading new torrent with aria2 now. ", "="*19)
|
||||
return True
|
||||
|
||||
def upload_torrent():
|
||||
s.aria2.addTorrent(secret, xc.Binary(open(torrent, mode='rb').read()))
|
||||
subprocess.run(["/usr/bin/aria2c",
|
||||
"--dht-entry-point=" + dhtentry,
|
||||
"--check-integrity",
|
||||
"--dir=" + os.path.dirname(file2send),
|
||||
torrent])
|
||||
|
||||
############################
|
||||
|
||||
if __name__ == '__main__':
|
||||
infoHash = make_torrent()
|
||||
if check_seeds(infoHash):
|
||||
upload_torrent()
|
||||
print("Upload finished.")
|
BIN
roles/lmn_vm/files/virtiofsd
Executable file
BIN
roles/lmn_vm/files/virtiofsd
Executable file
Binary file not shown.
33
roles/lmn_vm/files/vm-aria2
Executable file
33
roles/lmn_vm/files/vm-aria2
Executable file
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
# if less than one arguments supplied, display usage
|
||||
if [[ $# -ne 2 ]]; then
|
||||
echo "This script takes as input the name of the VM " >&2
|
||||
echo "Usage: $0 [start|stop] vm_name" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
COMMAND="$1"
|
||||
VM_NAME="$2"
|
||||
|
||||
source /etc/lmn/vm.conf
|
||||
|
||||
if [[ "${COMMAND}" = "start" ]]; then
|
||||
systemd-run --unit=aria2-"${VM_NAME}" \
|
||||
--slice=system-aria2 \
|
||||
--uid="$(id -u lmnsynci)" \
|
||||
--gid="$(id -g lmnsynci)" \
|
||||
--nice=19 \
|
||||
--working-directory="${VM_SYSDIR}" \
|
||||
--collect \
|
||||
--property=Type=exec \
|
||||
--property=SuccessExitStatus=1 \
|
||||
aria2c --bt-hash-check-seed=true --check-integrity=true --seed-ratio=0.0 \
|
||||
--dht-entry-point="${SEEDBOX_HOST}:${SEEDBOX_PORT}" \
|
||||
--dht-file-path=$DHTDAT \
|
||||
"${VM_SYSDIR}/${VM_NAME}.qcow2.torrent"
|
||||
elif [[ "${COMMAND}" = "stop" ]] && systemctl is-active "aria2-${VM_NAME}.service"; then
|
||||
systemctl stop "aria2-${VM_NAME}.service"
|
||||
fi
|
47
roles/lmn_vm/files/vm-create
Executable file
47
roles/lmn_vm/files/vm-create
Executable file
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/bash
|
||||
# create 1st level-Clones
|
||||
|
||||
set -eu
|
||||
|
||||
source /etc/lmn/vm.conf
|
||||
PERSISTENT=0
|
||||
|
||||
while getopts ':p' OPTION; do
|
||||
case "$OPTION" in
|
||||
p)
|
||||
PERSISTENT=1
|
||||
VM_DIR="${VM_DIR_PERSISTENT}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift "$((OPTIND -1))"
|
||||
|
||||
# if less than two arguments supplied, display usage
|
||||
if [[ $# -ne 2 ]]; then
|
||||
echo "This script takes as input the name of the VM to clone" >&2
|
||||
echo "Usage: $0 vm_name_orig vm_name_clone" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VM_NAME=$1
|
||||
VM_CLONE=$2
|
||||
|
||||
# Create User-VM-Dir and link system VM-Images
|
||||
[[ -d "${VM_DIR}" ]] || mkdir -p "${VM_DIR}"
|
||||
if [[ "${PERSISTENT}" -eq 1 ]]; then
|
||||
sudo /usr/local/bin/vm-link-images -p
|
||||
else
|
||||
sudo /usr/local/bin/vm-link-images
|
||||
fi
|
||||
|
||||
# change to image-directory
|
||||
cd "${VM_DIR}"
|
||||
|
||||
if [[ ! -f "${VM_NAME}.qcow2" ]]; then
|
||||
echo "qcow2 File does not exists." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
qemu-img create -f qcow2 -F qcow2 -b "${VM_NAME}.qcow2" "${VM_NAME}-${VM_CLONE}.qcow2"
|
||||
chmod a-w "${VM_NAME}-${VM_CLONE}.qcow2"
|
28
roles/lmn_vm/files/vm-link-images
Executable file
28
roles/lmn_vm/files/vm-link-images
Executable file
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/bash
|
||||
# link VM in User-Dir in /tmp or /var/vm
|
||||
|
||||
set -eu
|
||||
|
||||
source /etc/lmn/vm.conf
|
||||
|
||||
# change to image-directory
|
||||
cd "${VM_SYSDIR}"
|
||||
|
||||
while getopts ':p' OPTION; do
|
||||
case "$OPTION" in
|
||||
p)
|
||||
VM_DIR="${VM_DIR_PERSISTENT}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift "$((OPTIND -1))"
|
||||
|
||||
# link system-VM-Images to User VM Directory
|
||||
for i in *.qcow2; do
|
||||
[[ -f "${VM_DIR}/${i}" ]] || ln "${i}" "${VM_DIR}/${i}"
|
||||
done
|
||||
|
||||
# allow lmnsynci to remove old vm images
|
||||
chgrp lmnsynci "${VM_DIR}"
|
||||
chmod g+w "${VM_DIR}"
|
72
roles/lmn_vm/files/vm-netboot
Executable file
72
roles/lmn_vm/files/vm-netboot
Executable file
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/bash
|
||||
#
|
||||
# Start a netboot VM connected to macvtap device and fraction of mem/cpus
|
||||
#
|
||||
set -eu
|
||||
|
||||
## Imporant for all virsh libvirt calls:
|
||||
export XDG_CONFIG_HOME="/tmp/${UID}/.config"
|
||||
|
||||
menu=(standard "CLI Standard Debian GNU/Linux NFS"
|
||||
standard-ram "CLI Standard Debian GNU/Linux RAM"
|
||||
kde-desktop "KDE Plasma Desktop Debian GNU/Linux NFS"
|
||||
gnome-desktop "Gnome Desktop Debian GNU/Linux NFS")
|
||||
img=$(dialog --clear --backtitle "Virtual Machine Chooser" \
|
||||
--title "Choose the Virtual Machine to Start" \
|
||||
--menu "Start VM:" 12 70 6 "${menu[@]}" 2>&1 >/dev/tty)
|
||||
|
||||
## If the menu is canceled, $0 stops here because of set -e
|
||||
|
||||
mac="$(ip link | grep -A1 "vm-macvtap" | \
|
||||
sed -nE "s%\s+link/ether ([[:xdigit:]:]{17}) .+%\1%p")"
|
||||
|
||||
if [[ $# -eq 0 ]] ; then
|
||||
mem=$(sed -En "s/^MemAvailable:\s+([0-9]+)\s+kB/\1/p" /proc/meminfo)
|
||||
cpu=$(sed -En "0,/^cpu cores/s/^cpu cores\s+:\s+([0-9]+)/\1/p" /proc/cpuinfo)
|
||||
arg=("--memory=$((mem/2048))" "--vcpu=$((cpu/2))")
|
||||
echo Set options: "${arg[@]}"
|
||||
else
|
||||
arg=("$@")
|
||||
fi
|
||||
|
||||
kernel="http://livebox/d-i/n-live/${img%-ram}/live/vmlinuz"
|
||||
initrd="http://livebox/d-i/n-live/${img%-ram}/live/initrd.img"
|
||||
kargs=(boot=live components splash locales=de_DE.UTF-8 keyboard-layouts=de
|
||||
swap=true live-config.timezone=Europe/Berlin)
|
||||
|
||||
case "$img" in
|
||||
standard*)
|
||||
arg+=(--autoconsole=text)
|
||||
kargs+=(console=ttyS0)
|
||||
;;&
|
||||
*-ram)
|
||||
kargs+=("fetch=http://10.190.1.2/d-i/n-live/${img%-ram}/live/filesystem.squashfs")
|
||||
;;
|
||||
*)
|
||||
kargs+=(netboot=nfs "nfsroot=10.190.1.2:/srv/nfs/debian-live/${img%-ram}")
|
||||
;;
|
||||
esac
|
||||
|
||||
type="ethernet,mac=${mac},target.dev=vm-macvtap,xpath1.set=./target/@managed=no"
|
||||
for vm in $(virsh --connect qemu:///session list --all --name) ; do
|
||||
if virsh domiflist "$vm" | grep -q "$mac" ; then
|
||||
type="user"
|
||||
virt-manager &
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
## FIXME: use passt, needs more settings for correct DNS/gateway
|
||||
# type=user,xpath1.create=./backend,xpath2.set=./backend/@type=passt,xpath3.create=./ip,xpath4.set=./ip/@family=ipv4,xpath5.set=./ip/@address=172.16.1.1,xpath6.set=./ip/@prefix=24,xpath7.create=./portForward,xpath8.set=./portForward/@proto=tcp,xpath9.set=./portForward/range/@start=2001,xpath10.set=./portForward/range/@end=2500,xpath11.set=./portForward/range/@to=1
|
||||
|
||||
http_proxy='' \
|
||||
exec virt-install \
|
||||
--name "$img" \
|
||||
--osinfo debiantesting \
|
||||
--nodisks --import --noreboot --transient \
|
||||
--controller type=scsi,model=virtio-scsi \
|
||||
--install kernel="$kernel",initrd="$initrd",kernel_args="${kargs[*]}" \
|
||||
--network "type=$type" "${arg[@]}"
|
||||
|
||||
# --filesystem "$HOME",share
|
||||
# mount -t 9p share /mnt
|
80
roles/lmn_vm/files/vm-rebase
Executable file
80
roles/lmn_vm/files/vm-rebase
Executable file
|
@ -0,0 +1,80 @@
|
|||
#!/usr/bin/bash
|
||||
# Rebase one level down
|
||||
set -eu
|
||||
|
||||
show_help() {
|
||||
cat << EOF >&2
|
||||
Usage: $(basename "$0") [-n newname] vmname"
|
||||
This script takes as input the name of the VM to rebase one level down
|
||||
-n new name of the rebased image
|
||||
EOF
|
||||
}
|
||||
|
||||
source /etc/lmn/vm.conf
|
||||
|
||||
while getopts ':n:p' OPTION; do
|
||||
case "$OPTION" in
|
||||
n)
|
||||
NEWNAME=$OPTARG
|
||||
;;
|
||||
p)
|
||||
VM_DIR="${VM_DIR_PERSISTENT}"
|
||||
;;
|
||||
?)
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift "$((OPTIND -1))"
|
||||
|
||||
# if less or more than one arguments supplied, display usage
|
||||
if [[ $# -ne 1 ]]; then
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# change to Images directory
|
||||
cd "${VM_DIR}"
|
||||
|
||||
VM_NAME="$1"
|
||||
|
||||
# check if VM-Diskimage exists
|
||||
if [[ ! -f "${VM_NAME}.qcow2" ]]; then
|
||||
echo "File not found ${VM_NAME}.qcow2" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if new VM-Diskimage exists
|
||||
if [[ -v NEWNAME ]] && [[ -f "${NEWNAME}.qcow2" ]]; then
|
||||
echo "New Base already exists: ${NEWNAME}.qcow2" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NUMBASES=$(qemu-img info --backing-chain "${VM_NAME}.qcow2" | grep -c image)
|
||||
NEWBASE=$(qemu-img info --backing-chain "${VM_NAME}.qcow2" | grep image | head -n 3 | tail -n 1 | cut -d' ' -f2)
|
||||
CURRENTBASE=$(qemu-img info --backing-chain "${VM_NAME}.qcow2" | grep image | head -n 2 | tail -n 1 | cut -d' ' -f2)
|
||||
|
||||
if [[ ! "${NUMBASES}" -ge 3 ]]; then
|
||||
echo "Image must have at least 2 backing-files" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if base Diskimage exists
|
||||
if [[ ! -f "${NEWBASE}" ]] || [[ ! -f "${CURRENTBASE}" ]]; then
|
||||
echo "Backingfiles not found ${CURRENTBASE}, ${NEWBASE}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# rebasing disk image
|
||||
qemu-img rebase -f qcow2 -b "${NEWBASE}" -F qcow2 "${VM_NAME}.qcow2"
|
||||
if [[ -v NEWNAME ]]; then
|
||||
NEWNAME="${NEWNAME}.qcow2"
|
||||
else
|
||||
rm -f "${CURRENTBASE}"
|
||||
NEWNAME="${CURRENTBASE}"
|
||||
fi
|
||||
|
||||
mv "${VM_NAME}.qcow2" "${NEWNAME}"
|
||||
chmod a-w "${NEWNAME}"
|
256
roles/lmn_vm/files/vm-run
Executable file
256
roles/lmn_vm/files/vm-run
Executable file
|
@ -0,0 +1,256 @@
|
|||
#!/usr/bin/bash
|
||||
# create and run clone
|
||||
|
||||
set -eu
|
||||
|
||||
show_help() {
|
||||
cat << EOF >&2
|
||||
Usage: $(basename "$0") [options] vmname"
|
||||
Create a new clone, start the vm (if not yet running) and run virt-viewer.
|
||||
Squid-Proxy will be started too.
|
||||
options:
|
||||
-n|--new new clone will be created, even if exists
|
||||
-p|--persistent new clone will be created persistent, so available after reboot too
|
||||
-s|--system qemu:///system instead of default qemu:///session
|
||||
--no-viewer start without viewer
|
||||
--heads n number of displays
|
||||
--memory sizeMB memory size in MB
|
||||
--cpu num number of CPUs
|
||||
--os OS operating system (win10|linux|..)
|
||||
--data-disk size additional data-disk
|
||||
--bridge virbrX additional network interface on bridge virbrX
|
||||
--options options additional options for virt-install command
|
||||
EOF
|
||||
}
|
||||
|
||||
exit_script() {
|
||||
echo "run-vm.sh ${VM_NAME} terminated by trap!" >> "/tmp/${UID}/exit-run-vm.log"
|
||||
virsh --connect="${QEMU}" destroy "${VM_NAME}-clone"
|
||||
trap - SIGHUP SIGINT SIGTERM # clear the trap
|
||||
kill -- -$$ # Sends SIGTERM to child/sub processes
|
||||
}
|
||||
|
||||
check_images() {
|
||||
# sync vm-torrents and machine definition file
|
||||
sudo -u lmnsynci /usr/local/bin/vm-sync get_file "${VM_NAME}.qcow2.torrent"
|
||||
[[ -f "${VM_SYSDIR}/${VM_NAME}.qcow2" ]] && sudo -u lmnsynci /usr/local/bin/vm-sync delete_outdated_image "${VM_NAME}.qcow2"
|
||||
|
||||
BACKINGARRAY=()
|
||||
imgfile="${VM_SYSDIR}/${VM_NAME}.qcow2" && [[ -f "${VM_DIR}/${VM_NAME}.qcow2" ]] && imgfile="${VM_DIR}/${VM_NAME}.qcow2"
|
||||
BACKINGARRAY+=("${imgfile}")
|
||||
echo "Imgfile=$imgfile"
|
||||
if [[ ! -f "${imgfile}" ]] || ! qemu-img info -U "${imgfile}" | grep "file format: qcow2"; then
|
||||
if [[ ! -f "${VM_SYSDIR}/${VM_NAME}.qcow2.torrent" ]]; then
|
||||
echo "no base VM disk '${VM_NAME}.qcow2' found and/or ${VM_NAME} not found on server" >&2
|
||||
exit 1
|
||||
fi
|
||||
# sync vm-disk image by torrent
|
||||
echo "Try to sync VM ${VM_NAME} by torrent"
|
||||
sudo -u lmnsynci /usr/local/bin/vm-sync get_image "${VM_NAME}"
|
||||
fi
|
||||
|
||||
backingfile=$(qemu-img info -U "${imgfile}" | grep "^backing file:" | cut -d ' ' -f 3)
|
||||
while [[ -n "${backingfile}" ]]; do
|
||||
echo "Backingfile required: ${backingfile}"
|
||||
imgfile="${VM_SYSDIR}/${backingfile}" && [[ -f "${VM_DIR}/${backingfile}" ]] && imgfile="${VM_DIR}/${backingfile}"
|
||||
BACKINGARRAY+=("${imgfile}")
|
||||
sudo -u lmnsynci /usr/local/bin/vm-sync get_file "${backingfile}.torrent"
|
||||
[[ -f "${VM_SYSDIR}/${backingfile}" ]] && sudo -u lmnsynci /usr/local/bin/vm-sync delete_outdated_image "${backingfile}"
|
||||
if [[ ! -f "${imgfile}" ]] || ! qemu-img info -U "${imgfile}" | grep "file format: qcow2"; then
|
||||
# sync vm-disk image by torrent
|
||||
echo "Try to sync backingfile ${backingfile} by torrent"
|
||||
sudo -u lmnsynci /usr/local/bin/vm-sync get_image "${backingfile%.qcow2}"
|
||||
fi
|
||||
backingfile=$(qemu-img info -U "${imgfile}" | grep "^backing file:" | cut -d ' ' -f 3)
|
||||
done
|
||||
|
||||
echo "VM-Image and required backingfiles available"
|
||||
echo "Now, let's check the images."
|
||||
|
||||
# Check VM-Images in reverse order
|
||||
for ((i=${#BACKINGARRAY[@]}-1; i>=0; i--))
|
||||
do
|
||||
echo "Checking ${BACKINGARRAY[$i]}"
|
||||
if ! qemu-img check -U "${BACKINGARRAY[$i]}" 2>/dev/null; then
|
||||
echo "check failed!"
|
||||
echo "sync ${BACKINGARRAY[$i]} again"
|
||||
sudo -u lmnsynci /usr/local/bin/vm-sync get_file "${BACKINGARRAY[$i]}.torrent"
|
||||
sudo -u lmnsynci /usr/local/bin/vm-sync get_image "$(basename "${BACKINGARRAY[$i]}" .qcow2)"
|
||||
fi
|
||||
done
|
||||
echo "VM-Image and required backingfiles available and checked"
|
||||
|
||||
sudo -u lmnsynci /usr/local/bin/vm-sync update_usage_information ${BACKINGARRAY[*]}
|
||||
}
|
||||
|
||||
create_clone() {
|
||||
local VM_NAME="$1"
|
||||
|
||||
if ! [[ -f "${VM_SYSDIR}/${VM_NAME}.qcow2" || -f "${VM_DIR}/${VM_NAME}.qcow2" ]]; then
|
||||
echo "qcow2 File does not exists." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create User-VM-Dir and link system VM-Images
|
||||
[[ -d "${VM_DIR}" ]] || mkdir -p "${VM_DIR}"
|
||||
if [[ "${PERSISTENT}" -eq 1 ]]; then
|
||||
sudo /usr/local/bin/vm-link-images -p
|
||||
else
|
||||
sudo /usr/local/bin/vm-link-images
|
||||
fi
|
||||
|
||||
# Create backing file
|
||||
cd "${VM_DIR}"
|
||||
qemu-img create -f qcow2 -F qcow2 -b "${VM_NAME}.qcow2" "${VM_NAME}-clone.qcow2"
|
||||
|
||||
}
|
||||
|
||||
QEMU='qemu:///session'
|
||||
|
||||
NEWCLONE=0
|
||||
PERSISTENT=0
|
||||
LIBVIRTOSINFO="win10"
|
||||
LIBVIRTOPTS=""
|
||||
NO_VIEWER=0
|
||||
|
||||
source /etc/lmn/vm.conf
|
||||
|
||||
TEMP=$(getopt -o no:ps --long new,no-viewer,options:,persistent,system,memory:,data-disk:,heads:,cpu:,bridge:,os:,help -n $0 -- "$@")
|
||||
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
|
||||
|
||||
eval set -- "$TEMP"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-p | --persistent )
|
||||
PERSISTENT=1;
|
||||
VM_DIR="${VM_DIR_PERSISTENT}"
|
||||
shift
|
||||
;;
|
||||
-n | --new )
|
||||
NEWCLONE=1
|
||||
shift
|
||||
;;
|
||||
-s | --system )
|
||||
QEMU='qemu:///system'
|
||||
shift
|
||||
;;
|
||||
-o | --options )
|
||||
LIBVIRTOPTS=$2
|
||||
shift 2
|
||||
;;
|
||||
--no-viewer )
|
||||
NO_VIEWER=1
|
||||
shift
|
||||
;;
|
||||
--data-disk )
|
||||
LIBVIRTOPTS="${LIBVIRTOPTS} --disk ${VM_DIR}/data.qcow2,size=$2,sparse=yes"
|
||||
shift 2
|
||||
;;
|
||||
--heads )
|
||||
for i in $(seq $2)
|
||||
do
|
||||
LIBVIRTOPTS="${LIBVIRTOPTS} --video model.heads=$i"
|
||||
done
|
||||
shift 2
|
||||
;;
|
||||
--memory )
|
||||
mem_avail=$(sed -En "s/^MemAvailable:\s+([0-9]+)\s+kB/\1/p" /proc/meminfo)
|
||||
mem_avail=$((mem_avail / 1024 - 2048))
|
||||
if (( $2 < mem_avail )); then
|
||||
LIBVIRTOPTS="${LIBVIRTOPTS} --memory $2"
|
||||
else
|
||||
LIBVIRTOPTS="${LIBVIRTOPTS} --memory ${mem_avail}"
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
--cpu )
|
||||
#cpu=$(sed -En "0,/^cpu cores/s/^cpu cores\s+:\s+([0-9]+)/\1/p" /proc/cpuinfo)
|
||||
cpu=$(lscpu | grep "^CPU(s):" | sed 's/.* //g')
|
||||
if (( $2 < cpu )); then
|
||||
LIBVIRTOPTS="${LIBVIRTOPTS} --vcpu $2"
|
||||
else
|
||||
LIBVIRTOPTS="${LIBVIRTOPTS} --vcpu ${cpu}"
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
--bridge )
|
||||
if ip link | grep $2; then
|
||||
LIBVIRTOPTS="${LIBVIRTOPTS} --network=bridge=$2,model.type=virtio"
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
--os )
|
||||
LIBVIRTOSINFO=$2
|
||||
shift 2
|
||||
;;
|
||||
--help )
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
-- ) shift; break ;;
|
||||
* ) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# if less than one arguments supplied, display usage
|
||||
if [[ $# -ne 1 ]] ; then
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VM_NAME=$1
|
||||
|
||||
# check, if we have to start squid
|
||||
if ! killall -s 0 squid; then
|
||||
echo "starting squid."
|
||||
/usr/sbin/squid -f /etc/squid/squid-usermode.conf
|
||||
fi
|
||||
|
||||
# because virsh has problems with long pathnames, using diffent configdir
|
||||
export XDG_CONFIG_HOME="/tmp/${UID}/.config"
|
||||
|
||||
if ! virsh --connect="${QEMU}" list | grep "${VM_NAME}-clone"; then
|
||||
echo "VM not yet running."
|
||||
sudo /usr/local/bin/desktop-sync
|
||||
check_images
|
||||
if [[ "${NEWCLONE}" = 1 ]] || [[ ! -f "${VM_DIR}/${VM_NAME}-clone.qcow2" ]]; then
|
||||
create_clone "${VM_NAME}"
|
||||
fi
|
||||
# delete the old vm
|
||||
virsh --connect=qemu:///session undefine "${VM_NAME}-clone" || echo "${VM_NAME}-clone did not exist"
|
||||
#trap exit_script SIGHUP SIGINT SIGTERM
|
||||
|
||||
# start virtiofsd-service
|
||||
[[ "${QEMU}" = 'qemu:///session' ]] && sudo /usr/local/bin/vm-virtiofsd "${VM_NAME}"
|
||||
|
||||
# finally, create the new vm
|
||||
|
||||
virt-install \
|
||||
--osinfo "${LIBVIRTOSINFO}" \
|
||||
--name "${VM_NAME}-clone" \
|
||||
--import \
|
||||
--clock hpet_present=yes,hypervclock_present=yes \
|
||||
--features hyperv.synic.state=on,xpath1.set=./hyperv/vpindex/@state=on,xpath2.set=./hyperv/stimer/@state=on \
|
||||
--memorybacking source.type=memfd,access.mode=shared \
|
||||
--disk "${VM_DIR}/${VM_NAME}-clone.qcow2",driver.discard=unmap,target.bus=scsi,cache=writeback \
|
||||
--network=bridge=virbr0,model.type=virtio \
|
||||
--filesystem driver.type=virtiofs,accessmode=passthrough,target.dir=virtiofs,xpath1.set=./source/@socket="/run/user/${UID}/virtiofs-${VM_NAME}.sock" \
|
||||
--controller type=scsi,model=virtio-scsi \
|
||||
--check path_in_use=off \
|
||||
--connect="${QEMU}" \
|
||||
--noautoconsole \
|
||||
${LIBVIRTOPTS}
|
||||
|
||||
# --dry-run \
|
||||
# --print-xml \
|
||||
# > /tmp/vm.xml
|
||||
# --features hyperv.synic.state=on,xpath1.set=./hyperv/vpindex/@state=on,xpath2.set=./hyperv/stimer/@state=on \
|
||||
# --network type=ethernet,target.dev=vm-macvtap,xpath1.set=./target/@managed=no \
|
||||
# virsh --connect="${QEMU}" start "${VM_NAME}-clone"
|
||||
fi
|
||||
if [[ $NO_VIEWER == 0 ]] ; then
|
||||
echo "starting viewer"
|
||||
trap exit_script SIGHUP SIGINT SIGTERM
|
||||
virt-viewer --connect="${QEMU}" --full-screen "${VM_NAME}-clone"
|
||||
fi
|
168
roles/lmn_vm/files/vm-sync
Executable file
168
roles/lmn_vm/files/vm-sync
Executable file
|
@ -0,0 +1,168 @@
|
|||
#!/usr/bin/bash
|
||||
# Push/Pull VM-Disk-Image and Infos from server
|
||||
set -eu
|
||||
|
||||
show_help() {
|
||||
cat << EOF >&2
|
||||
Usage: $(basename "$0") command [args]"
|
||||
command:
|
||||
push_file
|
||||
get_file
|
||||
get_image
|
||||
delete_outdated_image
|
||||
update_usage_information
|
||||
EOF
|
||||
}
|
||||
|
||||
get_torrent() {
|
||||
if [[ ! -f "${VM_SYSDIR}/${VM_NAME}.qcow2.torrent" ]]; then
|
||||
echo "No torrent-File found"
|
||||
exit 1
|
||||
fi
|
||||
cd "${VM_SYSDIR}"
|
||||
echo Size needed: $(get_image_size "${VM_NAME}.qcow2.torrent")
|
||||
echo Size available: $(df --block-size=1 --output=avail "${VM_SYSDIR}" | sed 1d)
|
||||
while [[ $(get_image_size "${VM_NAME}.qcow2.torrent") -gt $(df --block-size=1 --output=avail "${VM_SYSDIR}" | sed 1d) ]]; do
|
||||
echo "Not enough space to get ${VM_NAME}."
|
||||
FILENAME="$(head -1 vm_usage_information.txt)"
|
||||
if [[ -z $FILENAME ]]; then
|
||||
echo "No more old VM-files to delete. Unable to get ${VM_NAME}. Please contact system administrator."
|
||||
exit 1
|
||||
fi
|
||||
echo "Deleting $FILENAME"
|
||||
sudo vm-aria2 stop "$(basename "${FILENAME}" .qcow2)"
|
||||
rm -f "${FILENAME}"
|
||||
[[ -f "${VM_DIR}/${FILENAME}" ]] && rm -f "${VM_DIR}/${FILENAME}"
|
||||
sed -i -e 1d vm_usage_information.txt
|
||||
done
|
||||
lockfile="/tmp/sync-vm-${VM_NAME}.lock"
|
||||
if ! flock -n "$lockfile" echo "try to acquire lock"; then
|
||||
echo torrent seems to be in process.
|
||||
echo waiting for completion ...
|
||||
flock -w 3600 "$lockfile" echo "...completed"
|
||||
sleep 5
|
||||
else
|
||||
(
|
||||
if ! flock -n 200; then
|
||||
echo "failed to acquire lock"
|
||||
echo "Bitte noch einmal starten."
|
||||
echo "Beliebige Taste zum Beenden."
|
||||
read -n 1
|
||||
exit 1
|
||||
fi
|
||||
# stop aria2-seeding if running
|
||||
sudo vm-aria2 stop "${VM_NAME}"
|
||||
cd "${VM_SYSDIR}"
|
||||
# get image
|
||||
aria2c --seed-time=0 --dht-file-path="$DHTDAT" \
|
||||
--dht-entry-point="${SEEDBOX_HOST}:${SEEDBOX_PORT}" \
|
||||
"${VM_SYSDIR}/${VM_NAME}.qcow2.torrent"
|
||||
# and seed
|
||||
sudo vm-aria2 start "${VM_NAME}"
|
||||
if ! flock -u 200; then
|
||||
echo failed to drop lock
|
||||
exit 1
|
||||
fi
|
||||
) 200>"$lockfile"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
get_image_size() {
|
||||
torrentfile=$1
|
||||
length=$(aria2c -S "${torrentfile}" | grep "Total Length" | \
|
||||
sed -E -e 's/.*\(([0-9,]*)\)/\1/' -e 's/,//g')
|
||||
echo "$length"
|
||||
}
|
||||
|
||||
delete_outdated_image() {
|
||||
cd "${VM_SYSDIR}"
|
||||
qcowsize=$(stat -c%s "${FILENAME}")
|
||||
if [[ -f "${FILENAME}.torrent" ]] && [[ "${qcowsize}" != $(get_image_size "${FILENAME}.torrent") ]]; then
|
||||
sudo vm-aria2 stop "${FILENAME%.qcow2}"
|
||||
rm -f "${FILENAME}"
|
||||
fi
|
||||
}
|
||||
|
||||
update_usage_information() {
|
||||
cd "${VM_SYSDIR}"
|
||||
[[ -f vm_usage_information.txt ]] || ls -tr *.qcow2 > vm_usage_information.txt || touch vm_usage_information.txt
|
||||
FILENAME="$(basename $FILENAME)"
|
||||
echo sed -i "/${FILENAME}/d" vm_usage_information.txt
|
||||
sed -i "/${FILENAME}/d" vm_usage_information.txt
|
||||
echo "${FILENAME}" >> vm_usage_information.txt
|
||||
}
|
||||
|
||||
get_file() {
|
||||
cd "${VM_SYSDIR}"
|
||||
curl --fail --noproxy "${SEEDBOX_HOST}" -o "${FILENAME}" \
|
||||
"http://${SEEDBOX_HOST}/aria2/${FILENAME}" || echo "File not found on seedbox"
|
||||
}
|
||||
|
||||
push_file() {
|
||||
cd "${VM_SYSDIR}"
|
||||
uploadseed --server "${SEEDBOX_HOST}:${SEEDBOX_RPC_PORT}" --dht-port "${SEEDBOX_PORT}" \
|
||||
--pwdfile "${SEEDBOX_PWFILE}" --no-cert "${FILENAME}"
|
||||
}
|
||||
|
||||
########################
|
||||
|
||||
if [[ "$(id -nu)" != "lmnsynci" ]]; then
|
||||
echo "$(basename "$0") must be run as lmnsynci user"
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source /etc/lmn/vm.conf
|
||||
|
||||
while getopts ':' OPTION; do
|
||||
case "$OPTION" in
|
||||
?)
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift "$((OPTIND -1))"
|
||||
|
||||
# if less than one arguments supplied, display usage
|
||||
if [[ $# -lt 1 ]]; then
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
command=$1
|
||||
shift
|
||||
|
||||
case "$command" in
|
||||
push_file)
|
||||
for FILENAME in "$@"; do
|
||||
push_file
|
||||
done
|
||||
;;
|
||||
get_file)
|
||||
for FILENAME in "$@"; do
|
||||
get_file
|
||||
done
|
||||
;;
|
||||
get_image)
|
||||
for VM_NAME in "$@"; do
|
||||
get_torrent
|
||||
done
|
||||
;;
|
||||
delete_outdated_image)
|
||||
for FILENAME in "$@"; do
|
||||
delete_outdated_image
|
||||
done
|
||||
;;
|
||||
update_usage_information)
|
||||
for FILENAME in "$@"; do
|
||||
update_usage_information
|
||||
done
|
||||
;;
|
||||
*)
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
60
roles/lmn_vm/files/vm-upload
Executable file
60
roles/lmn_vm/files/vm-upload
Executable file
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/bash
|
||||
# Push VM-Disk-Image on server
|
||||
set -eu
|
||||
|
||||
show_help() {
|
||||
cat << EOF >&2
|
||||
Usage: $(basename "$0") vmname"
|
||||
Create torrent and upload disk on server.
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
upload_image() {
|
||||
# check if VM-Diskimage exists
|
||||
if [[ ! (-f "${VM_SYSDIR}/${VM_NAME}.qcow2" || -f "${VM_DIR}/${VM_NAME}.qcow2") ]]; then
|
||||
echo "File not found ${VM_NAME}.qcow2" >&2
|
||||
exit 1
|
||||
fi
|
||||
vm-aria2 stop "${VM_NAME}" || echo "VMImage-torrent not running"
|
||||
# link private VM-Diskimage to system-Dir
|
||||
if [[ -f "${VM_DIR}/${VM_NAME}.qcow2" \
|
||||
&& ( -f "${VM_SYSDIR}/${VM_NAME}.qcow2" && ("${VM_DIR}/${VM_NAME}.qcow2" -nt "${VM_SYSDIR}/${VM_NAME}.qcow2") \
|
||||
|| ! -f "${VM_SYSDIR}/${VM_NAME}.qcow2") ]]; then
|
||||
echo "copy private VM-Diskimage to system-dir"
|
||||
chown lmnsynci:lmnsynci "${VM_DIR}/${VM_NAME}.qcow2"
|
||||
ln -f "${VM_DIR}/${VM_NAME}.qcow2" "${VM_SYSDIR}/${VM_NAME}.qcow2"
|
||||
fi
|
||||
cd "${VM_SYSDIR}"
|
||||
if [[ -f "/tmp/${VM_NAME}.qcow2.torrent" ]]; then
|
||||
rm -f "/tmp/${VM_NAME}.qcow2.torrent"
|
||||
fi
|
||||
uploadseed --server "${SEEDBOX_HOST}:${SEEDBOX_RPC_PORT}" --dht-port "${SEEDBOX_PORT}" \
|
||||
--pwdfile "${SEEDBOX_PWFILE}" --no-cert "${VM_NAME}.qcow2"
|
||||
}
|
||||
|
||||
source /etc/lmn/vm.conf
|
||||
|
||||
while getopts ':p' OPTION; do
|
||||
case "$OPTION" in
|
||||
p)
|
||||
VM_DIR="${VM_DIR_PERSISTENT}"
|
||||
;;
|
||||
?)
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift "$((OPTIND -1))"
|
||||
|
||||
# if less than one arguments supplied, display usage
|
||||
if [[ $# -ne 1 ]] ; then
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VM_NAME=$1
|
||||
|
||||
upload_image
|
50
roles/lmn_vm/files/vm-virtiofsd
Executable file
50
roles/lmn_vm/files/vm-virtiofsd
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
# if less than one arguments supplied, display usage
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "This script takes as input the name of the VM " >&2
|
||||
echo "Usage: $0 vm_name" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VM_NAME="$1"
|
||||
|
||||
## Make sure VMs can read the base directory:
|
||||
chgrp 1010 "/lmn/media/${SUDO_USER}"
|
||||
chmod 0775 "/lmn/media/${SUDO_USER}"
|
||||
|
||||
socket="/run/user/$(id -u $SUDO_USER)/virtiofs-${VM_NAME}.sock"
|
||||
|
||||
# FIXME: This does not work. In windows, there is no virtiofs device.
|
||||
# In GNU/Linux it's only readable.
|
||||
#
|
||||
#if ! systemctl -q is-active virtiofs-${VM_NAME}.socket ; then
|
||||
# systemd-run --unit=virtiofs-${VM_NAME} \
|
||||
# --slice=system-virtiofs \
|
||||
# --collect \
|
||||
# --socket-property=ListenStream="$socket" \
|
||||
# --socket-property=Accept=no \
|
||||
# --socket-property=SocketMode=0700 \
|
||||
# --socket-property=SocketUser=${SUDO_USER} \
|
||||
# --property=Type=exec \
|
||||
# --property=StandardInput=socket \
|
||||
# /usr/local/bin/virtiofsd --log-level debug --sandbox none \
|
||||
# --syslog --fd=0 --shared-dir "/lmn/media/${SUDO_USER}"
|
||||
#else
|
||||
# systemctl restart virtiofs-${VM_NAME}.socket
|
||||
#fi
|
||||
|
||||
if [[ ! -S "$socket" ]] ; then
|
||||
systemd-run --unit=virtiofs-${VM_NAME} \
|
||||
--slice=system-virtiofs \
|
||||
--collect \
|
||||
--property=Type=exec \
|
||||
--property=SuccessExitStatus=1 \
|
||||
--property="ExecStopPost=rm $socket" \
|
||||
/usr/local/bin/virtiofsd --socket-path "$socket" \
|
||||
--shared-dir "/lmn/media/${SUDO_USER}"
|
||||
fi
|
||||
sleep 1
|
||||
chown "${SUDO_USER}" "$socket"
|
17
roles/lmn_vm/files/vm.conf
Normal file
17
roles/lmn_vm/files/vm.conf
Normal file
|
@ -0,0 +1,17 @@
|
|||
# variables for LMN VM submodule
|
||||
|
||||
SEEDBOX_HOST="seedbox.pn.steinbeis.schule"
|
||||
SEEDBOX_PORT=6789
|
||||
SEEDBOX_RPC_PORT=6800
|
||||
SEEDBOX_PWFILE="/etc/lmn/uploadseed.conf"
|
||||
DHTDAT="/var/cache/aria2/dht.dat"
|
||||
DESKTOPSTARTERDIR="/srv/samba/schools/default-school/share/school/AdminIT/desktop/"
|
||||
|
||||
VM_SYSDIR="/lmn/vm"
|
||||
if [[ -v SUDO_UID ]]; then
|
||||
VM_DIR="/tmp/${SUDO_UID}/vm"
|
||||
VM_DIR_PERSISTENT="/var/vm/${SUDO_UID}"
|
||||
else
|
||||
VM_DIR="/tmp/${UID}/vm"
|
||||
VM_DIR_PERSISTENT="/var/vm/${UID}"
|
||||
fi
|
11
roles/lmn_vm/handlers/main.yml
Normal file
11
roles/lmn_vm/handlers/main.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
- name: Reload libvirtd
|
||||
systemd:
|
||||
name: libvirtd.service
|
||||
listen: reload libvirtd
|
||||
|
||||
- name: Run update-desktop-database
|
||||
command: update-desktop-database "{{ item }}"
|
||||
loop:
|
||||
- /usr/local/share/applications
|
||||
- /usr/local/share/desktop-directories
|
||||
- /etc/xdg/menus/applications-merged
|
277
roles/lmn_vm/tasks/main.yml
Normal file
277
roles/lmn_vm/tasks/main.yml
Normal file
|
@ -0,0 +1,277 @@
|
|||
---
|
||||
# FIXME #691138, better: prepare interfaces ready to use, c.f. down below, macvtap.
|
||||
# This task needs to be run before the last apt run to provide a ready-to-use installation.
|
||||
- name: Allow users to attach to bridge
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/apt/apt.conf.d/94qemu-bridge-suid
|
||||
content: |
|
||||
## Modify permissions after installation/upgrade
|
||||
## to run qemu-bridge as root
|
||||
DPkg::Post-Invoke {"/usr/bin/chmod 4755 /usr/lib/qemu/qemu-bridge-helper || true"; };
|
||||
|
||||
|
||||
- name: install libvirt packages
|
||||
apt:
|
||||
name:
|
||||
- aria2
|
||||
- mktorrent
|
||||
- libvirt-daemon-system
|
||||
- virt-manager
|
||||
- dialog # for vm-netboot menu
|
||||
state: latest
|
||||
autoremove: true
|
||||
|
||||
#- name: allow all users to use VMs
|
||||
# lineinfile:
|
||||
# dest: /etc/libvirt/libvirtd.conf
|
||||
# line: 'auth_unix_rw = "none"'
|
||||
# insertafter: '#auth_unix_rw = "polkit"'
|
||||
# notify: reload libvirtd
|
||||
|
||||
- name: Configure pam_mount for VM bind mounts
|
||||
blockinfile:
|
||||
dest: /etc/security/pam_mount.conf.xml
|
||||
marker: "<!-- {mark} ANSIBLE MANAGED BLOCK (bind mounts for VMs) -->"
|
||||
block: |
|
||||
<!-- bind mounts for the VMs, setting gid here does not work -->
|
||||
<volume
|
||||
path="~"
|
||||
mountpoint="/lmn/media/%(USER)/home"
|
||||
options="bind"
|
||||
><not><or><user>root</user><user>ansible</user><user>Debian-gdm</user><user>sddm</user><user>{{ localuser }}</user></or></not>
|
||||
</volume>
|
||||
<volume
|
||||
path="/srv/samba/schools/default-school/share"
|
||||
mountpoint="/lmn/media/%(USER)/share"
|
||||
options="bind"
|
||||
><not><or><user>root</user><user>ansible</user><user>Debian-gdm</user><user>sddm</user><user>{{ localuser }}</user></or></not>
|
||||
</volume>
|
||||
insertafter: "<!-- END ANSIBLE MANAGED BLOCK .* -->"
|
||||
|
||||
- name: Use umount script for proper cleanup
|
||||
blockinfile:
|
||||
dest: /etc/security/pam_mount.conf.xml
|
||||
marker: "<!-- {mark} ANSIBLE MANAGED BLOCK (umount script needed for bind mounts ordering) -->"
|
||||
block: |
|
||||
<!-- Provide special umount script here to handle bind mounts and proper ordering -->
|
||||
<umount>/usr/local/sbin/pam-umount.sh %(USER) %(USERUID) %(MNTPT)</umount>
|
||||
insertafter: '^<mntoptions.*'
|
||||
|
||||
- name: Prepare umount script
|
||||
ansible.builtin.copy:
|
||||
src: pam-umount.sh
|
||||
dest: /usr/local/sbin/pam-umount.sh
|
||||
mode: "0755"
|
||||
|
||||
- name: Insert domain in default-network
|
||||
lineinfile:
|
||||
path: /etc/libvirt/qemu/networks/default.xml
|
||||
line: ' <domain name="{{ ansible_domain }}" localOnly="no"/>'
|
||||
insertafter: '</ip>'
|
||||
|
||||
- name: Autostart default network for VMs
|
||||
file:
|
||||
src: /etc/libvirt/qemu/networks/default.xml
|
||||
dest: /etc/libvirt/qemu/networks/autostart/default.xml
|
||||
state: link
|
||||
|
||||
- name: Create system-user syncing VM-files and others
|
||||
ansible.builtin.user:
|
||||
name: lmnsynci
|
||||
comment: lmn sync user
|
||||
system: true
|
||||
create_home: false
|
||||
|
||||
- name: Create /etc/lmn directory
|
||||
file:
|
||||
path: /etc/lmn
|
||||
state: directory
|
||||
|
||||
- name: Create /lmn directory
|
||||
file:
|
||||
path: /lmn
|
||||
state: directory
|
||||
|
||||
- name: Create /lmn/media directory
|
||||
file:
|
||||
path: /lmn/media
|
||||
state: directory
|
||||
mode: '1777'
|
||||
|
||||
- name: Create /var/vm directory
|
||||
file:
|
||||
path: /var/vm
|
||||
state: directory
|
||||
mode: '1777'
|
||||
|
||||
- name: Create vm directory
|
||||
file:
|
||||
path: /lmn/vm
|
||||
state: directory
|
||||
owner: lmnsynci
|
||||
group: lmnsynci
|
||||
mode: 0755
|
||||
|
||||
- name: Install squid
|
||||
apt:
|
||||
name:
|
||||
- squid
|
||||
state: latest
|
||||
autoremove: true
|
||||
|
||||
- name: Disable squid
|
||||
systemd:
|
||||
name: squid
|
||||
enabled: false
|
||||
state: stopped
|
||||
|
||||
- name: Deploy squid user mode configuration
|
||||
template:
|
||||
src: squid-usermode.conf.j2
|
||||
dest: /etc/squid/squid-usermode.conf
|
||||
mode: '0644'
|
||||
|
||||
- name: Deploy sudo configurations
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "/etc/sudoers.d/90-{{ item }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0700'
|
||||
loop:
|
||||
- lmn-mounthome
|
||||
- lmn-vm
|
||||
|
||||
- name: Deploy vmimages scripts
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: /usr/local/bin/
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0755'
|
||||
loop:
|
||||
- mounthome.sh
|
||||
- vm-create
|
||||
- vm-rebase
|
||||
- vm-run
|
||||
- vm-upload
|
||||
- vm-sync
|
||||
- vm-link-images
|
||||
- vm-virtiofsd
|
||||
- virtiofsd
|
||||
- vm-aria2
|
||||
- uploadseed
|
||||
- desktop-sync
|
||||
|
||||
- name: Deploy vm configuration file vm.conf
|
||||
ansible.builtin.copy:
|
||||
src: vm.conf
|
||||
dest: /etc/lmn/vm.conf
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Deploy aria2 RPC password file
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/lmn/uploadseed.conf
|
||||
owner: root
|
||||
group: lmnsynci
|
||||
mode: '0640'
|
||||
content: |
|
||||
{{ uploadseed_pwd }}
|
||||
|
||||
- name: Prepare directory for aria2 dht.dat
|
||||
ansible.builtin.file:
|
||||
path: /var/cache/aria2/
|
||||
state: directory
|
||||
owner: lmnsynci
|
||||
group: lmnsynci
|
||||
|
||||
- name: Prepare directory for qemu bridge config
|
||||
ansible.builtin.file:
|
||||
path: /etc/qemu/
|
||||
state: directory
|
||||
|
||||
- name: Deploy bridge.conf needed for qemu session mode
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/qemu/bridge.conf
|
||||
content: |
|
||||
allow virbr0
|
||||
allow virbr1
|
||||
allow virbr2
|
||||
|
||||
- name: Configure macvtap interface
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/NetworkManager/system-connections/macvlan-vm-macvtap.nmconnection
|
||||
mode: '0600'
|
||||
content: |
|
||||
[connection]
|
||||
id=macvlan-vm-macvtap
|
||||
type=macvlan
|
||||
interface-name=vm-macvtap
|
||||
[macvlan]
|
||||
mode=2
|
||||
parent={{ ansible_default_ipv4['interface'] }}
|
||||
tap=true
|
||||
[ipv4]
|
||||
method=disabled
|
||||
[ipv6]
|
||||
method=disabled
|
||||
[proxy]
|
||||
|
||||
- name: Adjust interface permissions for user mode VMs
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/udev/rules.d/80-macvlan.rules
|
||||
content: |
|
||||
SUBSYSTEMS=="net", KERNELS=="vm-macvtap", MODE="0666"
|
||||
|
||||
|
||||
- name: Create directory for local .desktop-Files
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
loop:
|
||||
- /usr/local/share/applications
|
||||
- /usr/local/share/desktop-directories
|
||||
notify: Run update-desktop-database
|
||||
|
||||
- name: Copy fvs.directory
|
||||
ansible.builtin.copy:
|
||||
src: fvs.directory
|
||||
dest: /usr/local/share/desktop-directories/
|
||||
notify: Run update-desktop-database
|
||||
|
||||
- name: Copy fvs.menu
|
||||
ansible.builtin.copy:
|
||||
src: fvs.menu
|
||||
dest: /etc/xdg/menus/applications-merged/
|
||||
notify: Run update-desktop-database
|
||||
|
||||
- name: check if sync.desktop is installed
|
||||
stat: path=/usr/local/share/applications/sync.desktop
|
||||
register: syncdesktop
|
||||
|
||||
- name: remove deprecated desktop-files
|
||||
ansible.builtin.shell: rm -f /usr/local/share/applications/*.desktop
|
||||
when: not syncdesktop.stat.exists
|
||||
notify: Run update-desktop-database
|
||||
|
||||
- name: Copy initial sync starter
|
||||
ansible.builtin.copy:
|
||||
src: sync.desktop
|
||||
dest: /usr/local/share/applications/
|
||||
notify: Run update-desktop-database
|
||||
|
||||
- name: Start virt-manager in session mode by default
|
||||
ansible.builtin.copy:
|
||||
dest: /usr/local/bin/virt-manager
|
||||
content: |
|
||||
#!/usr/bin/sh
|
||||
exec /usr/bin/virt-manager --connect qemu:///session $@
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy vm-netboot script
|
||||
ansible.builtin.copy:
|
||||
src: vm-netboot
|
||||
dest: /usr/local/bin/
|
||||
mode: '0755'
|
11
roles/lmn_vm/templates/squid-usermode.conf.j2
Normal file
11
roles/lmn_vm/templates/squid-usermode.conf.j2
Normal file
|
@ -0,0 +1,11 @@
|
|||
acl local-servers dstdomain .{{ domain }}
|
||||
cache_peer firewall.{{ domain }} parent 3128 0 no-query default login=NEGOTIATE auth-no-keytab
|
||||
never_direct deny local-servers
|
||||
never_direct allow all
|
||||
#access_log stdio:/tmp/access.log squid
|
||||
access_log none
|
||||
cache_log /dev/null
|
||||
logfile_rotate 0
|
||||
pid_filename none
|
||||
http_port 192.168.122.1:3128
|
||||
http_access allow all
|
60
roles/lmn_wlan_iwd/tasks/main.yml
Normal file
60
roles/lmn_wlan_iwd/tasks/main.yml
Normal file
|
@ -0,0 +1,60 @@
|
|||
## Make sure to use an initrd providing firmware:
|
||||
## wget https://cdimage.debian.org/cdimage/firmware/testing/current/firmware.cpio.gz
|
||||
## cat initrd.gz firmware.cpio.gz > initrd-fw.gz
|
||||
---
|
||||
- name: Install packages related to iwd and wifi
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- iwd
|
||||
- systemd-resolved
|
||||
- firmware-realtek # for our wifi sticks
|
||||
- rfkill
|
||||
state: latest
|
||||
|
||||
- name: Disable wpa-supplicant
|
||||
ansible.builtin.systemd:
|
||||
name: wpa_supplicant.service
|
||||
enabled: False
|
||||
|
||||
- name: Enable iwd
|
||||
ansible.builtin.systemd:
|
||||
name: iwd.service
|
||||
enabled: True
|
||||
|
||||
- name: Prepare directory for iwd
|
||||
file:
|
||||
path: /var/lib/iwd/
|
||||
state: directory
|
||||
|
||||
- name: Configure iwd for wifi device
|
||||
ansible.builtin.copy:
|
||||
dest: /var/lib/iwd/{{ ssid }}.psk
|
||||
content: |
|
||||
[Security]
|
||||
Passphrase={{ wifipasswd }}
|
||||
|
||||
- name: Enable systemd-networkd
|
||||
ansible.builtin.systemd:
|
||||
name: systemd-networkd.service
|
||||
enabled: True
|
||||
|
||||
|
||||
- name: Provide service to enable WiFi on boot
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/system/enable-wifi.service
|
||||
content: |
|
||||
[Unit]
|
||||
Description=Switch WiFi on
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/sbin/rfkill enable wifi
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
- name: Enable the enable-wifi service
|
||||
ansible.builtin.systemd:
|
||||
name: enable-wifi.service
|
||||
enabled: True
|
||||
daemon_reload: True
|
24
roles/lmn_wlan_nm/tasks/main.yml
Normal file
24
roles/lmn_wlan_nm/tasks/main.yml
Normal file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
- name: Configure WLAN for devices
|
||||
community.general.nmcli:
|
||||
conn_name: "{{ ssid }}"
|
||||
type: wifi
|
||||
ssid: "{{ ssid }}"
|
||||
ifname: "{{ ansible_interfaces | select('search', 'wl.+') | first }}"
|
||||
wifi_sec:
|
||||
key-mgmt: wpa-psk
|
||||
psk: "{{ wifipasswd }}"
|
||||
autoconnect: true
|
||||
state: present
|
||||
when: |
|
||||
not run_in_installer|default(false)|bool and
|
||||
ansible_interfaces | select('search', 'wl.+') | first is defined
|
||||
|
||||
- name: Provide WLAN config during installation
|
||||
template:
|
||||
src: ssid.nmconnection.j2
|
||||
dest: "/etc/NetworkManager/system-connections/{{ ssid }}.nmconnection"
|
||||
mode: '0600'
|
||||
when: |
|
||||
run_in_installer|default(false)|bool and
|
||||
ansible_interfaces | select('search', 'wl.+') | first is defined
|
21
roles/lmn_wlan_nm/templates/ssid.nmconnection.j2
Normal file
21
roles/lmn_wlan_nm/templates/ssid.nmconnection.j2
Normal file
|
@ -0,0 +1,21 @@
|
|||
[connection]
|
||||
id=FVS-devices
|
||||
type=wifi
|
||||
interface-name={{ ansible_interfaces | select('search', 'wl.+') | first }}
|
||||
|
||||
[wifi]
|
||||
mode=infrastructure
|
||||
ssid=FVS-devices
|
||||
|
||||
[wifi-security]
|
||||
key-mgmt=wpa-psk
|
||||
psk={{ wifipasswd }}
|
||||
|
||||
[ipv4]
|
||||
method=auto
|
||||
|
||||
[ipv6]
|
||||
addr-gen-mode=default
|
||||
method=auto
|
||||
|
||||
[proxy]
|
2
roles/up2date_debian/defaults/main.yml
Normal file
2
roles/up2date_debian/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
extra_pkgs: ""
|
||||
extra_pkgs_bpo: ""
|
49
roles/up2date_debian/tasks/main.yml
Normal file
49
roles/up2date_debian/tasks/main.yml
Normal file
|
@ -0,0 +1,49 @@
|
|||
# Update lists and upgrade packages.
|
||||
|
||||
- name: update apt package lists
|
||||
apt:
|
||||
update_cache: true
|
||||
cache_valid_time: 86400
|
||||
|
||||
- block:
|
||||
- name: upgrade packages
|
||||
apt:
|
||||
upgrade: dist
|
||||
autoremove: true
|
||||
autoclean: true
|
||||
rescue:
|
||||
- name: Looks like dpkg was interrupted, configure manually
|
||||
command:
|
||||
cmd: dpkg --configure -a
|
||||
- name: Try again to upgrade packages
|
||||
apt:
|
||||
upgrade: dist
|
||||
autoremove: true
|
||||
autoclean: true
|
||||
|
||||
- name: install etckeeper
|
||||
apt:
|
||||
name: etckeeper
|
||||
state: latest # noqa package-latest
|
||||
|
||||
- name: install extra packages from stable
|
||||
apt:
|
||||
name: "{{ extra_pkgs }}"
|
||||
state: latest # noqa package-latest
|
||||
when: extra_pkgs|length
|
||||
|
||||
- name: add {{ ansible_distribution_release }}-backports
|
||||
apt_repository:
|
||||
repo: >
|
||||
deb http://deb.debian.org/debian/ {{ ansible_distribution_release }}-backports
|
||||
main non-free-firmware
|
||||
state: present
|
||||
update_cache: true
|
||||
when: extra_pkgs_bpo|length
|
||||
|
||||
- name: install extra packages from backports
|
||||
apt:
|
||||
name: "{{ extra_pkgs_bpo }}"
|
||||
state: latest # noqa package-latest
|
||||
default_release: "{{ ansible_distribution_release }}-backports"
|
||||
when: extra_pkgs_bpo|length
|
24
tools/collector
Executable file
24
tools/collector
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/bash
|
||||
#
|
||||
# collect messages from reporter and drop them into log files
|
||||
#
|
||||
set -eu
|
||||
|
||||
port=1234
|
||||
#logdir="/var/log/collector"
|
||||
logdir="/tmp/collector"
|
||||
|
||||
mkdir -vp "$logdir"
|
||||
|
||||
nc -k -l -u -p "$port" | while read line ; do
|
||||
sndr="${line%% *}"
|
||||
msg="${line#* }"
|
||||
if [[ "$sndr" =~ [a-z0-9]+ ]] ; then
|
||||
if [[ "$msg" =~ ^-------\ .+\ -------$ ]] ; then
|
||||
echo "$(date --rfc-3339=seconds) → Report from '$sndr' received."
|
||||
echo "$msg" > "$logdir/$sndr"
|
||||
else
|
||||
echo "$msg" >> "$logdir/$sndr"
|
||||
fi
|
||||
fi
|
||||
done
|
93
tools/emitter
Executable file
93
tools/emitter
Executable file
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/bash
|
||||
#
|
||||
# Run ansible on all hosts older than the latest git commit.
|
||||
# Use argument "$(date)" to update all machines independent
|
||||
# of the last ansible run.
|
||||
#
|
||||
set -eu
|
||||
|
||||
## maximal age of file in minutes:
|
||||
age="15"
|
||||
|
||||
pbook="lmn-client"
|
||||
logdir="/tmp/collector"
|
||||
debug=false
|
||||
|
||||
## date of latest git commit in ansible repository:
|
||||
git_date="$(date --iso-8601=seconds --date="$(git log --date=iso-strict | \
|
||||
head -3 | sed -nE "s/^Date:\s+(.+)$/\1/p")")"
|
||||
echo "Latest commit in git at: $git_date."
|
||||
|
||||
if [[ $# = 0 ]] ; then
|
||||
timestamp="$git_date"
|
||||
else
|
||||
timestamp="$(date --iso-8601=seconds --date="$1")"
|
||||
fi
|
||||
echo "Time stamp at: $timestamp."
|
||||
|
||||
#dir="$(mktemp -d)"
|
||||
dir="/tmp/emitter"
|
||||
mkdir -vp "$dir"
|
||||
|
||||
hlist=""
|
||||
n=0
|
||||
running=0
|
||||
ansible_arg=""
|
||||
|
||||
find_outdated(){
|
||||
hlist=""
|
||||
n=0
|
||||
running=0
|
||||
ansible_arg="--tags=upgrade"
|
||||
while IFS= read -r -d '' file ; do
|
||||
running=$(( running + 1 ))
|
||||
$debug && echo -n "Processing host '$file' with IP address "
|
||||
d="$(sed -nE "s/^2\s+(\S.+)$/\1/p" "$file")"
|
||||
if [[ -z "$d" ]] || \
|
||||
[[ $(date --date="$d" +%s) -lt $(date --date="$timestamp" +%s) ]] ; then
|
||||
r='([0-9]{1,3}\.){3}[0-9]{1,3}'
|
||||
ipa="$(sed -nE "s/^3\s+default via.+ src ($r) metric.+/\1/p" "$file")"
|
||||
if [[ -z "$ipa" ]] ; then
|
||||
# FIXME: Outdated report format, try fallback:
|
||||
ipa="$(sed -nE "s|^.+default via.+ src ($r) metric.+|\1|p" "$file" | head -1)"
|
||||
echo -ne "\n Outdated '$ipa': $file"
|
||||
fi
|
||||
hlist="$hlist,$ipa"
|
||||
n=$(( n + 1 ))
|
||||
if [[ $(date --date="$d" +%s) -lt $(date --date="$git_date" +%s) ]] ; then
|
||||
## ansible run needed at least on one machine, run it on all:
|
||||
echo -n "✗"
|
||||
ansible_arg=""
|
||||
else
|
||||
echo -n "U"
|
||||
fi
|
||||
else
|
||||
echo -n '✓'
|
||||
fi
|
||||
done < <(find "$logdir" -maxdepth 1 -type f -mmin -$age -print0)
|
||||
hlist="${hlist#,}"
|
||||
echo -n " $n/$running "
|
||||
}
|
||||
|
||||
run_ansible(){
|
||||
local hsts="$1"
|
||||
if [[ -n "$hsts" ]] ; then
|
||||
if ! echo | eval ANSIBLE_RETRY_FILES_ENABLED=1 ANSIBLE_RETRY_FILES_SAVE_PATH="$dir" \
|
||||
ansible-playbook --vault-password-file ~/.vaultpwd \
|
||||
-bi inventory.yml "$pbook.yml" "$ansible_arg" -l "$hsts" ; then
|
||||
while IFS= read -r ipa ; do
|
||||
echo "Ansible for IP address '$ipa' failed."
|
||||
done < "$dir/$pbook.retry"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#################
|
||||
while true ; do
|
||||
date +%H:%M | tr '\n' ' '
|
||||
find_outdated
|
||||
run_ansible "$hlist"
|
||||
t=$(( 600/(n*n+1) ))
|
||||
echo "sleeping ${t}s "
|
||||
sleep $t
|
||||
done
|
17
tools/wol-generator.sh
Executable file
17
tools/wol-generator.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/bash
|
||||
#
|
||||
# Pipe the '--list-hosts' output of ansible into this program to wake up all corresponding hosts:
|
||||
#
|
||||
# ansible-playbook [...] -i inventory/inventory.yml -l R317 --list-hosts | ./wol-generator.sh
|
||||
#
|
||||
set -eu
|
||||
|
||||
tmpf="$(mktemp)"
|
||||
devs='devices.csv'
|
||||
|
||||
while read -r line ; do
|
||||
sed -nE -e "s%.*(..:..:..:..:..:..);(${line//./\\.});.*%\1 \2%p" "$devs" >> "$tmpf"
|
||||
done < <(cat - | grep -E "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
|
||||
|
||||
wakeonlan -f "$tmpf"
|
||||
rm "$tmpf"
|
Loading…
Add table
Reference in a new issue