aboutsummaryrefslogtreecommitdiffstats
path: root/roles/solr
diff options
context:
space:
mode:
authorStonewall Jackson <stonewall@sacredheartsc.com>2023-02-04 01:23:43 -0500
committerStonewall Jackson <stonewall@sacredheartsc.com>2023-02-04 01:52:13 -0500
commit0261e875679f1bf63c8d689da7fc7e014597885d (patch)
tree3f19cd74a0c1070944f75437f30b098d6ef2ffcb /roles/solr
downloadselfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.tar.gz
selfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.zip
initial commit
Diffstat (limited to 'roles/solr')
-rw-r--r--roles/solr/defaults/main.yml5
-rw-r--r--roles/solr/handlers/main.yml4
-rw-r--r--roles/solr/tasks/main.yml77
-rw-r--r--roles/solr/templates/etc/solr/log4j2.xml.j218
-rw-r--r--roles/solr/templates/etc/solr/solrconfig.xml.j2280
-rw-r--r--roles/solr/templates/etc/sysconfig/solr.j26
-rw-r--r--roles/solr/templates/etc/systemd/system/solr.service.j263
-rw-r--r--roles/solr/vars/main.yml3
8 files changed, 456 insertions, 0 deletions
diff --git a/roles/solr/defaults/main.yml b/roles/solr/defaults/main.yml
new file mode 100644
index 0000000..ffcc163
--- /dev/null
+++ b/roles/solr/defaults/main.yml
@@ -0,0 +1,5 @@
+solr_version: 9.1.1
+solr_lucene_version: 9.3.0
+solr_port: 8983
+solr_heap_size: 2g
+solr_softcommit_ms: 60000
diff --git a/roles/solr/handlers/main.yml b/roles/solr/handlers/main.yml
new file mode 100644
index 0000000..ca32ef7
--- /dev/null
+++ b/roles/solr/handlers/main.yml
@@ -0,0 +1,4 @@
+- name: restart solr
+ systemd:
+ name: solr
+ state: restarted
diff --git a/roles/solr/tasks/main.yml b/roles/solr/tasks/main.yml
new file mode 100644
index 0000000..0538a2a
--- /dev/null
+++ b/roles/solr/tasks/main.yml
@@ -0,0 +1,77 @@
+- name: install java
+ dnf:
+ name: java-17-openjdk-headless
+ state: present
+
+- name: create installation directory
+ file:
+ path: '{{ solr_install_dir }}'
+ state: directory
+
+- name: unpack solr tarball
+ unarchive:
+ src: '{{ solr_url }}'
+ remote_src: yes
+ dest: '{{ solr_install_dir }}'
+ extra_opts:
+ - '--strip-components=1'
+ notify: restart solr
+
+- name: add local user
+ user:
+ name: solr
+ system: yes
+ home: '{{ solr_data_dir }}'
+ shell: /sbin/nologin
+ create_home: no
+
+- name: create data directory
+ file:
+ path: '{{ solr_data_dir }}'
+ state: directory
+ owner: solr
+ group: solr
+ mode: 0770
+
+- name: create systemd unit
+ template:
+ src: etc/systemd/system/solr.service.j2
+ dest: /etc/systemd/system/solr.service
+ register: solr_unit
+
+- name: reload systemd units
+ systemd:
+ daemon_reload: yes
+ when: solr_unit.changed
+
+- name: create config directory
+ file:
+ path: /etc/solr
+ state: directory
+
+- name: create EnvironmentFile
+ template:
+ src: etc/sysconfig/solr.j2
+ dest: /etc/sysconfig/solr
+ notify: restart solr
+
+- name: create config files
+ template:
+ src: etc/solr/{{ item }}.j2
+ dest: /etc/solr/{{ item }}
+ loop:
+ - log4j2.xml
+ - solrconfig.xml
+ notify: restart solr
+
+- name: copy default solr configuration
+ copy:
+ src: '{{ solr_install_dir }}/server/solr/solr.xml'
+ dest: '{{ solr_data_dir }}/solr.xml'
+ remote_src: yes
+
+- name: start solr
+ systemd:
+ name: solr
+ enabled: yes
+ state: started
diff --git a/roles/solr/templates/etc/solr/log4j2.xml.j2 b/roles/solr/templates/etc/solr/log4j2.xml.j2
new file mode 100644
index 0000000..a5d0442
--- /dev/null
+++ b/roles/solr/templates/etc/solr/log4j2.xml.j2
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+ <Appenders>
+ <Console name="STDOUT" target="SYSTEM_OUT">
+ <PatternLayout>
+ <Pattern>
+ {% raw %}%maxLen{%-5p %c %m%notEmpty{ =>%ex{short}}}{10240}%n{% endraw %}
+
+ </Pattern>
+ </PatternLayout>
+ </Console>
+ </Appenders>
+ <Loggers>
+ <AsyncRoot level="INFO">
+ <AppenderRef ref="STDOUT"/>
+ </AsyncRoot>
+ </Loggers>
+</Configuration>
diff --git a/roles/solr/templates/etc/solr/solrconfig.xml.j2 b/roles/solr/templates/etc/solr/solrconfig.xml.j2
new file mode 100644
index 0000000..0b5a602
--- /dev/null
+++ b/roles/solr/templates/etc/solr/solrconfig.xml.j2
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<config>
+ <luceneMatchVersion>{{ solr_lucene_version }}</luceneMatchVersion>
+ <!-- the rest of this file is unchanged from the defaults -->
+ <dataDir>${solr.data.dir:}</dataDir>
+ <directoryFactory name="DirectoryFactory"
+ class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>
+ <codecFactory class="solr.SchemaCodecFactory"/>
+ <indexConfig>
+ <lockType>${solr.lock.type:native}</lockType>
+ </indexConfig>
+ <jmx />
+ <updateHandler class="solr.DirectUpdateHandler2">
+ <updateLog>
+ <str name="dir">${solr.ulog.dir:}</str>
+ <int name="numVersionBuckets">${solr.ulog.numVersionBuckets:65536}</int>
+ </updateLog>
+ <autoCommit>
+ <maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
+ <openSearcher>false</openSearcher>
+ </autoCommit>
+ <autoSoftCommit>
+ <maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
+ </autoSoftCommit>
+ </updateHandler>
+
+ <query>
+ <maxBooleanClauses>${solr.max.booleanClauses:1024}</maxBooleanClauses>
+ <filterCache size="512"
+ initialSize="512"
+ autowarmCount="0"/>
+ <queryResultCache size="512"
+ initialSize="512"
+ autowarmCount="0"/>
+
+ <documentCache size="512"
+ initialSize="512"
+ autowarmCount="0"/>
+
+ <cache name="perSegFilter"
+ size="10"
+ initialSize="0"
+ autowarmCount="10"
+ regenerator="solr.NoOpRegenerator" />
+
+ <enableLazyFieldLoading>true</enableLazyFieldLoading>
+
+ <queryResultWindowSize>20</queryResultWindowSize>
+
+ <queryResultMaxDocsCached>200</queryResultMaxDocsCached>
+
+ <listener event="newSearcher" class="solr.QuerySenderListener">
+ <arr name="queries">
+ </arr>
+ </listener>
+ <listener event="firstSearcher" class="solr.QuerySenderListener">
+ <arr name="queries">
+ </arr>
+ </listener>
+
+ <useColdSearcher>false</useColdSearcher>
+ </query>
+
+ <circuitBreakers enabled="true">
+ </circuitBreakers>
+
+
+ <requestDispatcher>
+ <httpCaching never304="true" />
+ </requestDispatcher>
+
+ <requestHandler name="/select" class="solr.SearchHandler">
+ <lst name="defaults">
+ <str name="echoParams">explicit</str>
+ <int name="rows">10</int>
+ <str name="df">hdr</str>
+ </lst>
+ </requestHandler>
+
+ <requestHandler name="/query" class="solr.SearchHandler">
+ <lst name="defaults">
+ <str name="echoParams">explicit</str>
+ <str name="wt">json</str>
+ <str name="indent">true</str>
+ </lst>
+ </requestHandler>
+
+ <initParams path="/update/**,/query,/select,/spell">
+ <lst name="defaults">
+ <str name="df">_text_</str>
+ </lst>
+ </initParams>
+
+ <searchComponent name="spellcheck" class="solr.SpellCheckComponent">
+
+ <str name="queryAnalyzerFieldType">text_general</str>
+
+ <lst name="spellchecker">
+ <str name="name">default</str>
+ <str name="field">_text_</str>
+ <str name="classname">solr.DirectSolrSpellChecker</str>
+ <str name="distanceMeasure">internal</str>
+ <float name="accuracy">0.5</float>
+ <int name="maxEdits">2</int>
+ <int name="minPrefix">1</int>
+ <int name="maxInspections">5</int>
+ <int name="minQueryLength">4</int>
+ <float name="maxQueryFrequency">0.01</float>
+ </lst>
+ </searchComponent>
+
+ <requestHandler name="/spell" class="solr.SearchHandler" startup="lazy">
+ <lst name="defaults">
+ <str name="spellcheck.dictionary">default</str>
+ <str name="spellcheck">on</str>
+ <str name="spellcheck.extendedResults">true</str>
+ <str name="spellcheck.count">10</str>
+ <str name="spellcheck.alternativeTermCount">5</str>
+ <str name="spellcheck.maxResultsForSuggest">5</str>
+ <str name="spellcheck.collate">true</str>
+ <str name="spellcheck.collateExtendedResults">true</str>
+ <str name="spellcheck.maxCollationTries">10</str>
+ <str name="spellcheck.maxCollations">5</str>
+ </lst>
+ <arr name="last-components">
+ <str>spellcheck</str>
+ </arr>
+ </requestHandler>
+
+ <searchComponent name="terms" class="solr.TermsComponent"/>
+
+ <requestHandler name="/terms" class="solr.SearchHandler" startup="lazy">
+ <lst name="defaults">
+ <bool name="terms">true</bool>
+ <bool name="distrib">false</bool>
+ </lst>
+ <arr name="components">
+ <str>terms</str>
+ </arr>
+ </requestHandler>
+
+ <searchComponent class="solr.HighlightComponent" name="highlight">
+ <highlighting>
+ <fragmenter name="gap"
+ default="true"
+ class="solr.highlight.GapFragmenter">
+ <lst name="defaults">
+ <int name="hl.fragsize">100</int>
+ </lst>
+ </fragmenter>
+
+ <fragmenter name="regex"
+ class="solr.highlight.RegexFragmenter">
+ <lst name="defaults">
+ <int name="hl.fragsize">70</int>
+ <float name="hl.regex.slop">0.5</float>
+ <str name="hl.regex.pattern">[-\w ,/\n\&quot;&apos;]{20,200}</str>
+ </lst>
+ </fragmenter>
+
+ <formatter name="html"
+ default="true"
+ class="solr.highlight.HtmlFormatter">
+ <lst name="defaults">
+ <str name="hl.simple.pre"><![CDATA[<em>]]></str>
+ <str name="hl.simple.post"><![CDATA[</em>]]></str>
+ </lst>
+ </formatter>
+
+ <encoder name="html"
+ class="solr.highlight.HtmlEncoder" />
+
+ <fragListBuilder name="simple"
+ class="solr.highlight.SimpleFragListBuilder"/>
+
+ <fragListBuilder name="single"
+ class="solr.highlight.SingleFragListBuilder"/>
+
+ <fragListBuilder name="weighted"
+ default="true"
+ class="solr.highlight.WeightedFragListBuilder"/>
+
+ <fragmentsBuilder name="default"
+ default="true"
+ class="solr.highlight.ScoreOrderFragmentsBuilder">
+ </fragmentsBuilder>
+
+ <fragmentsBuilder name="colored"
+ class="solr.highlight.ScoreOrderFragmentsBuilder">
+ <lst name="defaults">
+ <str name="hl.tag.pre"><![CDATA[
+ <b style="background:yellow">,<b style="background:lawgreen">,
+ <b style="background:aquamarine">,<b style="background:magenta">,
+ <b style="background:palegreen">,<b style="background:coral">,
+ <b style="background:wheat">,<b style="background:khaki">,
+ <b style="background:lime">,<b style="background:deepskyblue">]]></str>
+ <str name="hl.tag.post"><![CDATA[</b>]]></str>
+ </lst>
+ </fragmentsBuilder>
+
+ <boundaryScanner name="default"
+ default="true"
+ class="solr.highlight.SimpleBoundaryScanner">
+ <lst name="defaults">
+ <str name="hl.bs.maxScan">10</str>
+ <str name="hl.bs.chars">.,!? &#9;&#10;&#13;</str>
+ </lst>
+ </boundaryScanner>
+
+ <boundaryScanner name="breakIterator"
+ class="solr.highlight.BreakIteratorBoundaryScanner">
+ <lst name="defaults">
+ <str name="hl.bs.type">WORD</str>
+ <str name="hl.bs.language">en</str>
+ <str name="hl.bs.country">US</str>
+ </lst>
+ </boundaryScanner>
+ </highlighting>
+ </searchComponent>
+
+ <updateProcessor class="solr.UUIDUpdateProcessorFactory" name="uuid"/>
+ <updateProcessor class="solr.RemoveBlankFieldUpdateProcessorFactory" name="remove-blank"/>
+ <updateProcessor class="solr.FieldNameMutatingUpdateProcessorFactory" name="field-name-mutating">
+ <str name="pattern">[^\w-\.]</str>
+ <str name="replacement">_</str>
+ </updateProcessor>
+ <updateProcessor class="solr.ParseBooleanFieldUpdateProcessorFactory" name="parse-boolean"/>
+ <updateProcessor class="solr.ParseLongFieldUpdateProcessorFactory" name="parse-long"/>
+ <updateProcessor class="solr.ParseDoubleFieldUpdateProcessorFactory" name="parse-double"/>
+ <updateProcessor class="solr.ParseDateFieldUpdateProcessorFactory" name="parse-date">
+ <arr name="format">
+ <str>yyyy-MM-dd['T'[HH:mm[:ss[.SSS]][z</str>
+ <str>yyyy-MM-dd['T'[HH:mm[:ss[,SSS]][z</str>
+ <str>yyyy-MM-dd HH:mm[:ss[.SSS]][z</str>
+ <str>yyyy-MM-dd HH:mm[:ss[,SSS]][z</str>
+ <str>[EEE, ]dd MMM yyyy HH:mm[:ss] z</str>
+ <str>EEEE, dd-MMM-yy HH:mm:ss z</str>
+ <str>EEE MMM ppd HH:mm:ss [z ]yyyy</str>
+ </arr>
+ </updateProcessor>
+ <updateProcessor class="solr.AddSchemaFieldsUpdateProcessorFactory" name="add-schema-fields">
+ <lst name="typeMapping">
+ <str name="valueClass">java.lang.String</str>
+ <str name="fieldType">text_general</str>
+ <lst name="copyField">
+ <str name="dest">*_str</str>
+ <int name="maxChars">256</int>
+ </lst>
+ <bool name="default">true</bool>
+ </lst>
+ <lst name="typeMapping">
+ <str name="valueClass">java.lang.Boolean</str>
+ <str name="fieldType">booleans</str>
+ </lst>
+ <lst name="typeMapping">
+ <str name="valueClass">java.util.Date</str>
+ <str name="fieldType">pdates</str>
+ </lst>
+ <lst name="typeMapping">
+ <str name="valueClass">java.lang.Long</str>
+ <str name="valueClass">java.lang.Integer</str>
+ <str name="fieldType">plongs</str>
+ </lst>
+ <lst name="typeMapping">
+ <str name="valueClass">java.lang.Number</str>
+ <str name="fieldType">pdoubles</str>
+ </lst>
+ </updateProcessor>
+
+ <updateRequestProcessorChain name="add-unknown-fields-to-the-schema" default="${update.autoCreateFields:true}"
+ processor="uuid,remove-blank,field-name-mutating,parse-boolean,parse-long,parse-double,parse-date,add-schema-fields">
+ <processor class="solr.LogUpdateProcessorFactory"/>
+ <processor class="solr.DistributedUpdateProcessorFactory"/>
+ <processor class="solr.RunUpdateProcessorFactory"/>
+ </updateRequestProcessorChain>
+
+ <queryResponseWriter name="json" class="solr.JSONResponseWriter">
+ <str name="content-type">text/plain; charset=UTF-8</str>
+ </queryResponseWriter>
+</config>
diff --git a/roles/solr/templates/etc/sysconfig/solr.j2 b/roles/solr/templates/etc/sysconfig/solr.j2
new file mode 100644
index 0000000..04e9ade
--- /dev/null
+++ b/roles/solr/templates/etc/sysconfig/solr.j2
@@ -0,0 +1,6 @@
+JVM_HEAP_SIZE="{{ solr_heap_size }}"
+
+SOLR_CONF_DIR=/etc/solr
+SOLR_OPTS="-Dsolr.autoSoftCommit.maxTime={{ solr_softcommit_ms }}"
+
+LOG4J_PROPS=/etc/solr/log4j2.xml
diff --git a/roles/solr/templates/etc/systemd/system/solr.service.j2 b/roles/solr/templates/etc/systemd/system/solr.service.j2
new file mode 100644
index 0000000..52ee55f
--- /dev/null
+++ b/roles/solr/templates/etc/systemd/system/solr.service.j2
@@ -0,0 +1,63 @@
+[Unit]
+Description=Apache Solr
+Before=dovecot.service
+
+[Service]
+Type=simple
+User=solr
+LimitNOFILE=65000
+LimitNPROC=65000
+Restart=on-failure
+
+ProtectSystem=strict
+ReadWritePaths={{ solr_data_dir }} /var/log/solr
+
+# Harden this java nightmare
+NoNewPrivileges=yes
+PrivateTmp=yes
+PrivateDevices=yes
+DevicePolicy=closed
+ProtectSystem=strict
+ProtectHome=yes
+ProtectControlGroups=yes
+ProtectKernelModules=yes
+ProtectKernelTunables=yes
+RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+RestrictNamespaces=yes
+RestrictRealtime=yes
+RestrictSUIDSGID=yes
+LockPersonality=yes
+
+WorkingDirectory={{ solr_install_dir }}/server
+LogsDirectory=solr
+
+Environment=SOLR_HOME={{ solr_data_dir }}
+Environment=SOLR_CONF_DIR=${SOLR_HOME}/server/solr/configsets/_default/conf
+Environment=JVM_ARGS=
+Environment=JVM_GC_ARGS="-XX:+UseG1GC -XX:+PerfDisableSharedMem -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=250 -XX:+UseLargePages -XX:+AlwaysPreTouch -XX:+ExplicitGCInvokesConcurrent"
+Environment=JVM_HEAP_SIZE=512m
+Environment=JETTY_HOST=localhost
+Environment=JETTY_PORT=8983
+Environment=LOG4J_PROPS={{ solr_install_dir }}/server/resources/log4j2.xml
+EnvironmentFile=/etc/sysconfig/solr
+
+ExecStart=java -server \
+ $JVM_ARGS \
+ -Xmx${JVM_HEAP_SIZE} \
+ $SOLR_OPTS \
+ $JVM_GC_ARGS \
+ -XX:+CrashOnOutOfMemoryError \
+ -Dlog4j.configurationFile=${LOG4J_PROPS} \
+ -Dsolr.log.dir=/var/log/solr \
+ -Djetty.host=${JETTY_HOST} \
+ -Djetty.port=${JETTY_PORT} \
+ -Djetty.home={{ solr_install_dir }}/server \
+ -Dsolr.solr.home=${SOLR_HOME} \
+ -Dsolr.data.home= \
+ -Dsolr.install.dir={{ solr_install_dir }} \
+ -Dsolr.default.confdir=${SOLR_CONF_DIR} \
+ -Dlog4j2.formatMsgNoLookups=true \
+ -jar start.jar --module=http --module=gzip
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/solr/vars/main.yml b/roles/solr/vars/main.yml
new file mode 100644
index 0000000..fa5f1f8
--- /dev/null
+++ b/roles/solr/vars/main.yml
@@ -0,0 +1,3 @@
+solr_url: https://dlcdn.apache.org/solr/solr/{{ solr_version }}/solr-{{ solr_version }}.tgz
+solr_install_dir: /usr/local/share/solr
+solr_data_dir: /var/lib/solr