summaryrefslogtreecommitdiff
path: root/src/install/7_scripts.xml
blob: 3ea0550067df03f9db197e536c28fb183fd7d8d7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?xml version="1.0" encoding="utf-8"?>
<chapter label="7" id="scripts">
    <title>Authoring and Maintaining HorizonScripts</title>
    <para>A <firstterm>HorizonScript</firstterm> defines the configuration of a computer.  The Horizon Executor takes a HorizonScript as input, and configures a computer using the information provided.</para>
    <para>This chapter will introduce you to concepts and best practices related to authoring and maintaining HorizonScript files.</para>
    <section id="script_intro">
        <title>Introduction to HorizonScript</title>
        <para>A HorizonScript is a plain-text file.  Each line of text has a <firstterm>key</firstterm>, which specifies what the line is configuring, and one or more <firstterm>value</firstterm>s, which is the configuration data.</para>
        <para>The Horizon Executor configures the <firstterm>target computer</firstterm>, or target.  The target computer is the computer on which you are configuring the environment.</para>
        <para>All HorizonScript files are required to specify at least four keys: <literal>network</literal>, which determines whether networking will be enabled on the target; <literal>hostname</literal>, which determines the host name of the target; <literal>pkginstall</literal>, which determines what packages will be installed on the target; and <literal>rootpw</literal>, which determines the encrypted root password for the target.</para>
        <para>For a detailed list of all valid keys, consult the <ulink url="https://horizon.adelielinux.org/script/">HorizonScript Reference at https://horizon.adelielinux.org/script/</ulink>.</para>
    </section>
    <section id="script_author">
        <title>Authoring HorizonScripts</title>
        <para>You may author a HorizonScript in one of three ways:</para>
        <itemizedlist>
            <listitem><para>
                    <emphasis role="bold">Using System Installation</emphasis>:
                    You can run the System Installation wizard in Runtime Environment mode.  When you finish with the wizard, instead of installing to your computer, it will save a HorizonScript to a location you specify.
            </para></listitem>
            <listitem><para>
                    <emphasis role="bold">Using a text editor</emphasis>:
                    You can write HorizonScripts using a text editor.  Ensure that the text editor you use does not use formatting; HorizonScript files are plain text only.
            </para></listitem>
            <listitem><para>
                    <emphasis role="bold">Using JSON</emphasis>:
                    The Horizon system defines a JSON schema for representing HorizonScript files.  If you have a tool capable of writing a properly-formatted JSON file, you may use the <command>hscript-fromjson</command> utility to generate a HorizonScript.
            </para></listitem>
        </itemizedlist>
        <para>Each of these methods should be evaluated based on your desired use case.  Note, however, that using a text editor may allow you to configure some advanced settings that the other methods do not support.</para>
        <section id="using_ui">
            <title>Using System Installation</title>
            <para>Install the <literal>horizon-wizard</literal> package on your workstation.  If you are not using an APK-based Linux distribution, you may download releases from <ulink url="https://horizon.adelielinux.org/">https://horizon.adelielinux.org/</ulink>.</para>
            <para>Run System Installation.  Refer to <xref linkend="navigating" /> and <xref linkend="options" /> for more information on how to use System Installation.</para>
            <para>At the end of System Installation, you will be prompted for a location to write the HorizonScript.  System Installation will write the HorizonScript and then close.  You may then review or edit it using a text editor.</para>
        </section>
        <section id="using_vi">
            <title>Using a text editor</title>
            <para>You can write HorizonScript files in a text editor.  Typically, HorizonScript files are named "<filename>installfile</filename>" or "<filename><userinput>name</userinput>.installfile</filename>".  You can also add comments on their own line by prefixing the comment with a "<literal>#</literal>" character.</para>
            <para>A simple HorizonScript that configures a computer called "test-web" to serve a Ruby Web site might look like:</para>
            <example>
                <title>A simple HorizonScript</title>
                <programlisting>
network true
netaddress eth0 static 10.1.9.8 255.255.0.0 10.1.0.1
nameserver 9.9.9.9
hostname test-web
pkginstall adelie-base-posix dash-binsh easy-kernel easy-kernel-modules lighttpd openrc ruby-full uwsgi-rack
# Enable lighttpd on startup:
svcenable lighttpd
                </programlisting>
            </example>
        </section>
        <section id="using_js">
            <title>Using JSON</title>
            <para>If you have a properly-formatted JSON file, for example from a vendor-provided tool, you can use it to generate a HorizonScript file.</para>
            <procedure>
                <title>Generating a HorizonScript from a JSON file</title>
                <step><para>Locate the JSON file on your computer.</para></step>
                <step><para>Open a Terminal window.</para></step>
                <step><para>Run <literal><command>hscript-fromjson</command> <filename><userinput>output.installfile</userinput></filename> <filename><userinput>/path/to/file.json</userinput></filename></literal>, where <userinput>output.installfile</userinput> is the desired location for the HorizonScript, and <userinput>/path/to/file.json</userinput> is the path to the JSON file.</para></step>
            </procedure>
        </section>
    </section>
    <section id="adv_script">
        <title>Advanced Usage of HorizonScripts</title>
        <para>The HorizonScript format allows for many different ways to author and extend configurations.</para>
        <para>One of the ways to extend configurations is via the <firstterm>inherit</firstterm> system.  Using this system, you write a base HorizonScript containing common options that apply to a group of computers, and then write per-computer configurations that <emphasis>inherit</emphasis> from the base HorizonScript.</para>
        <para>A HorizonScript can only inherit from a single HorizonScript.  However, you can use nesting and have the base HorizonScript inherit from another base.</para>
        <para>The following is an example of a typical multi-level nested HorizonScript:</para>
        <example>
            <title>Nesting HorizonScripts</title>
            <programlisting>
# base.installfile
network true
netaddress eth0 dhcp
nameserver 9.9.9.9
# Install KDE and X11 on all workstations.
pkginstall adelie-base-posix dash-binsh easy-kernel easy-kernel-modules kde openrc x11
svcenable udev boot
svcenable elogind
svcenable sddm
            </programlisting>
            <programlisting>
# cad.installfile
pkginstall blender freecad libreoffice
inherit base.installfile
            </programlisting>
            <programlisting>
# taylors-workstation.installfile
hostname taylor-workstation
rootpw <replaceable>...</replaceable>
username taylor
useralias taylor Taylor
usergroup taylor wheel,users,audio,video,usb,lp
userpw taylor <replaceable>...</replaceable>
inherit cad.installfile
            </programlisting>
        </example>
        <para>Another way to generate HorizonScripts is by using a templating engine.  Choosing and using a templating engine is beyond the scope of this document, but a few options may include Template::Toolkit for Perl, Jinja for Python, and ERB for Ruby.  Any templating engine capable of producing plain text files may be used to generate HorizonScript files.</para>
    </section>
    <section id="validate_script">
        <title>Validating HorizonScripts</title>
        <para>Once you have authored your HorizonScript, you may run the HorizonScript Validation Utility to ensure that the HorizonScript is syntatically valid.  The HorizonScript Validation Utility uses the same parsing engine that the Horizon Executor uses, so you can be assured that if the Validation Utility finds no issues, your script will have no parsing issues during execution.</para>
        <note>
            <para>Passing validation does not mean that a script will execute successfully, only that it will be parsed successfully.  For example, the Validation Utility cannot ensure that the disk structure you have specified will fit on the target computer's disk drive.</para>
        </note>
        <procedure>
            <title>Validating a script using the HorizonScript Validation Utility</title>
            <step><para>Locate the HorizonScript on your computer.</para></step>
            <step><para>Open a Terminal window.</para></step>
            <step><para>Run <literal><command>hscript-validate</command> <filename><userinput>/path/to/installfile</userinput></filename></literal>, where <userinput>/path/to/installfile</userinput> is the path to your HorizonScript.</para></step>
        </procedure>
        <para>The HorizonScript Validation Utility outputs log messages in the same format as the Horizon Executor.  For more information on interpreting log messages from the HorizonScript Validation Utility, refer to <!-- TODO chap 5 <xref linkend="executor_log"/> -->.</para>
        <para>If you believe your HorizonScript may have multiple errors, you can use the <option>-k</option> flag (which stands for "Keep going") to have the Validation Utility run through the entire script instead of stopping at the first error.</para>
    </section>
    <section id="simulate_script">
        <title>Simulating Execution of a HorizonScript</title>
        <para>One way to ensure your HorizonScript will execute in the way you expect is to use the HorizonScript Simulation Utility.  The Simulation Utility will log every action that the Executor will take, and will also output equivalent shell commands to what the Executor will run.</para>
        <procedure>
            <title>Simulating a script using the HorizonScript Simulation Utility</title>
            <step><para>Locate the HorizonScript on your computer.</para></step>
            <step><para>Open a Terminal window.</para></step>
            <step><para>Run <literal><command>hscript-simulate</command> <filename><userinput>/path/to/installfile</userinput></filename></literal>, where <userinput>/path/to/installfile</userinput> is the path to your HorizonScript.</para></step>
        </procedure>
        <para>The HorizonScript Simulation Utility outputs log messages in the same format as the Horizon Executor.  For more information on interpreting log messages from the HorizonScript Simulation Utility, refer to <!-- TODO chap 5 <xref linkend="executor_log"/> -->.</para>
        <para>The HorizonScript Simulation Utility writes log messages to <literal>stderr</literal>, and the equivalent shell commands to <literal>stdout</literal>.  If you want to read the log messages and discard the shell commands, you may run the <literal><command>hscript-simulate</command></literal> command with <literal>stdout</literal> redirected to <literal>/dev/null</literal>, as in <literal><command>hscript-simulate</command> <filename><userinput>/path/to/installfile</userinput></filename> &gt;/dev/null</literal>.  Similarly, if you want to save the shell commands to a file, you may redirect <literal>stdout</literal> to a file, as in <literal><command>hscript-simulate</command> <filename><userinput>/path/to/installfile</userinput></filename> &gt;<userinput>myscript.sh</userinput></literal>.</para>
    </section>
</chapter>