Révision de la formation tronc commun 2
This commit is contained in:
parent
13a1493753
commit
4bba6387ca
40
content/modules_eole_envole/exemple.xml
Normal file
40
content/modules_eole_envole/exemple.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<creole>
|
||||
<files>
|
||||
<file filelist='vnstat' name='etc/vnstat.conf'/>
|
||||
<service servicelist='vnstat'>vnstat</service>
|
||||
<service_access service='vnstat'>
|
||||
<port>8888</port>
|
||||
<tcpwrapper>vnstat</tcpwrapper>
|
||||
</service_access>
|
||||
<service_restriction service='vnstat'>
|
||||
<ip interface='auto' netmask='255.255.255.0'>192.168.56.101</ip>
|
||||
</service_restriction>
|
||||
</files>
|
||||
<variables>
|
||||
<family name='services'>
|
||||
<variable name='activer_vnstat' type='oui/non' description='Activer le service vnStat'>
|
||||
<value>oui</value>
|
||||
</variable>
|
||||
</family>
|
||||
<family name='vnstat'>
|
||||
<variable name='vnstat_interface' type='string' description='Numéro de l’interface par défaut de vnStat' mandatory='True' multi='True'/>
|
||||
<variable name='vnstat_user' type='unix_user' description='Nom d’utilisateur' mode='expert'/>
|
||||
<variable name='vnstat_group' type='unix_user' description='Nom du groupe' mode='expert'/>
|
||||
</family>
|
||||
</variables>
|
||||
<constraints>
|
||||
<check name='valid_enum' target='vnstat_interface'>
|
||||
<param>['0', '1', '2', '3', '4']</param>
|
||||
</check>
|
||||
<fill name='calc_val' target='vnstat_group'>
|
||||
<param type='eole' name='valeur'>vnstat_user</param>
|
||||
</fill>
|
||||
<condition name='disabled_if_in' source='activer_vnstat'>
|
||||
<param>non</param>
|
||||
<target type='family'>vnstat</target>
|
||||
<target type='filelist'>vnstat</target>
|
||||
<target type='servicelist'>vnstat</target>
|
||||
</condition>
|
||||
</constraints>
|
||||
</creole>
|
170
content/modules_eole_envole/vnstat.conf
Normal file
170
content/modules_eole_envole/vnstat.conf
Normal file
@ -0,0 +1,170 @@
|
||||
# vnStat 1.18 config file
|
||||
##
|
||||
|
||||
# default interface
|
||||
%set %%interfaces = []
|
||||
%for interface in %%vnstat_interface
|
||||
%set %%zone = 'nom_zone_eth' + interface
|
||||
%silent %%interfaces.append(%%getVar(%%zone))
|
||||
%end for
|
||||
Interface "%%custom_join(%%interfaces,'+']"
|
||||
|
||||
# location of the database directory
|
||||
DatabaseDir "/var/lib/vnstat"
|
||||
|
||||
# locale (LC_ALL) ("-" = use system locale)
|
||||
Locale "-"
|
||||
|
||||
# on which day should months change
|
||||
MonthRotate 1
|
||||
|
||||
# date output formats for -d, -m, -t and -w
|
||||
# see 'man date' for control codes
|
||||
DayFormat "%x"
|
||||
MonthFormat "%b '%y"
|
||||
TopFormat "%x"
|
||||
|
||||
# characters used for visuals
|
||||
RXCharacter "%"
|
||||
TXCharacter ":"
|
||||
RXHourCharacter "r"
|
||||
TXHourCharacter "t"
|
||||
|
||||
# how units are prefixed when traffic is shown
|
||||
# 0 = IEC standard prefixes (KiB/MiB/GiB/TiB)
|
||||
# 1 = old style binary prefixes (KB/MB/GB/TB)
|
||||
UnitMode 0
|
||||
|
||||
# how units are prefixed when traffic rate is shown
|
||||
# 0 = IEC binary prefixes (Kibit/s...)
|
||||
# 1 = SI decimal prefixes (kbit/s...)
|
||||
RateUnitMode 1
|
||||
|
||||
# output style
|
||||
# 0 = minimal & narrow, 1 = bar column visible
|
||||
# 2 = same as 1 except rate in summary and weekly
|
||||
# 3 = rate column visible
|
||||
OutputStyle 3
|
||||
|
||||
# used rate unit (0 = bytes, 1 = bits)
|
||||
RateUnit 1
|
||||
|
||||
# number of decimals to use in outputs
|
||||
DefaultDecimals 2
|
||||
HourlyDecimals 1
|
||||
|
||||
# spacer for separating hourly sections (0 = none, 1 = '|', 2 = '][', 3 = '[ ]')
|
||||
HourlySectionStyle 2
|
||||
|
||||
# try to detect interface maximum bandwidth, 0 = disable feature
|
||||
# MaxBandwidth will be used as fallback value when enabled
|
||||
BandwidthDetection 1
|
||||
|
||||
# maximum bandwidth (Mbit) for all interfaces, 0 = disable feature
|
||||
# (unless interface specific limit is given)
|
||||
MaxBandwidth 1000
|
||||
|
||||
# interface specific limits
|
||||
# example 8Mbit limit for eth0 (remove # to activate):
|
||||
#MaxBWeth0 8
|
||||
|
||||
# how many seconds should sampling for -tr take by default
|
||||
Sampletime 5
|
||||
|
||||
# default query mode
|
||||
# 0 = normal, 1 = days, 2 = months, 3 = top10
|
||||
# 4 = exportdb, 5 = short, 6 = weeks, 7 = hours
|
||||
QueryMode 0
|
||||
|
||||
# filesystem disk space check (1 = enabled, 0 = disabled)
|
||||
CheckDiskSpace 1
|
||||
|
||||
# database file locking (1 = enabled, 0 = disabled)
|
||||
UseFileLocking 1
|
||||
|
||||
# how much the boot time can variate between updates (seconds)
|
||||
BootVariation 15
|
||||
|
||||
# log days without traffic to daily list (1 = enabled, 0 = disabled)
|
||||
TrafficlessDays 1
|
||||
|
||||
|
||||
# vnstatd
|
||||
##
|
||||
|
||||
# switch to given user when started as root (leave empty to disable)
|
||||
DaemonUser "%%vnstat_user"
|
||||
|
||||
# switch to given user when started as root (leave empty to disable)
|
||||
DaemonGroup "%%vnstat_group"
|
||||
|
||||
# how many minutes to wait during daemon startup for system clock to
|
||||
# sync time if most recent database update appears to be in the future
|
||||
TimeSyncWait 5
|
||||
|
||||
# how often (in seconds) interface data is updated
|
||||
UpdateInterval 30
|
||||
|
||||
# how often (in seconds) interface status changes are checked
|
||||
PollInterval 5
|
||||
|
||||
# how often (in minutes) data is saved to file
|
||||
SaveInterval 5
|
||||
|
||||
# how often (in minutes) data is saved when all interface are offline
|
||||
OfflineSaveInterval 30
|
||||
|
||||
# how often (in minutes) bandwidth detection is redone when
|
||||
# BandwidthDetection is enabled (0 = disabled)
|
||||
BandwidthDetectionInterval 5
|
||||
|
||||
# force data save when interface status changes (1 = enabled, 0 = disabled)
|
||||
SaveOnStatusChange 1
|
||||
|
||||
# enable / disable logging (0 = disabled, 1 = logfile, 2 = syslog)
|
||||
UseLogging 2
|
||||
|
||||
# create dirs if needed (1 = enabled, 0 = disabled)
|
||||
CreateDirs 1
|
||||
|
||||
# update ownership of files if needed (1 = enabled, 0 = disabled)
|
||||
UpdateFileOwner 1
|
||||
|
||||
# file used for logging if UseLogging is set to 1
|
||||
LogFile "/var/log/vnstat/vnstat.log"
|
||||
|
||||
# file used as daemon pid / lock file
|
||||
PidFile "/var/run/vnstat/vnstat.pid"
|
||||
|
||||
|
||||
# vnstati
|
||||
##
|
||||
|
||||
# title timestamp format
|
||||
HeaderFormat "%x %H:%M"
|
||||
|
||||
# show hours with rate (1 = enabled, 0 = disabled)
|
||||
HourlyRate 1
|
||||
|
||||
# show rate in summary (1 = enabled, 0 = disabled)
|
||||
SummaryRate 1
|
||||
|
||||
# layout of summary (1 = with monthly, 0 = without monthly)
|
||||
SummaryLayout 1
|
||||
|
||||
# transparent background (1 = enabled, 0 = disabled)
|
||||
TransparentBg 0
|
||||
|
||||
# image colors
|
||||
CBackground "FFFFFF"
|
||||
CEdge "AEAEAE"
|
||||
CHeader "606060"
|
||||
CHeaderTitle "FFFFFF"
|
||||
CHeaderDate "FFFFFF"
|
||||
CText "000000"
|
||||
CLine "B0B0B0"
|
||||
CLineL "-"
|
||||
CRx "92CF00"
|
||||
CTx "606060"
|
||||
CRxD "-"
|
||||
CTxD "-"
|
@ -13,7 +13,7 @@
|
||||
]{skblocal.tex}
|
||||
|
||||
\newcommand{\pdfauthor}{Cadoles}
|
||||
\newcommand{\pdftitle}{Formation tronc commun niveau 1}
|
||||
\newcommand{\pdftitle}{Formation tronc commun niveau 2}
|
||||
\newcommand{\pdfkeywords}{EOLE}
|
||||
|
||||
\skbinput[from=sli]{style/preambule}
|
||||
@ -29,20 +29,16 @@
|
||||
|
||||
\subject{Talks}
|
||||
|
||||
\logo{
|
||||
\hspace{120pt}
|
||||
\skbfigure[width=2cm]{cadoles/logo_01.png}
|
||||
\hspace{113pt}
|
||||
\skbfigure[width=1cm]{en/logo.png}
|
||||
}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\skbinput[from=sli]{style/title}
|
||||
|
||||
% Corps de la formation
|
||||
|
||||
\skbinput[from=sli]{modules_EOLE_envole/tronc-commun-2/personnalisation-creole}
|
||||
\skbinput[from=sli]{modules_EOLE_envole/tronc-commun-2/personnalisation-creole-patchs}
|
||||
\skbinput[from=sli]{modules_EOLE_envole/tronc-commun-2/personnalisation-creole-patchs-pratique}
|
||||
\skbinput[from=sli]{modules_EOLE_envole/tronc-commun-2/personnalisation-creole-templates}
|
||||
\skbinput[from=sli]{modules_EOLE_envole/tronc-commun-2/personnalisation-creole-templates-pratique}
|
||||
\skbinput[from=sli]{modules_EOLE_envole/tronc-commun-2/zephir}
|
||||
\skbinput[from=sli]{modules_EOLE_envole/tronc-commun-2/zephir_script}
|
||||
\skbinput[from=sli]{modules_EOLE_envole/tronc-commun-2/api}
|
||||
|
@ -3,6 +3,7 @@
|
||||
\begin{itemize}
|
||||
\item Les journaux sont remontés sur le maître en mode conteneur ;
|
||||
\item les journaux locaux sont maintenant dans /var/log/rsyslog/local/ ;
|
||||
\item possibilité d’agréger des logs de serveurs distants dans /var/log/rsyslog/remote/ ;
|
||||
\item principaux journaux :
|
||||
\begin{itemize}
|
||||
\item kernel/ : tous les messages du noyau ;
|
||||
|
@ -0,0 +1,9 @@
|
||||
{\setbeamercolor{background canvas}{bg=TravauxPratiques}
|
||||
\begin{frame}
|
||||
\frametitle{Pratique}
|
||||
\begin{itemize}
|
||||
\item Modifié dans le template de configure sshd\_config : "LoginGraceTime" de "30" à "60"
|
||||
\item créé le patch.
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
\begin{frame}
|
||||
\frametitle{Création de patch}
|
||||
\begin{itemize}
|
||||
\item Génération normal : /usr/share/eole/creole/distrib => /etc
|
||||
\item Génération avec patch : /usr/share/eole/creole/distrib + /usr/share/eole/creole/patch => /var/lib/creole => /etc
|
||||
\item Créer un patch :
|
||||
\begin{itemize}
|
||||
\item copie du fichier original /usr/share/eole/creole/distrib => /usr/share/eole/creole/modif ;
|
||||
\item modification du fichier dans /usr/share/eole/creole/modif ;
|
||||
\item exécution \commande{gen\_patch} ;
|
||||
\item reconfiguration.
|
||||
\end{itemize}
|
||||
\item Désactiver un patch : supprimer le fichier dans /usr/share/eole/creole/patch.
|
||||
\end{itemize}
|
||||
\end{frame}
|
@ -0,0 +1,97 @@
|
||||
{\setbeamercolor{background canvas}{bg=TravauxPratiques}
|
||||
\begin{frame}
|
||||
\frametitle{Pratique}
|
||||
\framesubtitle{Gérer le service vnstat}
|
||||
\begin{enumerate}
|
||||
\item Créer un dictionnaire dans le répertoire /usr/share/eole/creole/dicos/local,
|
||||
\item ajouter l’entête \emph{<?xml version="1.0" encoding="utf-8"?>},
|
||||
\item ajouter une balise \emph{creole},
|
||||
\item ajouter une balise \emph{files} dans la balise \emph{creole},
|
||||
\item ajouter une balise \emph{service} dans la balise \emph{files},
|
||||
\item valider avec \commande{CreoleLint},
|
||||
\item tester le comportement au \commande{reconfigure}.
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Pratique}
|
||||
\framesubtitle{Gérer les accès réseau du service vnstat}
|
||||
\begin{enumerate}
|
||||
\item Ajouter au dictionnaire une balise \emph{service\_access} dans la balise \emph{files},
|
||||
\item appliquer la modification avec \commande{reconfigure},
|
||||
\item tester la gestion du port avec \commande{iptables-save}.
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Pratique}
|
||||
\framesubtitle{Gérer les accès réseau du service vnstat}
|
||||
\begin{enumerate}
|
||||
\item Ajouter au dictionnaire une balise \emph{service\_restriction} dans la balise \emph{files},
|
||||
\item appliquer la modification avec \commande{reconfigure},
|
||||
\item tester la gestion du port avec \commande{iptables-save}.
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Pratique}
|
||||
\framesubtitle{Ajouter une variable pour activer vnstat}
|
||||
\begin{enumerate}
|
||||
\item Ajouter une balise \emph{variables} dans la balise \emph{creole},
|
||||
\item ajouter une balise \emph{family} dans la balise \emph{variables},
|
||||
\item ajouter une balise \emph{variable} dans la balise \emph{family},
|
||||
\item valider avec \commande{CreoleLint},
|
||||
\item constater les changements dans \commande{gen\_config}.
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Pratique}
|
||||
\framesubtitle{Rendre variable un paramètre de configuration}
|
||||
\begin{enumerate}
|
||||
\item Ajouter une balise \emph{file} dans la balise \emph{files},
|
||||
\item copier le fichier /etc/vnstat.conf dans /usr/share/eole/creole/distrib,
|
||||
\item utiliser la variable dans le template /usr/share/eole/creole/distrib/vnstat.conf,
|
||||
\item générer le fichier avec \commande{CreoleCat -dt vnstat.conf}.
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Pratique}
|
||||
\framesubtitle{Contraindre la valeur d’une variable}
|
||||
\begin{enumerate}
|
||||
\item Ajouter une balise \emph{constraints} dans la balise \emph{creole},
|
||||
\item ajouter une balise \emph{check} dans la balise \emph{constraints},
|
||||
\item modifier le template pour construire une valeur à partir de la variable,
|
||||
\item générer le fichier avec \commande{CreoleCat -dt vnstat.conf}.
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Pratique}
|
||||
\framesubtitle{Calculer la valeur d’une variable}
|
||||
\begin{enumerate}
|
||||
\item Ajouter deux balises \emph{variable} dans la balise \emph{family vnstat},
|
||||
\item ajouter une balise \emph{fill} dans la balise \emph{constraints}.
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Pratique}
|
||||
\framesubtitle{Conditionner l’accès aux variables}
|
||||
\begin{enumerate}
|
||||
\item Ajouter une balise \emph{condition} dans la balise \emph{constraints},
|
||||
\item ajouter les balises \emph{target} pour la famille, le fichier et le service,
|
||||
\item passer la variable \emph{activer\_vnstat} à \emph{non} et valider les désactivations avec \commande{reconfigure}.
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Pratique}
|
||||
\framesubtitle{Documenter les variables et familles}
|
||||
\begin{itemize}
|
||||
\item Ajouter une balise \emph{help} dans la balise {creole},
|
||||
\item ajouter les balises \emph{variable} dans la balise \emph{help}.
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
\begin{frame}
|
||||
\frametitle{Dictionnaire Creole}
|
||||
\begin{itemize}
|
||||
\item Un dictionnaire est un fichier XML Creole ;
|
||||
\item décrit les variables présente dans l'interface de configuration ;
|
||||
\item informations utiles pour les services ;
|
||||
\item les dictionnaires locaux sont dans /usr/share/eole/creole/dicos/local/.
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{CreoleLint}
|
||||
\begin{itemize}
|
||||
\item Vérifie la syntaxe du dictionnaire : \commande{CreoleLint -d} ;
|
||||
\item test la génération d'un template suivant contrainte : \commande{CreoleLint -t nom\_du\_template}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{CreoleCat}
|
||||
\begin{itemize}
|
||||
\item Templatise un fichier sans faire de reconfigure (objectif de test) ;
|
||||
\item \commande{CreoleCat -t nom\_du\_template}
|
||||
\item \commande{CreoleCat -t nom\_du\_template -o /tmp/template.tmpl}
|
||||
\item \commande{CreoleCat -s /tmp/nom\_du\_template -o /tmp/template.tmpl}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Dictionnaires Creole}
|
||||
\frametitle{Les paquets}
|
||||
\begin{itemize}
|
||||
\item Les paquets fonctionnent sur le maitre ou dans un conteneur ;
|
||||
\item permet d'installer les paquets sans passer par les dépendances de paquet.
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Dictionnaires Creole}
|
||||
\frametitle{Les services}
|
||||
\begin{itemize}
|
||||
\item Services fonctionnent sur le maitre ou dans un conteneur ;
|
||||
\item différentes méthodes : service, upstart (version EOLE inférieur à 2.6) ou apache.
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Dictionnaires Creole}
|
||||
\frametitle{Le firewall}
|
||||
\begin{itemize}
|
||||
\item On commence par ouvrir les accès (service\_access) ;
|
||||
\item on ajoute ensuite les restrictions (service\_restiction).
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Dictionnaires Creole}
|
||||
\frametitle{Les familles}
|
||||
\begin{itemize}
|
||||
\item Les variables sont classés dans des familles.
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Dictionnaires Creole}
|
||||
\frametitle{Les variables}
|
||||
\begin{itemize}
|
||||
\item Les variables sont typées :
|
||||
\begin{itemize}
|
||||
\item number, port,
|
||||
\item string, mail, filename, unix\_user, web\_address,
|
||||
\item ip, local\_ip, netmask, network, broadcast,
|
||||
\item netbios, domain, domain\_strict, hostname, hostname\_strict,
|
||||
\item oui/non, on/off, yes/no.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Dictionnaires Creole}
|
||||
\frametitle{Les fichiers templates}
|
||||
\begin{itemize}
|
||||
\item Le nom des fichiers templates sont dans les dictionnaires (file) ;
|
||||
\item le répertoire de destination doit existé par défaut ;
|
||||
\item possibilité de définir les droits sur le fichier ;
|
||||
\item nom de la source peut être différents de la destination.
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Dictionnaires Creole}
|
||||
\frametitle{Les contraintes}
|
||||
\begin{itemize}
|
||||
\item pour tester/remplir/grouper/conditionner des variables ;
|
||||
\begin{itemize}
|
||||
\item calcul automatique (fill),
|
||||
\item calcul automatique non modifiable (auto),
|
||||
\item choix de réponse (valid\_enum),
|
||||
\item cacher des variables suivant des contraintes (condition),
|
||||
\item groupe de variables (group) :
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Dictionnaires Creole}
|
||||
\framesubtitle{Redéfinition de variables}
|
||||
\begin{itemize}
|
||||
\item Permet de redéfinir des attributs et caractéristiques :
|
||||
\begin{itemize}
|
||||
\item service
|
||||
\item variable
|
||||
\end{itemize}
|
||||
\item remove\_check : supprimer les "check" déjà définit de la variable.
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Langague de template Creole}
|
||||
\begin{itemize}
|
||||
\item Un template utilise le langage de template Creole.
|
||||
\item variable Creole préfixé par \begin{semiverbatim}\%\%\end{semiverbatim}
|
||||
\item Test : \begin{semiverbatim}\%if EXPRESSION code if \%else code else \%end if\end{semiverbatim}
|
||||
\item Boucle : \begin{semiverbatim}\%for \%\%i in EXPRESSION hello \%\%i \%end for\end{semiverbatim}
|
||||
\item Boucle pour variable multi évolué avec esclave : \begin{semiverbatim}\%for \%\%var in \%\%variablemaitre\end{semiverbatim}\begin{semiverbatim}\%\%var, \%\%var.esclave1, \%\%var.esclave2\end{semiverbatim}\begin{semiverbatim}\%end for\end{semiverbatim}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Langague de template Creole}
|
||||
\begin{itemize}
|
||||
\item Test existence : \begin{semiverbatim}\%if \%\%is\_defined('variable') code if \%end if\end{semiverbatim}
|
||||
\item valeur vide : \begin{semiverbatim}\%if \%\%is\_empty(\%\%variable) code if \%end if\end{semiverbatim}
|
||||
\item nom de variable dans une variable : \begin{semiverbatim}\%set \%\%var='adresse\_ip\_eth0' \%\%getVar(\%\%var)\end{semiverbatim}
|
||||
\end{itemize}
|
||||
\end{frame}
|
Loading…
Reference in New Issue
Block a user