Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  8 2766
Jeg prøver å lære mer om Python og hvordan det fungerer. Sitter akkurat nå og lager meg en "config-generator".
Jeg har ingenting imot å få tips eller gode råd til hvordan dette kan gjøres bedre Bare fint å lære.

Koden:

Kode

import json
def opentemplate():
 templatefile = open('empty-configfile.txt', "r")
 templatelines = templatefile.read().splitlines()
 templatefile.close()
 return(templatelines)

def getdefaultvalue():
  file="defaultvalues.txt"
 with open(file) as f:
  arr = json.loads(f.read())
 return arr

def configure():
 lin=[]
 for lines in opentemplate():
  if lines:
   try:
     lin.append(lines % getdefaultvalue())
   except KeyError as e:
     keyerr=e.args[0]
     lin.append(lines % {keyerr:"not-set-because-not-found"})
  final_string = '\n'.join(lin)
 return(final_string)
Så skal jeg vise dere hva som er i empty-configfile.txt:

Kode

servername=%(cfg_servername)s
ipaddress=%(cfg_ipaddress)s
documentroot=%(cfg_docroot)s
foobar=%(foobar)s
Og så, defaultvalues.txt:

Kode

{
"cfg_servername":"foobar.com",
"cfg_ipaddress":"*",
"cfg_docroot":"/var/www/%(cfg_servername)s"
}
Jeg gjør oppmerksom på at dette ikke er fullstendig eller 100% korrekt bortsett fra python-koden som brukes. For eksempel er ikke empty-configfile.txt den samme som jeg bruker, det som er lagt ut her er for illustrasjon.

Som dere skjønner, så skal dette skriptet åpne "empty-configfile.txt" og erstatte det som står i f.eks. %(cfg_ipaddress)s med * som er satt i defaultvalues.txt.

Jeg har en tanke om at denne defaultvalues.txt-filen kun skal benyttes dersom brukeren ikke har lagt alle variablene i input. Jeg har ikke tatt med delen hvor jeg henter frem input fra brukeren i koden over, da det ikke egentlig er relevant.

Poenget er at hvis brukeren kun har lagt inn cfg_servername, men unnlater å legge inn cfg_ipaddress, så skal den settes til å være *. Det samme gjelder hvis ikke cfg_docroot er satt, da skal den settes til default /var/www/%(cfg_servername)s.

Med andre ord, brukeren kan valgfritt legge inn domenenavnet + variablene, eller kun domenenavnet og ingen av variablene (eller bare et par av dem) uten problemer.

Og hvis dere har gjettet at dette er en webserver-config, så har dere rett, det er det jeg leker med

Koden gjør nå dette:
1: Henter frem output fra opentemplate(), som altså er empty-configfile.txt

2: Leser hver linje av denne.

3: Legger inn hver linje i lista lin[] og erstatter samtidig verdien av %(cfg_variabel) med {cfg_variabel} som enten kommer fra brukerinput eller defaultvalues.txt. Til slutt legges lin[] inn i final_string sammen med et linjeskift per linje.

4: Dersom en nøkkel i empty-configfile.txt ikke finnes i defaultvalues.txt (eller input fra bruker), for eksempel nøkkelen foobar, så skjer det en KeyError. Da legges nøkkelen inn uansett, med verdi "not-set-because-not-found". (Eksperimentelt)

Jeg lager denne tråden fordi jeg ønsker å lære hvordan punkt nr. 4 kan gjøres omvendt. Altså, hvis nøkkelen finnes i defaultvalues.txt, men ikke brukes av empty-config.txt, så vil jeg vite om det. Utfordringen er at jeg ikke helt vet hvordan jeg kan hente frem hvilke nøkler som ligger inne i empty-config.txt. Det kunne jeg ha sammenlignet med defaultvalues.txt isåfall.

En annen ting jeg fremdeles tygger på, er at når den henter frem docroot=/var/www/%(cfg_domain)s, så vet jeg ikke helt om jeg skal kjøre enda en loop for å sette cfg_domain inne i docroot, eller om dere kanskje har andre forslag som er bedre.

På forhånd tusen takk for alle bidrag
Når du leser inn "empty-configfile.txt" bør du kanskje parse den til et array likt det du får fra "defaultvalues.txt".

Da kan logikken din være noe sånt:
  1. Lag en liste med unike keys fra begge filer
  2. Loop gjennom denne listen
  3. Om en key finnes i i begge filer tar du verdi fra "empty-configfile", om ikke tar du verdi fra default
  4. Bygg opp et nytt array
  5. Skriv til fil i ønsket format
Sitat av Yochi Vis innlegg
Når du leser inn "empty-configfile.txt" bør du kanskje parse den til et array likt det du får fra "defaultvalues.txt".

Da kan logikken din være noe sånt:
  1. Lag en liste med unike keys fra begge filer
  2. Loop gjennom denne listen
  3. Om en key finnes i i begge filer tar du verdi fra "empty-configfile", om ikke tar du verdi fra default
  4. Bygg opp et nytt array
  5. Skriv til fil i ønsket format
Vis hele sitatet...
Tusen takk. Dessverre er det ikke så lett å gjøre punkt 1. Jeg burde ha lagt ved den virkelige konfigurasjonsfilen til webserveren, og ikke det eksempelet jeg la ved. Legger derfor ved den nå:

Kode

server {
server_name %(cfg_domain)s;
listen %(cfg_ipv4)s:%(cfg_port4)s
listen [%(cfg_ipv6)s]:%(cfg_port6)s
root %(cfg_root)s
index index.php index.htm index.html;
access_log %(cfg_accesslog)s
error_log %(cfg_errorlog)s
fastcgi_param HTTPS $https;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_read_timeout 60;
location ~ \.php(/|$) {
try_files $uri $fastcgi_script_name =404;
fastcgi_pass %(cfg_fcgitype)s:%(cfg_fcgisocket)s
}
location / {
try_files $uri $uri/ /index.php?$args;
}
}
Så, det å hente ut keys fra denne configfilen er problemet mitt. Jeg er nødt til å hente ut hvilke %(key)s som ligger her. Det ville ha vært rett fram om configfilen faktisk så ut som jeg la ved i førstepost:

Kode

servername=%(cfg_servername)s
ipaddress=%(cfg_ipaddress)s
documentroot=%(cfg_docroot)s
foobar=%(foobar)s
Derfor trenger jeg å forstå hvordan jeg kan få hentet ut en liste over alle %(key)s som ligger i den configfilen...
Sist endret av FailedTech; 23. april 2022 kl. 17:14.
Sitat av FailedTech Vis innlegg
Derfor trenger jeg å forstå hvordan jeg kan få hentet ut en liste over alle %(key)s som ligger i den configfilen...
Vis hele sitatet...
Regex?

Kode

%\(.*?\)
Evt, hvis du kun vil ha innsiden av parantesene:

Kode

(?<=%\().*?(?=\))
Sist endret av Realist1; 23. april 2022 kl. 21:20. Grunn: Automatisk sammenslåing med etterfølgende innlegg.
Ser ut til å være nginx. Anbefaler at du begynner å google problemstillingen før du kaster deg over tastaturet for å løse det selv, som oftest har noen møtt på samme problem før.

Jeg søkte etter "nginx config parser" og fikk opp denne https://github.com/nginxinc/crossplane
Sist endret av Patrick; 24. april 2022 kl. 11:51.
I stedet for å finne opp ditt eget template-system, vurder å bruke et eksisterende? Jinja2 f.eks.
Ikke bare kan det lønne seg å bruke et etablert templating-system, men det kan også være lurt å sette seg inn i hvordan Nginx funker med inheritance. Du burde heller ikke finne opp config management på nytt. Dette er et løst problem, og du slipper mange gotchas hvis du bare bruker noe etablert, som Ansible eller Chef.

Du kan også forenkle alt det du prøver å oppnå ved å bare bruke variabler i konfigurasjonen din. Så hvis du f.eks. bruker regex til å normalisere server_name-direktivet (f.eks. strippe vekk www) og sette det til en ny variabel, så kan du bruke dette igjen som f.eks. root, og da lage dynamisk mapping basert på server_name og en mappestruktur.

Kode

server {
    server_name ~^(www\.)?(?<domain>.+)$;

    location / {
        root /sites/$domain;
    }
}
Anbefaler deg sterkt å ta deg tiden til å lese hva de forskjellige direktivene gjør, og hvilke variabler du har tilgjengelig. Hvis du leser dokumentasjonen så ser du også hvor verdier kan settes, i hvilken rekkefølge de evalueres og hva som allerede er standardverdiene.
Ventnålitt Dette er ikke noe som skal i produksjon. Jeg vil lære Python, ikke noe mer