Liigu peamise sisu juurde

Mitme .NET 10 rakenduse paigaldamine ühte kausta ilma DLL-konfliktideta

· 10 min lugemine
Infokiir OÜ

1. Probleem

.NET 10 rakenduse tavaline raamistikupõhine (framework-dependent) Release-ehitus tekitab kausta hulga faile, mis näivad jagatavatena, kuid enamasti seda ei ole:

AlamkollektsiooniKopeerimineValikuga.deps.json
AlamkollektsiooniKopeerimineValikuga.dll
AlamkollektsiooniKopeerimineValikuga.exe
AlamkollektsiooniKopeerimineValikuga.pdb
AlamkollektsiooniKopeerimineValikuga.runtimeconfig.json
AlamkollektsiooniKopeerimineValikugaLib.dll / .pdb
BouncyCastle.Crypto.dll
Google.Protobuf.dll
K4os.Compression.LZ4.dll
K4os.Compression.LZ4.Streams.dll
K4os.Hash.xxHash.dll
MySql.Data.dll
System.CommandLine.dll
cs\ de\ es\ fr\ it\ ja\ ko\ pl\ pt-BR\ ru\ tr\ zh-Hans\ zh-Hant\ (satelliit-ressursiteegid)
runtimes\ (natiivteegid)

Kui teise rakenduse ehitustulemus paigutada samasse kausta, tekib klassikaline DLL-põrgu: kui kaks rakendust viitavad sama NuGet-paketi eri versioonidele (nt MySql.Data 8.0.33 vs 8.4.x), jääb peale see, kelle failid viimasena kopeeriti. Iga rakenduse deps.json sisaldab täpselt seda versiooni, millega rakendus kompileeriti, mistõttu „kaotanud" rakendus võib käivitumisel anda teegi laadimise vea või – veelgi halvem – töötada vaikselt valesti.

Milleks iga väljundfail on

FailOtstarveRakenduste vahel jagatav?
*.deps.jsonTäpne sõltuvuste graaf (teegid + versioonid), mida host käivitumisel loebEi – rangelt rakendusepõhine
*.runtimeconfig.jsonSihtruntime'i versioon ja seadedEi – rangelt rakendusepõhine
*.exe (apphost)Natiivne käivitaja, mis on kõvasti seotud rakenduse põhi-DLL-igaEi – definitsiooni järgi rakendusepõhine
Rakenduse .dll / .pdbRakenduse kompileeritud IL-kood ja silumissümbolidEi
NuGet-sõltuvuste DLL-idKopeeritakse ehitamisel NuGet-vahemälustAinult siis, kui kõik rakendused kasutavad täpselt samu paketiversioone
Keelekaustad (cs, de, …)Satelliit-ressursiteegid (lokaliseeritud sõnumid, siin MySql.Data omad)Sama versioonisõltuvuse probleem
runtimes\Platvormispetsiifilised natiivteegid NuGet-pakettidestSama versioonisõltuvuse probleem

.NET runtime ise raamistikupõhise ehituse puhul selles kaustas ei ole – see on paigaldatud masinaüleselt ja on niikuinii jagatud. Kõik väljundkaustas olev on rakenduse enda pagas.

Viide: .NET-rakenduste avaldamise ülevaade – https://learn.microsoft.com/en-us/dotnet/core/deploying/


2. Samm 1 – tarbetute satelliit- (keele-) teekide eemaldamine

Kolmteist keelekausta pärinesid MySql.Data lokaliseeritud veateadetest. Kui ingliskeelsetest sõnumitest piisab, piirab MSBuild-atribuut SatelliteResourceLanguages väljundisse kopeeritavaid satelliitteeke:

<PropertyGroup>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>

Praktikas selgunud olulised detailid:

  1. Atribuut peab olema seatud käivitatava projekti failis. Iga projekt otsustab ise, millised satelliitteegid ta oma NuGet-sõltuvustest väljundisse kopeerib, seega ainult viidatud klassiteegis seadmine käivitatava projekti väljundit ei puhasta. Mõlemas projektis seadmine on ohutu.
  2. Lahendusülene alternatiiv: paiguta atribuut üks kord lahenduse juurkausta faili Directory.Build.props – MSBuild rakendab selle automaatselt kõigile allolevatele projektidele:
<Project>
<PropertyGroup>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>
</Project>
  1. Clean ega Rebuild vanu kaustu ei eemalda. dotnet clean / VS Clean kustutab ainult faile, mis on kirjas eelmise ehituse jälgimislogis. Kui uus ehitus satelliitteeke enam ei tooda, muutuvad vanad kaustad orbudeks, mida ükski ehitussamm ei „oma". Õnnestumist saab kontrollida deps.json faili suuruse vähenemisest (antud juhul 7 756 → 6 191 baiti); seejärel kustuta bin-kaust käsitsi üks kord. Kaustad enam tagasi ei teki.

Viited:


3. Samm 2 – ühefaililine avaldamine (single-file publish)

Ühefaililine avaldamine pakendab rakenduse DLL-i ja kõik hallatavad (managed) NuGet-sõltuvused exe-faili sisse. Hallatavad teegid laaditakse otse pakendist mällu (kettale midagi lahti ei pakita). See kõrvaldab peaaegu kõik jagatud failidest tulenevad konfliktid.

Töötav avaldamisprofiil (Properties\PublishProfiles\FolderProfile.pubxml):

<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\net10.0-windows7.0\publish\win-x64\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net10.0-windows7.0</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
</Project>

Sama käsurealt:

dotnet publish -c Release -r win-x64 --self-contained false ^
-p:PublishSingleFile=true ^
-p:IncludeNativeLibrariesForSelfExtract=true ^
-p:DebugType=none -p:DebugSymbols=false

Atribuutide selgitused

PublishSingleFile=true Pakendab rakenduse ja kõik hallatavad sõltuvused üheks käivitatavaks failiks. Nõuab RuntimeIdentifier-i, sest apphost on platvormispetsiifiline. Dokumentatsioon: https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview

SelfContained=false (raamistikupõhine) .NET 10 runtime'i pakendisse ei lisata; see peab olema sihtmasinas paigaldatud. Nii jäi exe suuruseks ~7 MB. Väärtus true pakendaks kogu runtime'i (~70+ MB exe kohta), kuid kaotaks runtime'i paigaldamise nõude. Dokumentatsioon: https://learn.microsoft.com/en-us/dotnet/core/deploying/

RuntimeIdentifier=win-x64 Valib sihtplatvormi natiivse apphost'i ja natiivsõltuvuste jaoks. RID-kataloog: https://learn.microsoft.com/en-us/dotnet/core/rid-catalog

IncludeNativeLibrariesForSelfExtract=true Vaikimisi (alates .NET 5-st) jätab ühefaililine avaldamine natiivsed DLL-id lahtiste failidena exe kõrvale. Selles projektis olid nendeks MySql.Data Kerberos/GSSAPI teegid: comerr64.dll, gssapi64.dll, k5sprt64.dll, krb5_64.dll, krbcc64.dll – viimane allesjäänud konfliktipind. Selle atribuudiga pakitakse natiivteegid exe sisse ja pakitakse käivitumisel lahti rakendusepõhisesse ajutisse kausta, mistõttu erinevad rakendused ei puutu kunagi üksteise natiivfaile. Exe kasvas umbes 1,8 MB võrra. Dokumentatsioon (sama leht, jaotis „Include native libraries"): https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview (Lahtipakkimise asukohta saab vajadusel suunata keskkonnamuutujaga DOTNET_BUNDLE_EXTRACT_BASE_DIR – kirjeldatud samal lehel.)

DebugType=none + DebugSymbols=false Keelab .pdb-failide genereerimise Release/publish puhul täielikult. Tähelepanu: avaldamisprofiil mõjutab ainult käivitatavat projekti; viidatud klassiteek kompileerub oma seadetega ja tekitab endiselt .pdb faili. Töökindel lahendus on seada need atribuudid projektipõhiselt (või üks kord failis Directory.Build.props), tingimusega Release-konfiguratsioonile, et Debug-ehitused säilitaksid täielikud sümbolid:

<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>

Teadmist väärt alternatiiv: DebugType=embedded paigutab sümbolid exe sisse – lahtist .pdb-d pole, kuid stack trace'id säilitavad faili- ja reainfo. Kasulik, kui välidiagnostika on paarisaja kilobaidi kokkuhoiust olulisem. Dokumentatsioon: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/code-generation

PublishReadyToRun=false ReadyToRun kompileerib IL-koodi ette natiivkoodiks, mis kiirendab käivitumist suurema faili hinnaga. Siin välja lülitatud; lülita sisse rakendusepõhiselt, kui käivituskiirus on oluline. Dokumentatsioon: https://learn.microsoft.com/en-us/dotnet/core/deploying/ready-to-run

Tulemus

Pärast vana publish-kausta ühekordset kustutamist (publish, nagu ka clean, ei eemalda eelmiste konfiguratsioonide orvuks jäänud faile) ja uuesti avaldamist:

AlamkollektsiooniKopeerimineValikuga.exe (~7 MB, üks fail)

Muud midagi. Hallatavad sõltuvused, satelliitteekide käsitlus ja natiivsed Kerberos-teegid on kõik exe sees.


4. Mitme rakenduse paigaldamine ühte kausta

Ülaltoodud seadistusega võib ühte jagatud kausta paigutada ükskõik kui palju rakendusi:

  1. Iga rakendus on üks unikaalse nimega exe – jagatud faile pole, seega on versioonikonfliktid välistatud.
  2. Natiivteegid pakitakse käivitumisel lahti rakendusepõhistesse ajutistesse kaustadesse, seega ei teki ka käitusaegseid kokkupõrkeid.
  3. Iga rakendus võib kasutada MySql.Data või mis tahes muu paketi erinevat versiooni, mõjutamata teisi.

Üks praktiline soovitus: ära suuna mitme projekti PublishDir-i otse samasse jagatud kausta. Publish-samm võib kustutada faile, mida ta peab aegunuks, ja nii võib kaduma minna teise rakenduse exe. Ohutum muster:

avalda iga projekt oma kausta (nagu ülal seadistatud)

└──► kopeeri valminud exe-failid ühisesse paigalduskausta

Kopeerimise saab teha väikese skriptiga või MSBuildi publish-järgse sammuna, näiteks:

<Target Name="CopyToDeployFolder" AfterTargets="Publish">
<Copy SourceFiles="$(PublishDir)$(AssemblyName).exe"
DestinationFolder="E:\LenneApps\Deploy\" />
</Target>

5. Ühefaililise paigalduse kompromissid ja tähelepanekud

  • Raamistikupõhine ühefaililine exe nõuab endiselt .NET 10 runtime'i igas sihtmasinas. Ettevõttesisese paigalduse puhul, kus runtime'i hallatakse tsentraalselt, on see enamasti õige valik: exe-d jäävad väikeseks ja runtime'i turvapaigad rakenduvad kõigile rakendustele korraga.
  • Mõned API-d käituvad ühefaililises rakenduses teisiti. Assembly.Location tagastab tühja stringi; kood, mis selle põhjal teid koostab, peab kasutama hoopis AppContext.BaseDirectory-t. Kolmandate osapoolte paketid komistavad selle otsa aeg-ajalt. Täielik ühilduvustabel: https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview (jaotis „API incompatibility").
  • Valikuline suuruse vähendamine: EnableCompressionInSingleFile=true pakib pakendatud teegid kokku väikese käivitusaja hinnaga. Trimmimine (PublishTrimmed=true) on saadaval ainult self-contained rakendustele ja vajab testimist refleksioonirohkete teekidega nagu MySql.Data.
  • Rusikareegel aegunud failide kohta: kui ehitus- või avaldamisseaded muudavad, mida toodetakse, kustuta vana bin-/publish-kaust üks kord. Ei Clean ega Publish ei eemalda faile, mida uus konfiguratsioon enam ei genereeri.

6. Ühefaililise avaldamise ajalugu ja Windowsi tugi

Kuidas võimalus arenes

  • .NET Core 3.0 (september 2019)PublishSingleFile ilmus esimest korda. Toona oli see sisuliselt isepakkiv arhiiv: käivitumisel pakiti kõik failid (nii hallatavad kui natiivsed) kettale ajutisse kausta lahti ja käivitati sealt.
  • .NET 5 (november 2020) – praegune „päris" ühefaililine mudel: hallatavad teegid laaditakse otse exe seest mällu, kettale ei pakita midagi. Samas versioonis tuli ka IncludeNativeLibrariesForSelfExtract, sest natiivteegid jäeti nüüd vaikimisi pakendist välja (varem pakiti kõik kaasa). Just seda kombinatsiooni käesolev juhend kasutabki.
  • .NET 6 (november 2021) – lisandus EnableCompressionInSingleFile pakendatud teekide kokkupakkimiseks ning mudel stabiliseerus tänasel kujul.

Seega on selles dokumendis kirjeldatud tehnika (mällu laadimine + natiivteekide kaasapakkimine) olemas alates .NET 5-st, novembrist 2020.

Millised Windowsi versioonid tulemust jooksutavad

.NET 10 on ametlikult toetatud Windows 11 (23H2, 24H2, 25H2, 26H1) ja Windows 10 peal alates versioonist 1607 (Enterprise/LTSC kanalid: 1607, 1809, 21H2). Praktikas tähendab see Windows 10 (1607+) ja Windows 11. Tavaline Windows 10 22H2 langes ametlikust toest välja koos Windowsi enda toe lõppemisega oktoobris 2025, kuigi rakendused seal endiselt töötavad. Windows 7 ja 8.1 peal .NET 10 ei tööta üldse – nende tugi kadus juba .NET 7/8 ajal.

Märkus TFM-i net10.0-windows7.0 kohta: „7.0" ei tähenda Windows 7 tuge. See on lihtsalt vaikimisi deklareeritav minimaalne Windowsi API versioon, mille MSBuild paneb, kui <TargetFramework>net10.0-windows</TargetFramework> on kirjutatud ilma versioonita. Tegelik miinimum-OS on see, mida runtime ise toetab.

Ajakohane .NET 10 toetatud operatsioonisüsteemide nimekiri: https://github.com/dotnet/core/blob/main/release-notes/10.0/supported-os.md


7. Natiivmaailm: kuidas teha C++ rakendusest üks .exe fail

Natiivrakendustel puudub .NET-i laadne bundle-mehhanism, mida runtime oskaks mälust laadida, seega on lähenemised teistsugused.

Variant 1 – staatiline linkimine (soovitatav)

Sõltuvused lingitakse kompileerimisel .lib staatiliste teekidena otse exe sisse, DLL-e ei tekigi. MSVC puhul tähendab see runtime'i lülitit /MT (/MD asemel) ja kolmandate osapoolte teekide staatilisi variante. vcpkg teeb selle lihtsaks: triplet x64-windows-static ehitab kõik sõltuvused staatilistena. Tulemus on üksainus exe ilma käitusaegse maagiata – kiireim käivitus ja kõige töökindlam variant. Miinused: suurem exe, iga teegi uuendus nõuab uuesti linkimist, ja mõned litsentsid (nt LGPL, sh Qt) seavad staatilisele linkimisele piiranguid.

Variant 2 – DLL-ide pakkimine valmis exe sisse

Tööriistad nagu Enigma Virtual Box (tasuta) või BoxedApp Packer võtavad valmis exe + DLL-id ja teevad neist ühe faili, mis virtualiseerib failisüsteemi kutsed – DLL-id eksisteerivad ainult mälus. Töötab ka siis, kui lähtekoodi või staatilisi teeke pole (suletud lähtekoodiga DLL-id). Miinused: viirusetõrjed suhtuvad pakitud exe-desse kohati kahtlustavalt ning COM-registreerimist vajavad DLL-id ei pruugi töötada.

Variant 3 – DLL ressursina ja mälust laadimine

DLL-id paigutatakse exe ressurssidesse ja laaditakse käivitumisel kas ajutisse kausta tavalise LoadLibrary-ga (nagu .NET Core 3.0 omal ajal tegi) või otse mälust MemoryModule teegiga, mis implementeerib oma PE-laadija. Kõige paindlikum, aga ka kõige rohkem käsitööd nõudev tee; MemoryModule'il on piirangud (erandikäsitlus x64-l, mõned DLL-id eeldavad failitee olemasolu).

Järeldus

GUI-rakenduste puhul on staatilise linkimisega natiivset exe-d tegelikult harva vaja: .NET raamistiku kasutamine on hästi hallatav, arendus on kiirem ning jõudlus ei jää natiivrakendusele oluliselt alla. Ühefaililine .NET-avaldamine (peatükid 3–4) annab sama paigaldusmugavuse – üks exe, null DLL-konflikti – ilma natiivmaailma linkimis- ja litsentsimuredeta. Natiivne staatiline linkimine tasub end ära peamiselt siis, kui runtime'i paigaldamine sihtmasinasse pole võimalik, rakendus peab olema minimaalse mälujäljega või tegu on niikuinii C++ koodibaasiga (nt riistvaralähedased tööriistad).


8. Kiirviited – dokumentatsiooni lingid

TeemaLink
Ühefaililine paigaldus (PublishSingleFile, IncludeNativeLibrariesForSelfExtract, lahtipakkimine, API piirangud)https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview
.NET paigaldusmudelid (raamistikupõhine vs self-contained)https://learn.microsoft.com/en-us/dotnet/core/deploying/
SDK-projektide MSBuild-atribuudid (SatelliteResourceLanguages, publish-atribuudid)https://learn.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props
Directory.Build.props / ehituse kohandamine kaustapõhiselthttps://learn.microsoft.com/en-us/visualstudio/msbuild/customize-by-directory
DebugType / DebugSymbols kompilaatoriseadedhttps://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/code-generation
ReadyToRun kompileeriminehttps://learn.microsoft.com/en-us/dotnet/core/deploying/ready-to-run
Runtime identifier (RID) katalooghttps://learn.microsoft.com/en-us/dotnet/core/rid-catalog
Self-contained rakenduste trimmiminehttps://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trim-self-contained

Uus koduleht 2026

· Ühe min lugemine
Infokiir OÜ
  1. aasta lõpus sai siinsamas kirjutatud, et vana koduleht oli liiga kaua muutumatuna püsinud. Ajalugu kordub — vahepeal möödus kaheksa aastat ja nüüd oli jälle aeg uuenduseks.

Kummalise SSH vea lahendamine

· Ühe min lugemine
Infokiir OÜ

See artikkel on pisike jätk varasemale artiklile:

https://www.asjade.net/varia-menu/81-maengud-ssh-ga

Pärast Ubuntu 20.04 focal üleminekut uuemale Ubuntu 22.04 jammy versioonile ei toiminud enam võtmeid vahetades ssh ühendus ühe Synology NAS seadmega. Tuli parooli küsimise rida ning sisestades õige salasõna oli võimalik ikka sisse saada.

Sedasorti probleemide lahendamisel aitab -vvv võtme lisamine ssh käsureale. Lisaks sellele kasuta ikka Google otsingut, kuid ära pelga ka uut populaarset ChatGPT https://en.wikipedia.org/wiki/ChatGPT teenust https://chat.openai.com. See võib lahenduseni viia kiiremini kui arvata oskad.

Lahenduseks oli seekord selline:

touch ~/.ssh/config
chmod 600 ~/.ssh/config
nano ~/.ssh/config

cat ~/.ssh/config
Host tegelik.ip.aadress
PubkeyAcceptedKeyTypes +ssh-rsa
KexAlgorithms +diffie-hellman-group14-sha1
HostKeyAlgorithms +ssh-rsa

Rohkem selle kohta lugemist:

https://askubuntu.com/questions/1409105/ubuntu-22-04-ssh-the-rsa-key-isnt-working-since-upgrading-from-20-04

MacBook Pro Ubuntu Desktop 20.04 LTS Linux ja USB klaviatuur

· Ühe min lugemine
Infokiir OÜ

Kuidas installida Ubuntu Desktop 20.04 LTS Linux MacBook Pro sülearvutile USB mälupulgale?

macbook-ubuntu

Selle kohta sai tehtud 2 videot:

https://www.youtube.com/watch?v=mo440sAe2dQ

https://www.youtube.com/watch?v=F7ZHVNVBuN8

Selleks, et GRUB käsureal oleks kergem tööd teha, sai tehtud ka USB klaviatuur, mis saadab klahvivajutused järjestikpordi kaudu:

https://www.youtube.com/watch?v=ZbuvjBGOJGg

Vastavad github leheküljed:

https://github.com/asjadenet/macbook-ubuntu-usb

https://github.com/asjadenet/serial2keyb

https://github.com/asjadenet/serial2keyb-byline

Pordi suunamine turvalisemaks OpenWrt ruuteriga

· 4 min lugemine
Infokiir OÜ

Ei ole just ebatavaline olukord, kus meil on vaja sisevõrgust mingi teenus kättesaadavaks teha avalikule internetile. Seda saab suhteliselt lihtsasti teha pordi suunamisega. Näiteks Cisco EPC3940 modemil näeb see välja selliselt:

Cisco EPC3940

Kui teeme lahti pordi 22 ja meil on see edasi suunatud ssh serveri teenusele, siis võime näha logidest umbes sellist vaatepilti:

ssh auth fail log

Kui nüüd ip aadresside haaval uurida, siis võime leida, et üritajaid on olnud Hiinast, Vietnamist, Lõuna-Koreast ja mujaltki.

Loomulikult tuleb tahtmine nende üritajate elu raskemaks teha ja need IP aadressid ära keelata. Tavalise ruuteri tarkvaras ei pruugi aga sellist võimalust olla. Õnneks on populaarses vabavaralises ruuteri tarkvaras OpenWrt see võimalik. Sellepärast tasuks enne uue ruuteri ostmist uurida, kui hästi see OpenWrt OS-i toetab. Näiteks üks populaarne ruuter on TP-LINK Wireless Access Point Archer C7 AC1750 Dual Band Gigabit wireless Router

Selle asemel, et hoida ajakohasena pikka nimekirja, kust me ühendusi ei soovi, võime teha ka nn "valge nimekirja" IP-aadressidest, kust me soovime ligipääsu lubada.

Mängime nüüd läbi olukorra, kus tahame lubada ligipääsu vaid Eesti IP aadressidelt ja mitte kusagilt mujalt.

Esiteks on meil vaja nimekirja Eesti IP aadressruumist. Abiks on selline pisike tööriist nagu get-ripe-ips. See on bash skript, mis laadib aadressid json vormingus alla ja salvestab tekstifailina. On ka teisi võimalusi. Vaatame siin vaid ühte.

$ git clone https://github.com/mivk/ip-country.git
$ chmod +x get-ripe-ips
$ ./get-ripe-ips -c ee -o . -s 1800
./get-ripe-ips: line 74: hash: jq: ei leitud
Cannot find the jq Json processor. Install it with 'apt install jq' or similar
$ sudo apt install jq
$ ./get-ripe-ips -c ee -o . -s 1800
$ head ipv4_ee
2.57.220.0/22
2.59.164.0/22
5.34.240.0/21
5.44.184.0/21
5.45.112.0/21
5.45.120.0/21
5.101.112.0/20
5.101.176.0/20
5.153.232.0/21
5.157.0.0/18

Selliselt on meil IP aadressid failis ipv4_ee olemas.

Vaikimisi ei ole ruuteris installeeritud ipset utiliiti, kuid selle võib installeerida veebiliidese abil:

openwrt-ipset

Samuti võime testimiseks installida netcat: openwrt-netcat

Kopeerin selle faili ruuteris asukohta /usr/opt/geoip-ee/ipv4_ee.

Muudan ruuteris faili /etc/firewall.user:

root@OpenWrt:~# cat /etc/firewall.user
# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.

# Internal uci firewall chains are flushed and recreated on reload, so
# put custom rules into the root chains e.g. INPUT or FORWARD or into the
# special user chains, e.g. input_wan_rule or postrouting_lan_rule
ipset create ipv4_ee hash:net
while read network ; do
ipset add ipv4_ee $network;
done < /usr/opt/geoip-ee/ipv4_ee

Teeme ruuterile restardi. Seejärel logime sisse ja vaatame, kas igal käivitamisel tehakse ipset nimega ipv4_ee. Seda saame vaadata käsklusega:

ipset list ipv4_ee

Kui ilmub nimekiri IP aadressidega, siis on sellega korras.

Proovime kõigepealt pordi suunamist ilma ip aadresside piiranguteta.

openwrt-port-fw1 openwrt-port-fw1a

Käivitan ruuteris:

netcat -l -p 8080

Proovin Eestis paiknevast masinast:

connect-test-eesti1

listen-test-eesti1

Sama Inglismaal paiknevast masinast:

connect-test-uk1

listen-test-uk1

Nagu näha, pordi suunamine töötab ja see on ligipääsetav igalt poolt maailmas.

Paneme nüüd piirangu peale, lisades tulemüüris Extra arguments reale: -m set --match-set ipv4_ee src.

openwrt-extra-arguments

Proovime nüüd uuesti. Kui meil on kõik õigesti, siis peaksime endiselt Eestist ligi pääsema, kuid Inglismaalt enam mitte:

connect-test-eesti1

listen-test-eesti2

Sama Inglismaal paiknevast masinast:

connect-test-uk2

Mida öelda kokkuvõtteks? Kui meil on kasutada OpenWrt ruuter, siis tasub ligipääs IP aadresside järgi ära seadistada. Nagu nägime, ei olegi seda nii raske teha.

Linke:

https://openwrt.org/toh/tp-link/archer-c5-c7-wdr7500

https://unix.stackexchange.com/questions/502907/how-to-block-countries-iptables-or-firewalld-by-geolite2-mmdb/527504#527504

https://unix.stackexchange.com/questions/516504/iptables-to-allow-traffic-from-one-country-only

Mitte keegi ei taha rohkem tarkvara…

· Ühe min lugemine
Infokiir OÜ

tarkvara

Photo by Fotis Fotopoulos on Unsplash

Mitte keegi ei taha rohkem tarkvara… See on täitsa tõsi. Tarkvara ei ole vaja lihtsalt tarkvara pärast. Kellele meeldiks iga päev paigaldada oma arvutisse aina uusi programme või proovida internetis üha uusi ja uusi teenuseid?

Kui meil ei ole vaja uut tarkvara, siis mida meil siiski vaja on? Eelkõige soovime lahendusi tüütutele ja keerulistele probleemidele, soovime vältida vigu, mis tulenevad sellest, et meil ei ole asjad hästi organiseeritud, puudub ülevaade, eksime sisestamisel, unustame jne.

Hea tarkvara aitab lahendada probleeme ja kes seda ei tahaks? Hea tarkvara justkui peidab probleemid ja keerukuse meie eest ja näitab meile midagi lihtsat, ilusat ja mugavat.

Seega selle asemel, et öelda "meil on vaja rohkem tarkvara" võiks öelda "meil on vaja head lahendust".

Azure docker ja eestikeelne kõnetuvastus

· 4 min lugemine
Infokiir OÜ

Eesti keele kõnetuvastus on üsna keeruline tarkvara. Isegi selle installeerimine enda arvutisse võib olla väljakutse. Mis siis rääkida veel selle kirjutamisest programmeerijana.

Veebibrauseris vastav tööriist on internetis saadaval siin: http://bark.phon.ioc.ee/webtrans/

Kui siiski soovime seda tarkvara ise jooksutada, siis üks lihtne võimalus on kasutada valmis docker konteinerit.

Juhendi leiame siit:

https://github.com/alumae/kaldi-offline-transcriber/tree/master/misc/docker

Kui teha selle juhendi järgi, siis suure tõenäosusega saame selle ka kohe tööle. Eelnevalt tuleb jälgida, et docker konteineri käsutuses oleks vähemalt 6GB RAM. Mul ebaõnnestus 4GB RAM-ga, kuid 6GB oli piisav, et üks näide tööle saada.

Kui me ei sooviks seda tarkvara hoida enda arvutis vaid hoopis Azure pilves, kuidas see siis tööle saada? Järgnevalt on dokumenteeritud väike juhend, kuidas mul see õnnestus kasutades PowerShell käsurida.

Kõigepealt tee resource group:

az group create --name tuvastusResourceGroup --location uksouth

vastus:

{
"id": "/subscriptions/55622624-1ccb-4e6c-97dc-51d463935a2e/resourceGroups/tuvastusResourceGroup",
"location": "uksouth",
"managedBy": null,
"name": "tuvastusResourceGroup",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}

Seejärel tee Container Registry:

az acr create --resource-group tuvastusResourceGroup --name tuvastusContainerRegistry --sku Basic

vastus:

{
"adminUserEnabled": false,
"creationDate": "2019-11-01T08:36:50.213637+00:00",
"id": "/subscriptions/55622624-1ccb-4e6c-97dc-51d463935a2e/resourceGroups/tuvastusResourceGroup/providers/Microsoft.ContainerRegistry/registries/tuvastusContainerRegistry",
"location": "uksouth",
"loginServer": "tuvastuscontainerregistry.azurecr.io",
"name": "tuvastusContainerRegistry",
"networkRuleSet": null,
"policies": {
"quarantinePolicy": {
"status": "disabled"
},
"retentionPolicy": {
"days": 7,
"lastUpdatedTime": "2019-11-01T08:36:52.156079+00:00",
"status": "disabled"
},
"trustPolicy": {
"status": "disabled",
"type": "Notary"
}
},
"provisioningState": "Succeeded",
"resourceGroup": "tuvastusResourceGroup",
"sku": {
"name": "Basic",
"tier": "Basic"
},
"status": null,
"storageAccount": null,
"tags": {},
"type": "Microsoft.ContainerRegistry/registries"
}

Logi sisse:

az acr login --name tuvastusContainerRegistry

Vastus:

Login Succeeded

Lubame admin kasutaja:

az acr update -n tuvastusContainerRegistry --admin-enabled true

vastus:

{
"adminUserEnabled": true,
"creationDate": "2019-11-01T08:36:50.213637+00:00",
"id": "/subscriptions/55622624-1ccb-4e6c-97dc-51d463935a2e/resourceGroups/tuvastusResourceGroup/providers/Microsoft.ContainerRegistry/registries/tuvastusContainerRegistry",
"location": "uksouth",
"loginServer": "tuvastuscontainerregistry.azurecr.io",
"name": "tuvastusContainerRegistry",
"networkRuleSet": null,
"policies": {
"quarantinePolicy": {
"status": "disabled"
},
"retentionPolicy": {
"days": 7,
"lastUpdatedTime": "2019-11-01T08:36:52.156079+00:00",
"status": "disabled"
},
"trustPolicy": {
"status": "disabled",
"type": "Notary"
}
},
"provisioningState": "Succeeded",
"resourceGroup": "tuvastusResourceGroup",
"sku": {
"name": "Basic",
"tier": "Basic"
},
"status": null,
"storageAccount": null,
"tags": {},
"type": "Microsoft.ContainerRegistry/registries"
}

Tekitatud kasutajanime ja parooli saab vaadata nii:

az acr credential show --name tuvastusContainerRegistry

Vastus:

{
"passwords": [
{
"name": "password",
"value": "********************************"
},
{
"name": "password2",
"value": "********************************"
}
],
"username": "tuvastusContainerRegistry"
}

Veendu, et käsurida lokaalses dockeris töötab. Näiteks:

docker exec 79bafd51385a1933d7ea584a07870a0bc8ab9c791ab24a938e17e3313ce750cb bash -c 'mkdir -p /opt/speechfiles/ ; cd /opt/speechfiles/ ; wget https://www.infokiir.ee/mp3test/proov.mp3 ; /opt/kaldi-offline-transcriber/speech2text.sh --trs /opt/speechfiles/proov.trs /opt/speechfiles/proov.mp3 ; cat /opt/speechfiles/proov.trs'

tag käsklusega märgistame konteineri:

docker tag alumae/kaldi-offline-transcriber-et tuvastuscontainerregistry.azurecr.io/kaldi-offline-transcriber-et:v1

Saadame selle azure pilve (see võtab üsnagi aega, sõltuvalt interneti kiirusest):

docker push tuvastuscontainerregistry.azurecr.io/kaldi-offline-transcriber-et:v1

Nüüd teen docker image vastava käsureaga:

az container create --restart-policy Never --registry-username tuvastusContainerRegistry --registry-password ******************************** --cpu 2 --memory 6 --resource-group tuvastusResourceGroup --name tuvastus6m --image tuvastuscontainerregistry.azurecr.io/kaldi-offline-transcriber-et:v1 --command-line "bash -c 'mkdir -p /opt/speechfiles/ ; cd /opt/speechfiles/ ; wget https://www.infokiir.ee/mp3test/proov.mp3 ; /opt/kaldi-offline-transcriber/speech2text.sh --trs /opt/speechfiles/proov.trs /opt/speechfiles/proov.mp3 ; cat /opt/speechfiles/proov.trs'"

Muide alla 6GB mälu ei tasu panna. Proovisin 4GB ja sellest jäi väheks.

Tulemust vaatan käsklusega:

az container logs --resource-group tuvastusResourceGroup --name tuvastus6m

See näeb välja umbes selline:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Trans SYSTEM "trans-14.dtd">
<Trans scribe="est-speech2txt" audio_filename="proov" version="1" version_date="191101">
<Speakers>
<Speaker id="spk1" name="K01" check="no" dialect="native" accent="" scope="local"/>
</Speakers>
<Episode>
<Section type="report" startTime="0.000" endTime="9.330">
<Turn speaker="spk1" startTime="0.690" endTime="9.150">
<Sync time="0.690"/>
Ma teen siis ise kõigepealt ühe väikse proovi. Vaatame, kas ta oskab helifaili teha tekstiks.
</Turn>
</Section>
<Section type="filler" startTime="9.330" endTime="10.320">
</Section>
</Episode>
</Trans>

Kui soovin uuesti käivitada kestuse mõõtmisega, siis kasutan käsklust:

Measure-Command { az container start --resource-group tuvastusResourceGroup --name tuvastus6m }

Tulemus:

Days : 0
Hours : 0
Minutes : 8
Seconds : 43
Milliseconds : 367
Ticks : 5233673801
TotalDays : 0,00605749282523148
TotalHours : 0,145379827805556
TotalMinutes : 8,72278966833333
TotalSeconds : 523,3673801
TotalMilliseconds : 523367,3801

See tarkvara jookseb üllatavalt kaua, samas tuvastuse kvaliteet on üllatavalt hea.

Nädalapäev E, T, K, N, R, L, P Excelisse

· Ühe min lugemine
Infokiir OÜ

Exceliga tööd tehes on mõnikord vaja kuupäeva puhul teada nädalapäeva. Tore oleks, kui selleks oleks valmis funktsioon. Tegelikult selline funktsioon ongi olemas. Esimese hooga ehk selle peale lihtsalt ei tule. Tavaliselt aitab interneti otsingumootor, kui teada sobivaid märksõnu.

Funktsioon ise on selline:

=TEXT(WEEKDAY("2019-03-15");"ddd")

Muidugi saaks sarnase funktsiooni ka ise programmeerida, kuid sellisel juhul peaks olema failis makrod lubatud. Ülaltoodud funktsioon töötab ka LibreOffice-ga.

excel-nadalapaev