Compare commits
103 Commits
0.7.202007
...
0.8.202101
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c271df2f5 | ||
|
|
c9b02fa1dd | ||
|
|
83a83e087e | ||
|
|
a0feac3f66 | ||
|
|
4136f8fff4 | ||
|
|
1120a0eebd | ||
|
|
c337994414 | ||
|
|
d9ee2e190d | ||
|
|
ca8819d7b6 | ||
|
|
32a1278326 | ||
|
|
cbd60032fc | ||
|
|
a56c37983c | ||
|
|
2e5811b1ee | ||
|
|
857b5d430b | ||
|
|
a3d2f69b71 | ||
|
|
7150b63391 | ||
|
|
31dfa2bfba | ||
|
|
7675286cd3 | ||
|
|
be6b1adfb9 | ||
|
|
4e843be9e3 | ||
|
|
62c8060b53 | ||
|
|
01494ad3fd | ||
|
|
574f655cc8 | ||
|
|
160040d2e9 | ||
|
|
73c500ce3e | ||
|
|
81ff4a3243 | ||
|
|
7c134184c6 | ||
|
|
54f6ef62cd | ||
|
|
02f9df6cc0 | ||
|
|
c6ad100d8a | ||
|
|
7d44a39a01 | ||
|
|
c2839f859e | ||
|
|
b90d8c60f7 | ||
|
|
5518273881 | ||
|
|
a47b0a43c9 | ||
|
|
30a8a93fe9 | ||
|
|
554f2293c1 | ||
|
|
b0c27329c9 | ||
|
|
351020d137 | ||
|
|
ce57d05081 | ||
|
|
0a9ae633e3 | ||
|
|
4c9f1aca25 | ||
|
|
5e9578ca5e | ||
|
|
a9ea02b743 | ||
|
|
1ffa999f08 | ||
|
|
e1cda4ba15 | ||
|
|
64b869e295 | ||
|
|
8d3b83bd44 | ||
|
|
8b4d18f8f3 | ||
|
|
cc513c3bed | ||
|
|
dd9e55bb9b | ||
|
|
52643c7e07 | ||
|
|
3dc2db84b0 | ||
|
|
3c79e1d82b | ||
|
|
67d2fdcbbb | ||
|
|
2483fdd0f0 | ||
|
|
2225f48f05 | ||
|
|
5b096e82ed | ||
|
|
8bef2bfe63 | ||
|
|
20b6f2ffe6 | ||
|
|
7d78358f9f | ||
|
|
855dcf3eae | ||
|
|
bc07ff2389 | ||
|
|
67a9c65912 | ||
|
|
917b4d8d0b | ||
|
|
ace6c9ab29 | ||
|
|
5e9e58dd92 | ||
|
|
2b9aa0ecd3 | ||
|
|
0c5225571f | ||
|
|
9fd83714c8 | ||
|
|
8725e9ccac | ||
|
|
bf5fd4ef2a | ||
|
|
5b36a9e762 | ||
|
|
5766d66078 | ||
|
|
935118fc99 | ||
|
|
976aa077b6 | ||
|
|
cbff4e326d | ||
|
|
3ca32fa1bc | ||
|
|
fddb762b45 | ||
|
|
a4fcf0100b | ||
|
|
c6aded8d0a | ||
|
|
aaffc882f9 | ||
|
|
94df833e6b | ||
|
|
3c070bf908 | ||
|
|
a369ed399d | ||
|
|
0ce53f4c4e | ||
|
|
abd80b151f | ||
|
|
8b196ffaeb | ||
|
|
5a9034ff18 | ||
|
|
7e27bcd36c | ||
|
|
3ebfb69305 | ||
|
|
d09644dc23 | ||
|
|
1dd2280e2c | ||
|
|
14dbc09b7c | ||
|
|
388cb39607 | ||
|
|
ad749e8a75 | ||
|
|
85176e35da | ||
|
|
a0b0eadc68 | ||
|
|
709f00a2ac | ||
|
|
dc1b1f838a | ||
|
|
24b4985371 | ||
|
|
3872f93063 | ||
|
|
3c19c5b183 |
2
Makefile
2
Makefile
@@ -5,7 +5,7 @@ all:
|
||||
install:
|
||||
@echo "Installing Bastille"
|
||||
@echo
|
||||
@cp -av usr /
|
||||
@cp -Rv usr /
|
||||
@echo
|
||||
@echo "This method is for testing / development."
|
||||
|
||||
|
||||
82
README.md
82
README.md
@@ -45,6 +45,7 @@ Available Commands:
|
||||
bootstrap Bootstrap a FreeBSD release for container base.
|
||||
clone Clone an existing container.
|
||||
cmd Execute arbitrary command on targeted container(s).
|
||||
config Get or set a config value for the targeted container(s).
|
||||
console Console into a running container.
|
||||
convert Convert a thin container into a thick container.
|
||||
cp cp(1) files from host to targeted container(s).
|
||||
@@ -71,14 +72,14 @@ Available Commands:
|
||||
update Update container base -pX release.
|
||||
upgrade Upgrade container release to X.Y-RELEASE.
|
||||
verify Verify bootstrapped release or automation template.
|
||||
zfs Manage (get|set) zfs attributes on targeted container(s).
|
||||
zfs Manage (get|set) ZFS attributes on targeted container(s).
|
||||
|
||||
Use "bastille -v|--version" for version information.
|
||||
Use "bastille command -h|--help" for more information about a command.
|
||||
|
||||
```
|
||||
|
||||
## 0.7-beta
|
||||
## 0.8-beta
|
||||
This document outlines the basic usage of the Bastille container management
|
||||
framework. This release is still considered beta.
|
||||
|
||||
@@ -121,7 +122,7 @@ scrub in on $ext_if all fragment reassemble
|
||||
set skip on lo
|
||||
|
||||
table <jails> persist
|
||||
nat on $ext_if from <jails> to any -> ($ext_if)
|
||||
nat on $ext_if from <jails> to any -> ($ext_if:0)
|
||||
|
||||
## static rdr example
|
||||
# rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
|
||||
@@ -141,6 +142,9 @@ pass in inet proto tcp from any to any port ssh flags S/SA keep state
|
||||
```
|
||||
|
||||
* Make sure to change the `ext_if` variable to match your host system interface.
|
||||
* Note that if multiple interface aliases are in place, the index `($ext_if:0)`
|
||||
can be changed accordingly; so if you want to send traffic out the second IP alias
|
||||
of the interface, change the value to `($ext_if:1)` and so on.
|
||||
* Make sure to include the last line (`port ssh`) or you'll end up locked
|
||||
out of a remote system.
|
||||
|
||||
@@ -149,7 +153,7 @@ containers are:
|
||||
|
||||
```
|
||||
table <jails> persist
|
||||
nat on $ext_if from <jails> to any -> ($ext_if)
|
||||
nat on $ext_if from <jails> to any -> ($ext_if:0)
|
||||
|
||||
## rdr example
|
||||
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
|
||||
@@ -364,10 +368,6 @@ VNET also requires a custom `devfs` ruleset. Create the file as needed on the ho
|
||||
**/etc/devfs.rules**
|
||||
```
|
||||
[bastille_vnet=13]
|
||||
add include $devfsrules_hide_all
|
||||
add include $devfsrules_unhide_basic
|
||||
add include $devfsrules_unhide_login
|
||||
add include $devfsrules_jail
|
||||
add path 'bpf*' unhide
|
||||
```
|
||||
|
||||
@@ -628,8 +628,8 @@ Templates](https://gitlab.com/BastilleBSD-Templates)?
|
||||
Bastille supports a templating system allowing you to apply files, pkgs and
|
||||
execute commands inside the container automatically.
|
||||
|
||||
Currently supported template hooks are: `LIMITS`, `INCLUDE`, `PRE`, `FSTAB`,
|
||||
`PKG`, `OVERLAY`, `SYSRC`, `SERVICE`, `CMD`.
|
||||
Currently supported template hooks are: `ARG`, `LIMITS`, `INCLUDE`, `PRE`,
|
||||
`FSTAB`, `PKG`, `OVERLAY`, `SYSRC`, `SERVICE`, `CMD`, `RENDER`.
|
||||
Planned template hooks include: `PF`, `LOG`
|
||||
|
||||
Templates are created in `${bastille_prefix}/templates` and can leverage any of
|
||||
@@ -652,17 +652,19 @@ echo "usr" > /usr/local/bastille/templates/username/base-template/OVERLAY
|
||||
Template hooks are executed in specific order and require specific syntax to
|
||||
work as expected. This table outlines that order and those requirements:
|
||||
|
||||
| SUPPORTED | format | example |
|
||||
|-----------|---------------------|------------------------------------------------|
|
||||
| LIMITS | resource value | memoryuse 1G |
|
||||
| INCLUDE | template path/URL | http?://TEMPLATE_URL or username/base-template |
|
||||
| PRE | /bin/sh command | mkdir -p /usr/local/path |
|
||||
| FSTAB | fstab syntax | /host/path container/path nullfs ro 0 0 |
|
||||
| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop |
|
||||
| OVERLAY | paths (one/line) | etc usr |
|
||||
| SYSRC | sysrc command(s) | nginx_enable=YES |
|
||||
| SERVICE | service command(s) | nginx restart |
|
||||
| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh |
|
||||
| SUPPORTED | format | example |
|
||||
|-----------|-----------------------|------------------------------------------------|
|
||||
| ARG | name=value (one/line) | domain=example.com (omit value for no default) |
|
||||
| LIMITS | resource value | memoryuse 1G |
|
||||
| INCLUDE | template path/URL | http?://TEMPLATE_URL or username/base-template |
|
||||
| PRE | /bin/sh command | mkdir -p /usr/local/path |
|
||||
| FSTAB | fstab syntax | /host/path container/path nullfs ro 0 0 |
|
||||
| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop |
|
||||
| OVERLAY | paths (one/line) | etc usr |
|
||||
| SYSRC | sysrc command(s) | nginx_enable=YES |
|
||||
| SERVICE | service command(s) | nginx restart |
|
||||
| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh |
|
||||
| RENDER | paths (one/line) | /usr/local/etc/nginx |
|
||||
|
||||
| PLANNED | format | example |
|
||||
|---------|------------------|----------------------------------------------------------------|
|
||||
@@ -671,6 +673,13 @@ work as expected. This table outlines that order and those requirements:
|
||||
|
||||
Note: SYSRC requires NO quotes or that quotes (`"`) be escaped. ie; `\"`)
|
||||
|
||||
Any name provided in the ARG file can be used as a variable in the other hooks.
|
||||
For example, `name=value` in the ARG file will cause instances of `${name}`
|
||||
to be replaced with `value`. The `RENDER` hook can be used to specify existing files or
|
||||
directories inside the jail whose contents should have the variables replaced. Values can be
|
||||
specified either through the command line when applying the template or as a default in the ARG
|
||||
file.
|
||||
|
||||
In addition to supporting template hooks, Bastille supports overlaying files
|
||||
into the container. This is done by placing the files in their full path, using the
|
||||
template directory as "/".
|
||||
@@ -702,12 +711,23 @@ create a `Bastillefile` inside the base template directory. Each line in
|
||||
the file should begin with an uppercase reference to a Bastille command
|
||||
followed by its arguments (omitting the target, which is deduced from the
|
||||
`template` arguments). Lines beginning with `#` are treated as comments.
|
||||
Variables can also be defined using `ARG` with one `name=value` pair per
|
||||
line. Subsequent references to `${name}` would be replaced by `value`.
|
||||
Note that argument values are not available for use until after the point
|
||||
at which they are defined in the file. Both `${JAIL_NAME}` and `${JAIL_IP}`
|
||||
are made available in templates without having to define them as args.
|
||||
|
||||
Bastillefile example:
|
||||
|
||||
```shell
|
||||
LIMITS memoryuse 1G
|
||||
|
||||
# This value can be overridden when the template is applied.
|
||||
ARG domain=example.com
|
||||
|
||||
# Replace all argument variables inside the nginx config.
|
||||
RENDER /usr/local/etc/nginx
|
||||
|
||||
# Install and start nginx.
|
||||
PKG nginx
|
||||
SYSRC nginx_enable=YES
|
||||
@@ -716,6 +736,9 @@ SERVICE nginx restart
|
||||
# Copy files to nginx.
|
||||
CP www/ usr/local/www/nginx-dist/
|
||||
|
||||
# Use the "domain" arg to create a file on the server containing the domain.
|
||||
CMD echo "${domain}" > /usr/local/www/nginx-dist/domain.txt
|
||||
|
||||
# Create a file on the server containing the jail's hostname.
|
||||
CMD hostname > /usr/local/www/nginx-dist/hostname.txt
|
||||
|
||||
@@ -723,6 +746,11 @@ CMD hostname > /usr/local/www/nginx-dist/hostname.txt
|
||||
RDR tcp 80 80
|
||||
```
|
||||
|
||||
Use the following command to convert a hook-based template into the Bastillefile format:
|
||||
```shell
|
||||
bastille template --convert my-template
|
||||
```
|
||||
|
||||
Applying Templates
|
||||
------------------
|
||||
|
||||
@@ -732,8 +760,12 @@ Bastille includes a `template` sub-command. This sub-command requires a target
|
||||
and a template name. As covered in the previous section, template names
|
||||
correspond to directory names in the `bastille/templates` directory.
|
||||
|
||||
To provide values for arguments defined by `ARG` in the template, pass the
|
||||
optional `--arg` parameter as many times as needed. Alternatively, use
|
||||
`--arg-file <fileName>` with one `name=value` pair per line.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille template folsom username/base
|
||||
ishmael ~ # bastille template folsom username/base --arg domain=example.com
|
||||
[folsom]:
|
||||
Copying files...
|
||||
Copy complete.
|
||||
@@ -906,7 +938,7 @@ validation are not used.
|
||||
|
||||
bastille zfs
|
||||
------------
|
||||
This sub-command allows managing zfs attributes for the targeted container(s).
|
||||
This sub-command allows managing ZFS attributes for the targeted container(s).
|
||||
Common usage includes setting container quotas.
|
||||
|
||||
**set quota**
|
||||
@@ -932,7 +964,7 @@ Note: On UFS systems containers must be stopped before export.
|
||||
```shell
|
||||
ishmael ~ # bastille export folsom
|
||||
Exporting 'folsom' to a compressed .xz archive.
|
||||
Sending zfs data stream...
|
||||
Sending ZFS data stream...
|
||||
100 % 1057.2 KiB / 9231.5 KiB = 0.115 0:01
|
||||
Exported '/usr/local/bastille/jails/backups/folsom_2020-01-26-19:23:04.xz' successfully.
|
||||
|
||||
@@ -947,7 +979,7 @@ ishmael ~ # bastille import folsom_2020-01-26-19:22:23.xz
|
||||
Validating file: folsom_2020-01-26-19:22:23.xz...
|
||||
File validation successful!
|
||||
Importing 'folsom' from compressed .xz archive.
|
||||
Receiving zfs data stream...
|
||||
Receiving ZFS data stream...
|
||||
/usr/local/bastille/jails/backups/folsom_2020-01-26-19:22:23.xz (1/1)
|
||||
100 % 626.4 KiB / 9231.5 KiB = 0.068 0:02
|
||||
Container 'folsom' imported successfully.
|
||||
|
||||
@@ -4,7 +4,7 @@ Bastille is available in the official FreeBSD ports tree at
|
||||
`sysutils/bastille`. Binary packages available in `quarterly` and `latest`
|
||||
repositories.
|
||||
|
||||
Current version is `0.7.20200714`.
|
||||
Current version is `0.8.20210101`.
|
||||
|
||||
To install from the FreeBSD package repository:
|
||||
|
||||
|
||||
@@ -76,10 +76,6 @@ host system:
|
||||
## /etc/devfs.rules (NOT .conf)
|
||||
|
||||
[bastille_vnet=13]
|
||||
add include $devfsrules_hide_all
|
||||
add include $devfsrules_unhide_basic
|
||||
add include $devfsrules_unhide_login
|
||||
add include $devfsrules_jail
|
||||
add path 'bpf*' unhide
|
||||
|
||||
Lastly, you may want to consider these three `sysctl` values:
|
||||
@@ -90,6 +86,29 @@ Lastly, you may want to consider these three `sysctl` values:
|
||||
net.link.bridge.pfil_onlyip=0
|
||||
net.link.bridge.pfil_member=0
|
||||
|
||||
**Regarding Routes**
|
||||
|
||||
Bastille will attempt to auto-detect the default route from the host system and
|
||||
assign it to the VNET container. This auto-detection may not always be accurate
|
||||
for your needs for the particular container. In this case you'll need to add
|
||||
a default route manually or define the preferred default route in the
|
||||
`bastille.conf`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
bastille sysrc TARGET defaultrouter=aa.bb.cc.dd
|
||||
bastille service TARGET routing restart
|
||||
|
||||
To define a default route / gateway for all VNET containers define the value in
|
||||
`bastille.conf`:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
bastille_network_gateway=aa.bb.cc.dd
|
||||
|
||||
This config change will apply the defined gateway to any new containers.
|
||||
Existing containers will need to be manually updated.
|
||||
|
||||
|
||||
Public Network
|
||||
==============
|
||||
@@ -161,7 +180,7 @@ Create the firewall rules:
|
||||
|
||||
# If you are using dynamic rdr also need to ensure that the external port
|
||||
# range you are using is open
|
||||
# pass in inet proto tcp any to any port <rdr-start>:<rdr-end>
|
||||
# pass in inet proto tcp from any to any port <rdr-start>:<rdr-end>
|
||||
|
||||
- Make sure to change the `ext_if` variable to match your host system interface.
|
||||
- Make sure to include the last line (`port ssh`) or you'll end up locked out.
|
||||
|
||||
@@ -9,7 +9,7 @@ as described in the Networking section).
|
||||
|
||||
Note: you need to be careful if host services are configured to run
|
||||
on all interfaces as this will include the jail interface - you should
|
||||
sepcify the interface they run on in rc.conf (or other config files)
|
||||
specify the interface they run on in rc.conf (or other config files)
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ Usage
|
||||
bootstrap Bootstrap a FreeBSD release for container base.
|
||||
cmd Execute arbitrary command on targeted container(s).
|
||||
clone Clone an existing container.
|
||||
config Get or set a config value for the targeted container(s).
|
||||
console Console into a running container.
|
||||
convert Convert a Thin container into a Thick container.
|
||||
cp cp(1) files from host to targeted container(s).
|
||||
@@ -24,6 +25,7 @@ Usage
|
||||
help Help about any command.
|
||||
htop Interactive process viewer (requires htop).
|
||||
import Import a specified container.
|
||||
limits Apply resources limits to targeted container(s). See rctl(8).
|
||||
list List containers (running and stopped).
|
||||
mount Mount a volume inside the targeted container(s).
|
||||
pkg Manipulate binary packages within targeted container(s). See pkg(8).
|
||||
@@ -40,7 +42,7 @@ Usage
|
||||
update Update container base -pX release.
|
||||
upgrade Upgrade container release to X.Y-RELEASE.
|
||||
verify Compare release against a "known good" index.
|
||||
zfs Manage (get|set) zfs attributes on targeted container(s).
|
||||
zfs Manage (get|set) ZFS attributes on targeted container(s).
|
||||
|
||||
Use "bastille -v|--version" for version information.
|
||||
Use "bastille command -h|--help" for more information about a command.
|
||||
|
||||
@@ -12,9 +12,9 @@ copyright = '2018-2020, Christer Edwards'
|
||||
author = 'Christer Edwards'
|
||||
|
||||
# The short X.Y version
|
||||
version = '0.7.20200714'
|
||||
version = '0.8.20210101'
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '0.7.20200714-beta'
|
||||
release = '0.8.20210101-beta'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
@@ -30,19 +30,14 @@
|
||||
|
||||
PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
|
||||
|
||||
bastille_colors_pre() {
|
||||
## so we can make it colorful
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
}
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
## root check first.
|
||||
bastille_root_check() {
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
bastille_colors_pre
|
||||
## permission denied
|
||||
echo -e "${COLOR_RED}Bastille: Permission Denied${COLOR_RESET}" 1>&2
|
||||
echo -e "${COLOR_RED}root / sudo / doas required${COLOR_RESET}" 1>&2
|
||||
exit 1
|
||||
error_notify "Bastille: Permission Denied"
|
||||
error_exit "root / sudo / doas required"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -51,9 +46,7 @@ bastille_root_check
|
||||
## check for config existance
|
||||
bastille_conf_check() {
|
||||
if [ ! -r "/usr/local/etc/bastille/bastille.conf" ]; then
|
||||
bastille_colors_pre
|
||||
echo -e "${COLOR_RED}Missing Configuration${COLOR_RESET}" 1>&2
|
||||
exit 1
|
||||
error_exit "Missing Configuration"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -68,11 +61,8 @@ bastille_perms_check() {
|
||||
if [ -d "${bastille_prefix}" ]; then
|
||||
BASTILLE_PREFIX_PERMS=$(stat -f "%Op" "${bastille_prefix}")
|
||||
if [ "${BASTILLE_PREFIX_PERMS}" != 40750 ]; then
|
||||
bastille_colors_pre
|
||||
echo -e "${COLOR_RED}Insecure permissions on ${bastille_prefix}${COLOR_RESET}" 1>&2
|
||||
echo -e "${COLOR_RED}Try: chmod 0750 ${bastille_prefix}${COLOR_RESET}" 1>&2
|
||||
echo
|
||||
exit 1
|
||||
error_notify "Insecure permissions on ${bastille_prefix}"
|
||||
error_exit "Try: chmod 0750 ${bastille_prefix}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -80,7 +70,7 @@ bastille_perms_check() {
|
||||
bastille_perms_check
|
||||
|
||||
## version
|
||||
BASTILLE_VERSION="0.7.20200714"
|
||||
BASTILLE_VERSION="0.8.20210101"
|
||||
|
||||
usage() {
|
||||
cat << EOF
|
||||
@@ -94,6 +84,7 @@ Available Commands:
|
||||
bootstrap Bootstrap a FreeBSD release for container base.
|
||||
cmd Execute arbitrary command on targeted container(s).
|
||||
clone Clone an existing container.
|
||||
config Get or set a config value for the targeted container(s).
|
||||
console Console into a running container.
|
||||
convert Convert a Thin container into a Thick container.
|
||||
cp cp(1) files from host to targeted container(s).
|
||||
@@ -104,6 +95,7 @@ Available Commands:
|
||||
help Help about any command.
|
||||
htop Interactive process viewer (requires htop).
|
||||
import Import a specified container.
|
||||
limits Apply resources limits to targeted container(s). See rctl(8).
|
||||
list List containers (running and stopped).
|
||||
mount Mount a volume inside the targeted container(s).
|
||||
pkg Manipulate binary packages within targeted container(s). See pkg(8).
|
||||
@@ -120,7 +112,7 @@ Available Commands:
|
||||
update Update container base -pX release.
|
||||
upgrade Upgrade container release to X.Y-RELEASE.
|
||||
verify Compare release against a "known good" index.
|
||||
zfs Manage (get|set) zfs attributes on targeted container(s).
|
||||
zfs Manage (get|set) ZFS attributes on targeted container(s).
|
||||
|
||||
Use "bastille -v|--version" for version information.
|
||||
Use "bastille command -h|--help" for more information about a command.
|
||||
@@ -137,27 +129,64 @@ shift
|
||||
# Handle special-case commands first.
|
||||
case "${CMD}" in
|
||||
version|-v|--version)
|
||||
bastille_colors_pre
|
||||
echo -e "${COLOR_GREEN}${BASTILLE_VERSION}${COLOR_RESET}"
|
||||
info "${BASTILLE_VERSION}"
|
||||
exit 0
|
||||
;;
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
bootstrap|create|destroy|import|list|rdr|restart|start|update|upgrade|verify)
|
||||
# Nothing "extra" to do for these commands. -- cwells
|
||||
;;
|
||||
clone|config|cmd|console|convert|cp|edit|export|htop|limits|mount|pkg|rename|service|stop|sysrc|template|top|umount|zfs)
|
||||
# Parse the target and ensure it exists. -- cwells
|
||||
if [ $# -eq 0 ]; then # No target was given, so show the command's help. -- cwells
|
||||
PARAMS='help'
|
||||
elif [ "${1}" != 'help' ] && [ "${1}" != '-h' ] && [ "${1}" != '--help' ]; then
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
# Filter out all non-commands
|
||||
case "${CMD}" in
|
||||
bootstrap|clone|cmd|console|convert|cp|create)
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
_JAILS=$(jls name)
|
||||
JAILS=""
|
||||
for _jail in ${_JAILS}; do
|
||||
_JAILPATH=$(jls -j "${_jail}" path)
|
||||
if [ -z ${_JAILPATH##${bastille_jailsdir}*} ]; then
|
||||
JAILS="${JAILS} ${_jail}"
|
||||
fi
|
||||
done
|
||||
elif [ "${CMD}" = 'template' ] && [ "${TARGET}" = '--convert' ]; then
|
||||
# This command does not act on a jail, so we are temporarily bypassing the presence/started
|
||||
# checks. The command will simply convert a template from hooks to a Bastillefile. -- cwells
|
||||
else
|
||||
JAILS="${TARGET}"
|
||||
|
||||
# Ensure the target exists. -- cwells
|
||||
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
error_exit "[${TARGET}]: Not found."
|
||||
fi
|
||||
|
||||
case "${CMD}" in
|
||||
cmd|console|htop|pkg|service|stop|sysrc|template|top)
|
||||
# Require the target to be running. -- cwells
|
||||
if [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'."
|
||||
fi
|
||||
;;
|
||||
convert|rename)
|
||||
# Require the target to be stopped. -- cwells
|
||||
if [ "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
export TARGET
|
||||
export JAILS
|
||||
fi
|
||||
;;
|
||||
destroy|edit|export|htop|import|limits|list|mount)
|
||||
;;
|
||||
pkg|rdr|rename|restart|service|start|stop|sysrc|umount)
|
||||
;;
|
||||
template|top|update|upgrade|verify|zfs)
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
*) # Filter out all non-commands
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -168,8 +197,11 @@ if [ -f "${SCRIPTPATH}" ]; then
|
||||
|
||||
: "${SH:=sh}"
|
||||
|
||||
exec "${SH}" "${SCRIPTPATH}" "$@"
|
||||
if [ -n "${PARAMS}" ]; then
|
||||
exec "${SH}" "${SCRIPTPATH}" "${PARAMS}"
|
||||
else
|
||||
exec "${SH}" "${SCRIPTPATH}" "$@"
|
||||
fi
|
||||
else
|
||||
bastille_colors_pre
|
||||
echo -e "${COLOR_RED}${SCRIPTPATH} not found.${COLOR_RESET}" 1>&2
|
||||
error_exit "${SCRIPTPATH} not found."
|
||||
fi
|
||||
|
||||
@@ -48,3 +48,10 @@ bastille_decompress_xz_options="-c -d -v" ## default
|
||||
bastille_network_loopback="bastille0" ## default: "bastille0"
|
||||
bastille_network_shared="" ## default: ""
|
||||
bastille_network_gateway="" ## default: ""
|
||||
|
||||
## Default Templates
|
||||
bastille_template_base="default/base" ## default: "default/base"
|
||||
bastille_template_empty="default/empty" ## default: "default/empty"
|
||||
bastille_template_thick="default/thick" ## default: "default/thick"
|
||||
bastille_template_thin="default/thin" ## default: "default/thin"
|
||||
bastille_template_vnet="default/vnet" ## default: "default/vnet"
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille bootstrap [release|template] [update].${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille bootstrap [release|template] [update|arch]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,25 +42,35 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Validate ZFS parameters first.
|
||||
#Validate if ZFS is enabled in rc.conf and bastille.conf.
|
||||
if [ "$(sysrc -n zfs_enable)" = "YES" ] && [ ! "${bastille_zfs_enable}" = "YES" ]; then
|
||||
warn "ZFS is enabled in rc.conf but not bastille.conf. Do you want to continue? (N|y)"
|
||||
read answer
|
||||
case $answer in
|
||||
no|No|n|N|"")
|
||||
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_enable."
|
||||
;;
|
||||
yes|Yes|y|Y)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Validate ZFS parameters.
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
## check for the ZFS pool and bastille prefix
|
||||
if [ -z "${bastille_zfs_zpool}" ]; then
|
||||
echo -e "${COLOR_RED}ERROR: Missing ZFS parameters, see bastille_zfs_zpool.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_zpool."
|
||||
elif [ -z "${bastille_zfs_prefix}" ]; then
|
||||
echo -e "${COLOR_RED}ERROR: Missing ZFS parameters, see bastille_zfs_prefix.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_prefix."
|
||||
elif ! zfs list "${bastille_zfs_zpool}" > /dev/null 2>&1; then
|
||||
echo -e "${COLOR_RED}ERROR: ${bastille_zfs_zpool} is not a ZFS pool.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ERROR: ${bastille_zfs_zpool} is not a ZFS pool."
|
||||
fi
|
||||
|
||||
## check for the ZFS dataset prefix if already exist
|
||||
if [ -d "/${bastille_zfs_zpool}/${bastille_zfs_prefix}" ]; then
|
||||
if [ -d "/${bastille_zfs_zpool}/${bastille_zfs_prefix}" ]; then
|
||||
if ! zfs list "${bastille_zfs_zpool}/${bastille_zfs_prefix}" > /dev/null 2>&1; then
|
||||
echo -e "${COLOR_RED}ERROR: ${bastille_zfs_zpool}/${bastille_zfs_prefix} is not a ZFS dataset.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ERROR: ${bastille_zfs_zpool}/${bastille_zfs_prefix} is not a ZFS dataset."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -71,10 +80,16 @@ validate_release_url() {
|
||||
if [ -n "${NAME_VERIFY}" ]; then
|
||||
RELEASE="${NAME_VERIFY}"
|
||||
if ! fetch -qo /dev/null "${UPSTREAM_URL}/MANIFEST" 2>/dev/null; then
|
||||
echo -e "${COLOR_RED}Unable to fetch MANIFEST, See 'bootstrap urls'.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Unable to fetch MANIFEST. See 'bootstrap urls'."
|
||||
fi
|
||||
echo -e "${COLOR_GREEN}Bootstrapping ${PLATFORM_OS} distfiles...${COLOR_RESET}"
|
||||
info "Bootstrapping ${PLATFORM_OS} distfiles..."
|
||||
|
||||
# Alternate RELEASE/ARCH fetch support
|
||||
if [ "${OPTION}" = "--i386" -o "${OPTION}" = "--32bit" ]; then
|
||||
ARCH="i386"
|
||||
RELEASE="${RELEASE}-${ARCH}"
|
||||
fi
|
||||
|
||||
bootstrap_directories
|
||||
bootstrap_release
|
||||
else
|
||||
@@ -163,6 +178,7 @@ bootstrap_directories() {
|
||||
else
|
||||
mkdir -p "${bastille_templatesdir}"
|
||||
fi
|
||||
ln -s "${bastille_sharedir}/templates/default" "${bastille_templatesdir}/default"
|
||||
fi
|
||||
|
||||
## ${bastille_releasesdir}
|
||||
@@ -200,10 +216,9 @@ bootstrap_release() {
|
||||
|
||||
## check if release already bootstrapped, else continue bootstrapping
|
||||
if [ -z "${bastille_bootstrap_archives}" ]; then
|
||||
echo -e "${COLOR_RED}Bootstrap appears complete.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Bootstrap appears complete."
|
||||
else
|
||||
echo -e "${COLOR_GREEN}Bootstrapping additional distfiles...${COLOR_RESET}"
|
||||
info "Bootstrapping additional distfiles..."
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -211,14 +226,13 @@ bootstrap_release() {
|
||||
## check if the dist files already exists then extract
|
||||
FETCH_VALIDATION="0"
|
||||
if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
|
||||
echo -e "${COLOR_GREEN}Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz.${COLOR_RESET}"
|
||||
info "Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz."
|
||||
if /usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz"; then
|
||||
## silence motd at container login
|
||||
touch "${bastille_releasesdir}/${RELEASE}/root/.hushlogin"
|
||||
touch "${bastille_releasesdir}/${RELEASE}/usr/share/skel/dot.hushlogin"
|
||||
else
|
||||
echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Failed to extract ${_archive}.txz."
|
||||
fi
|
||||
else
|
||||
## get the manifest for dist files checksum validation
|
||||
@@ -248,8 +262,7 @@ bootstrap_release() {
|
||||
rm -rf "${bastille_releasesdir}/${RELEASE}"
|
||||
fi
|
||||
fi
|
||||
echo -e "${COLOR_RED}Bootstrap failed.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Bootstrap failed."
|
||||
fi
|
||||
|
||||
## fetch for missing dist files
|
||||
@@ -257,7 +270,7 @@ bootstrap_release() {
|
||||
fetch "${UPSTREAM_URL}/${_archive}.txz" -o "${bastille_cachedir}/${RELEASE}/${_archive}.txz"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
## alert only if unable to fetch additional dist files
|
||||
echo -e "${COLOR_RED}Failed to fetch ${_archive}.txz.${COLOR_RESET}"
|
||||
error_notify "Failed to fetch ${_archive}.txz."
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -266,34 +279,32 @@ bootstrap_release() {
|
||||
SHA256_DIST=$(grep -w "${_archive}.txz" "${bastille_cachedir}/${RELEASE}/MANIFEST" | awk '{print $2}')
|
||||
SHA256_FILE=$(sha256 -q "${bastille_cachedir}/${RELEASE}/${_archive}.txz")
|
||||
if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then
|
||||
echo -e "${COLOR_RED}Failed validation for ${_archive}.txz, please retry bootstrap!${COLOR_RESET}"
|
||||
rm "${bastille_cachedir}/${RELEASE}/${_archive}.txz"
|
||||
exit 1
|
||||
error_exit "Failed validation for ${_archive}.txz. Please retry bootstrap!"
|
||||
else
|
||||
echo -e "${COLOR_GREEN}Validated checksum for ${RELEASE}:${_archive}.txz.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}MANIFEST:${SHA256_DIST}${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}DOWNLOAD:${SHA256_FILE}${COLOR_RESET}"
|
||||
info "Validated checksum for ${RELEASE}: ${_archive}.txz"
|
||||
info "MANIFEST: ${SHA256_DIST}"
|
||||
info "DOWNLOAD: ${SHA256_FILE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
## extract the fetched dist files
|
||||
if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
|
||||
echo -e "${COLOR_GREEN}Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz.${COLOR_RESET}"
|
||||
info "Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz."
|
||||
if /usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz"; then
|
||||
## silence motd at container login
|
||||
touch "${bastille_releasesdir}/${RELEASE}/root/.hushlogin"
|
||||
touch "${bastille_releasesdir}/${RELEASE}/usr/share/skel/dot.hushlogin"
|
||||
else
|
||||
echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Failed to extract ${_archive}.txz."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo
|
||||
|
||||
echo -e "${COLOR_GREEN}Bootstrap successful.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}See 'bastille --help' for available commands.${COLOR_RESET}"
|
||||
info "Bootstrap successful."
|
||||
info "See 'bastille --help' for available commands."
|
||||
echo
|
||||
}
|
||||
|
||||
@@ -308,6 +319,7 @@ bootstrap_template() {
|
||||
else
|
||||
mkdir -p "${bastille_templatesdir}"
|
||||
fi
|
||||
ln -s "${bastille_sharedir}/templates/default" "${bastille_templatesdir}/default"
|
||||
fi
|
||||
|
||||
## define basic variables
|
||||
@@ -318,16 +330,15 @@ bootstrap_template() {
|
||||
|
||||
## support for non-git
|
||||
if [ ! -x "$(which git)" ]; then
|
||||
echo -e "${COLOR_RED}Git not found.${COLOR_RESET}"
|
||||
echo -e "${COLOR_RED}Not yet implemented.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_notify "Git not found."
|
||||
error_exit "Not yet implemented."
|
||||
elif [ -x "$(which git)" ]; then
|
||||
if [ ! -d "${_template}/.git" ]; then
|
||||
$(which git) clone "${_url}" "${_template}" ||\
|
||||
echo -e "${COLOR_RED}Clone unsuccessful.${COLOR_RESET}"
|
||||
error_notify "Clone unsuccessful."
|
||||
elif [ -d "${_template}/.git" ]; then
|
||||
cd "${_template}" && $(which git) pull ||\
|
||||
echo -e "${COLOR_RED}Template update unsuccessful.${COLOR_RESET}"
|
||||
error_notify "Template update unsuccessful."
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -337,9 +348,28 @@ bootstrap_template() {
|
||||
HW_MACHINE=$(sysctl hw.machine | awk '{ print $2 }')
|
||||
HW_MACHINE_ARCH=$(sysctl hw.machine_arch | awk '{ print $2 }')
|
||||
RELEASE="${1}"
|
||||
OPTION="${2}"
|
||||
|
||||
# Alternate RELEASE/ARCH fetch support(experimental)
|
||||
if [ -n "${OPTION}" ] && [ "${OPTION}" != "${HW_MACHINE}" ] && [ "${OPTION}" != "update" ]; then
|
||||
# Supported architectures
|
||||
if [ "${OPTION}" = "--i386" -o "${OPTION}" = "--32bit" ]; then
|
||||
HW_MACHINE="i386"
|
||||
HW_MACHINE_ARCH="i386"
|
||||
else
|
||||
error_exit "Unsupported architecture."
|
||||
fi
|
||||
fi
|
||||
|
||||
## Filter sane release names
|
||||
case "${1}" in
|
||||
*-CURRENT|*-current)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT)$' | tr '[:lower:]' '[:upper:]')
|
||||
UPSTREAM_URL=$(echo "${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}" | sed 's/releases/snapshots/')
|
||||
PLATFORM_OS="FreeBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]')
|
||||
@@ -401,7 +431,7 @@ http?://github.com/*/*|http?://gitlab.com/*/*)
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${2}" in
|
||||
case "${OPTION}" in
|
||||
update)
|
||||
bastille update "${RELEASE}"
|
||||
;;
|
||||
|
||||
@@ -28,17 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille clone [TARGET] [NEW_NAME] [IPADRESS].${COLOR_RESET}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
error_notify() {
|
||||
# Notify message on error and exit
|
||||
echo -e "$*" >&2
|
||||
exit 1
|
||||
usage() {
|
||||
error_exit "Usage: bastille clone [TARGET] [NEW_NAME] [IPADRESS]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first
|
||||
@@ -48,21 +42,19 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 3 ]; then
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
NEWNAME="${2}"
|
||||
IP="${3}"
|
||||
shift
|
||||
NEWNAME="${1}"
|
||||
IP="${2}"
|
||||
|
||||
validate_ip() {
|
||||
IPX_ADDR="ip4.addr"
|
||||
IP6_MODE="disable"
|
||||
ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))')
|
||||
if [ -n "${ip6}" ]; then
|
||||
echo -e "${COLOR_GREEN}Valid: (${ip6}).${COLOR_RESET}"
|
||||
info "Valid: (${ip6})."
|
||||
IPX_ADDR="ip6.addr"
|
||||
IP6_MODE="new"
|
||||
else
|
||||
@@ -73,18 +65,16 @@ validate_ip() {
|
||||
set ${TEST_IP}
|
||||
for quad in 1 2 3 4; do
|
||||
if eval [ \$$quad -gt 255 ]; then
|
||||
echo "Invalid: (${TEST_IP})"
|
||||
exit 1
|
||||
error_exit "Invalid: (${TEST_IP})"
|
||||
fi
|
||||
done
|
||||
if ifconfig | grep -qw "${TEST_IP}"; then
|
||||
echo -e "${COLOR_YELLOW}Warning: ip address already in use (${TEST_IP}).${COLOR_RESET}"
|
||||
warn "Warning: IP address already in use (${TEST_IP})."
|
||||
else
|
||||
echo -e "${COLOR_GREEN}Valid: (${IP}).${COLOR_RESET}"
|
||||
info "Valid: (${IP})."
|
||||
fi
|
||||
else
|
||||
echo -e "${COLOR_RED}Invalid: (${IP}).${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Invalid: (${IP})."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -130,7 +120,7 @@ update_jailconf_vnet() {
|
||||
|
||||
# If 0.0.0.0 set DHCP, else set static IP address
|
||||
if [ "${IP}" == "0.0.0.0" ]; then
|
||||
sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="DHCP"
|
||||
sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP"
|
||||
else
|
||||
sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}"
|
||||
fi
|
||||
@@ -140,7 +130,7 @@ update_fstab() {
|
||||
# Update fstab to use the new name
|
||||
FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab"
|
||||
if [ -f "${FSTAB_CONFIG}" ]; then
|
||||
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
|
||||
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
|
||||
FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET}/root/.bastille" "${FSTAB_CONFIG}")
|
||||
FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${NEWNAME}/root/.bastille nullfs ro 0 0"
|
||||
if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then
|
||||
@@ -154,39 +144,35 @@ update_fstab() {
|
||||
|
||||
clone_jail() {
|
||||
# Attempt container clone
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
echo -e "${COLOR_GREEN}Attempting to clone '${TARGET}' to ${NEWNAME}...${COLOR_RESET}"
|
||||
if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
# Replicate the existing container
|
||||
DATE=$(date +%F-%H%M%S)
|
||||
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}"
|
||||
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" | zfs recv "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}"
|
||||
info "Attempting to clone '${TARGET}' to ${NEWNAME}..."
|
||||
if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
# Replicate the existing container
|
||||
DATE=$(date +%F-%H%M%S)
|
||||
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}"
|
||||
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" | zfs recv "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}"
|
||||
|
||||
# Cleanup source temporary snapshots
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_clone_${DATE}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}"
|
||||
# Cleanup source temporary snapshots
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_clone_${DATE}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}"
|
||||
|
||||
# Cleanup target temporary snapshots
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}/root@bastille_clone_${DATE}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}@bastille_clone_${DATE}"
|
||||
fi
|
||||
else
|
||||
# Just clone the jail directory
|
||||
# Check if container is running
|
||||
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_notify "${COLOR_RED}${TARGET} is running, See 'bastille stop ${TARGET}'.${COLOR_RESET}"
|
||||
fi
|
||||
|
||||
# Perform container file copy(archive mode)
|
||||
cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
|
||||
# Cleanup target temporary snapshots
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}/root@bastille_clone_${DATE}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}@bastille_clone_${DATE}"
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}${NEWNAME} already exists.${COLOR_RESET}"
|
||||
# Just clone the jail directory
|
||||
# Check if container is running
|
||||
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'."
|
||||
fi
|
||||
|
||||
# Perform container file copy(archive mode)
|
||||
cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}${TARGET} not found. See bootstrap.${COLOR_RESET}"
|
||||
error_exit "${NEWNAME} already exists."
|
||||
fi
|
||||
|
||||
# Generate jail configuration files
|
||||
@@ -195,16 +181,15 @@ clone_jail() {
|
||||
|
||||
# Display the exist status
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_notify "${COLOR_RED}An error has occurred while attempting to clone '${TARGET}'.${COLOR_RESET}"
|
||||
error_exit "An error has occurred while attempting to clone '${TARGET}'."
|
||||
else
|
||||
echo -e "${COLOR_GREEN}Cloned '${TARGET}' to '${NEWNAME}' successfully.${COLOR_RESET}"
|
||||
info "Cloned '${TARGET}' to '${NEWNAME}' successfully."
|
||||
fi
|
||||
}
|
||||
|
||||
## don't allow for dots(.) in container names
|
||||
if echo "${NEWNAME}" | grep -q "[.]"; then
|
||||
echo -e "${COLOR_RED}Container names may not contain a dot(.)!${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Container names may not contain a dot(.)!"
|
||||
fi
|
||||
|
||||
## check if ip address is valid
|
||||
|
||||
@@ -28,11 +28,10 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille cmd TARGET command.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille cmd TARGET command"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,22 +41,12 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -eq 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
jexec -l "${_jail}" "$@"
|
||||
echo
|
||||
done
|
||||
|
||||
50
usr/local/share/bastille/common.sh
Normal file
50
usr/local/share/bastille/common.sh
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
|
||||
# Notify message on error, but do not exit
|
||||
error_notify() {
|
||||
echo -e "${COLOR_RED}$*${COLOR_RESET}" 1>&2
|
||||
}
|
||||
|
||||
# Notify message on error and exit
|
||||
error_exit() {
|
||||
error_notify $@
|
||||
exit 1
|
||||
}
|
||||
|
||||
info() {
|
||||
echo -e "${COLOR_GREEN}$*${COLOR_RESET}"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${COLOR_YELLOW}$*${COLOR_RESET}"
|
||||
}
|
||||
115
usr/local/share/bastille/config.sh
Normal file
115
usr/local/share/bastille/config.sh
Normal file
@@ -0,0 +1,115 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille config TARGET get|set propertyName [newValue]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -eq 1 ] || [ $# -gt 3 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
ACTION=$1
|
||||
shift
|
||||
|
||||
case $ACTION in
|
||||
get)
|
||||
if [ $# -ne 1 ]; then
|
||||
error_notify 'Too many parameters for a "get" operation.'
|
||||
usage
|
||||
fi
|
||||
;;
|
||||
set) ;;
|
||||
*) error_exit 'Only get and set are supported.' ;;
|
||||
esac
|
||||
|
||||
PROPERTY=$1
|
||||
shift
|
||||
VALUE="$@"
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
FILE="${bastille_jailsdir}/${_jail}/jail.conf"
|
||||
if [ ! -f "${FILE}" ]; then
|
||||
error_notify "jail.conf does not exist for jail: ${_jail}"
|
||||
continue
|
||||
fi
|
||||
|
||||
ESCAPED_PROPERTY=$(echo "${PROPERTY}" | sed 's/\./\\\./g')
|
||||
MATCH_LINE=$(grep "^[[:blank:]]*${ESCAPED_PROPERTY}[[:blank:]=;]" "${FILE}" 2>/dev/null)
|
||||
MATCH_FOUND=$?
|
||||
|
||||
if [ "${ACTION}" = 'get' ]; then
|
||||
if [ $MATCH_FOUND -ne 0 ]; then
|
||||
warn "not set"
|
||||
elif ! echo "${MATCH_LINE}" | grep '=' > /dev/null 2>&1; then
|
||||
echo "enabled"
|
||||
else
|
||||
VALUE=$(echo "${MATCH_LINE}" | sed -E 's/.+= *(.+) *;$/\1/' 2>/dev/null)
|
||||
if [ $? -ne 0 ]; then
|
||||
error_notify "Failed to get value."
|
||||
else
|
||||
echo "${VALUE}"
|
||||
fi
|
||||
fi
|
||||
else # Setting the value. -- cwells
|
||||
if [ -n "${VALUE}" ]; then
|
||||
VALUE=$(echo "${VALUE}" | sed 's/\//\\\//g')
|
||||
if echo "${VALUE}" | grep ' ' > /dev/null 2>&1; then # Contains a space, so wrap in quotes. -- cwells
|
||||
VALUE="'${VALUE}'"
|
||||
fi
|
||||
LINE=" ${PROPERTY} = ${VALUE};"
|
||||
else
|
||||
LINE=" ${PROPERTY};"
|
||||
fi
|
||||
|
||||
if [ $MATCH_FOUND -ne 0 ]; then # No match, so insert the property at the end. -- cwells
|
||||
echo "$(awk -v line="${LINE}" '$0 == "}" { print line; } 1 { print $0; }' "${FILE}")" > "${FILE}"
|
||||
else # Replace the existing value. -- cwells
|
||||
sed -i '' -E "s/ *${ESCAPED_PROPERTY}[ =;].*/${LINE}/" "${FILE}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Only display this message once at the end (not for every jail). -- cwells
|
||||
if [ "${ACTION}" = 'set' ]; then
|
||||
info "A restart is required for the changes to be applied. See 'bastille restart ${TARGET}'."
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -28,11 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille console TARGET [user]'.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille console TARGET [user]'"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,21 +42,12 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -gt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
USER="${1}"
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
validate_user() {
|
||||
if jexec -l "${_jail}" id "${USER}" >/dev/null 2>&1; then
|
||||
USER_SHELL="$(jexec -l "${_jail}" getent passwd "${USER}" | cut -d: -f7)"
|
||||
@@ -74,12 +65,22 @@ validate_user() {
|
||||
fi
|
||||
}
|
||||
|
||||
check_fib() {
|
||||
fib=$(grep 'exec.fib' "${bastille_jailsdir}/${_jail}/jail.conf" | awk '{print $3}' | sed 's/\;//g')
|
||||
if [ -n "${fib}" ]; then
|
||||
_setfib="setfib -F ${fib}"
|
||||
else
|
||||
_setfib=""
|
||||
fi
|
||||
}
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
if [ -n "${USER}" ]; then
|
||||
validate_user
|
||||
else
|
||||
jexec -l "${_jail}" /usr/bin/login -f root
|
||||
check_fib
|
||||
${_setfib} jexec -l "${_jail}" /usr/bin/login -f root
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille convert TARGET.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille convert TARGET"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,20 +42,10 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -ne 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
error_notify()
|
||||
{
|
||||
# Notify message on error and exit
|
||||
echo -e "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
convert_symlinks() {
|
||||
# Work with the symlinks, revert on first cp error
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
@@ -86,13 +75,13 @@ convert_symlinks() {
|
||||
fi
|
||||
done
|
||||
else
|
||||
error_notify "${COLOR_RED}Release must be bootstrapped first, See 'bastille bootstrap'.${COLOR_RESET}"
|
||||
error_exit "Release must be bootstrapped first. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
revert_convert() {
|
||||
# Revert the conversion on first cp error
|
||||
echo -e "${COLOR_RED}A problem has occurred while copying the files, reverting changes...${COLOR_RESET}"
|
||||
error_notify "A problem has occurred while copying the files. Reverting changes..."
|
||||
for _link in ${SYMLINKS}; do
|
||||
if [ -d "${_link}" ]; then
|
||||
chflags -R noschg "${bastille_jailsdir}/${TARGET}/root/${_link}"
|
||||
@@ -106,16 +95,16 @@ revert_convert() {
|
||||
mv "${_link}.old" "${_link}"
|
||||
fi
|
||||
done
|
||||
error_notify "${COLOR_GREEN}Changes for '${TARGET}' has been reverted.${COLOR_RESET}"
|
||||
error_exit "Changes for '${TARGET}' has been reverted."
|
||||
}
|
||||
|
||||
start_convert() {
|
||||
# Attempt container conversion and handle some errors
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
echo -e "${COLOR_GREEN}Converting '${TARGET}' into a thickjail, this may take a while...${COLOR_RESET}"
|
||||
info "Converting '${TARGET}' into a thickjail. This may take a while..."
|
||||
|
||||
# Set some variables
|
||||
RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${bastille_jailsdir}/${TARGET}/fstab")
|
||||
RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${bastille_jailsdir}/${TARGET}/fstab")
|
||||
FSTABMOD=$(grep -w "${bastille_releasesdir}/${RELEASE} ${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab")
|
||||
SYMLINKS="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/ports usr/sbin usr/share usr/src"
|
||||
|
||||
@@ -129,32 +118,27 @@ start_convert() {
|
||||
sed -i '' -E "s|${FSTABMOD}|# Converted from thin to thick container on $(date)|g" "${bastille_jailsdir}/${TARGET}/fstab"
|
||||
mv "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/root/.bastille.old"
|
||||
|
||||
echo -e "${COLOR_GREEN}Conversion of '${TARGET}' completed successfully!${COLOR_RESET}"
|
||||
info "Conversion of '${TARGET}' completed successfully!"
|
||||
exit 0
|
||||
else
|
||||
error_notify "${COLOR_RED}Can't determine release version, See 'bastille bootstrap'.${COLOR_RESET}"
|
||||
error_exit "Can't determine release version. See 'bastille bootstrap'."
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}${TARGET} not found. See 'bastille create'.${COLOR_RESET}"
|
||||
error_exit "${TARGET} not found. See 'bastille create'."
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if container is running
|
||||
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_notify "${COLOR_RED}${TARGET} is running, See 'bastille stop'.${COLOR_RESET}"
|
||||
fi
|
||||
|
||||
# Check if is a thin container
|
||||
if [ ! -d "${bastille_jailsdir}/${TARGET}/root/.bastille" ]; then
|
||||
error_notify "${COLOR_RED}${TARGET} is not a thin container.${COLOR_RESET}"
|
||||
error_exit "${TARGET} is not a thin container."
|
||||
elif ! grep -qw ".bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
|
||||
error_notify "${COLOR_RED}${TARGET} is not a thin container.${COLOR_RESET}"
|
||||
error_exit "${TARGET} is not a thin container."
|
||||
fi
|
||||
|
||||
# Make sure the user agree with the conversion
|
||||
# Be interactive here since this cannot be easily undone
|
||||
while :; do
|
||||
echo -e "${COLOR_RED}Warning: container conversion from thin to thick can't be undone!${COLOR_RESET}"
|
||||
error_notify "Warning: container conversion from thin to thick can't be undone!"
|
||||
read -p "Do you really wish to convert '${TARGET}' into a thick container? [y/N]:" yn
|
||||
case ${yn} in
|
||||
[Yy]) start_convert;;
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille cp TARGET HOST_PATH CONTAINER_PATH${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille cp TARGET HOST_PATH CONTAINER_PATH"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,24 +42,23 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 3 ] || [ $# -lt 3 ]; then
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
CPSOURCE="${2}"
|
||||
CPDEST="${3}"
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
CPSOURCE="${1}"
|
||||
CPDEST="${2}"
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
bastille_jail_path="$(jls -j "${_jail}" path)"
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
bastille_jail_path="${bastille_jailsdir}/${_jail}/root"
|
||||
cp -av "${CPSOURCE}" "${bastille_jail_path}/${CPDEST}"
|
||||
echo
|
||||
RETURN="$?"
|
||||
if [ "${TARGET}" = "ALL" ]; then
|
||||
# Display the return status for reference
|
||||
echo -e "Returned: ${RETURN}\n"
|
||||
else
|
||||
echo
|
||||
return "${RETURN}"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -28,25 +28,18 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille create [option] name release ip [interface].${COLOR_RESET}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
error_notify() {
|
||||
# Notify message on error and exit
|
||||
echo -e "$*" >&2
|
||||
exit 1
|
||||
error_exit "Usage: bastille create [option] name release ip [interface]"
|
||||
}
|
||||
|
||||
running_jail() {
|
||||
if [ -n "$(jls name | awk "/^${NAME}$/")" ]; then
|
||||
error_notify "${COLOR_RED}A running jail matches name.${COLOR_RESET}"
|
||||
error_exit "A running jail matches name."
|
||||
elif [ -d "${bastille_jailsdir}/${NAME}" ]; then
|
||||
error_notify "${COLOR_RED}Jail: ${NAME} already created.${COLOR_RESET}"
|
||||
error_exit "Jail: ${NAME} already created."
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -54,7 +47,7 @@ validate_name() {
|
||||
local NAME_VERIFY=${NAME}
|
||||
local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')
|
||||
if [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then
|
||||
error_notify "${COLOR_RED}Container names may not contain special characters!${COLOR_RESET}"
|
||||
error_exit "Container names may not contain special characters!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -63,7 +56,7 @@ validate_ip() {
|
||||
IP6_MODE="disable"
|
||||
ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))')
|
||||
if [ -n "${ip6}" ]; then
|
||||
echo -e "${COLOR_GREEN}Valid: (${ip6}).${COLOR_RESET}"
|
||||
info "Valid: (${ip6})."
|
||||
IPX_ADDR="ip6.addr"
|
||||
IP6_MODE="new"
|
||||
else
|
||||
@@ -79,12 +72,12 @@ validate_ip() {
|
||||
fi
|
||||
done
|
||||
if ifconfig | grep -qw "${TEST_IP}"; then
|
||||
echo -e "${COLOR_YELLOW}Warning: ip address already in use (${TEST_IP}).${COLOR_RESET}"
|
||||
warn "Warning: IP address already in use (${TEST_IP})."
|
||||
else
|
||||
echo -e "${COLOR_GREEN}Valid: (${IP}).${COLOR_RESET}"
|
||||
info "Valid: (${IP})."
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}Invalid: (${IP}).${COLOR_RESET}"
|
||||
error_exit "Invalid: (${IP})."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -92,15 +85,15 @@ validate_ip() {
|
||||
validate_netif() {
|
||||
local LIST_INTERFACES=$(ifconfig -l)
|
||||
if echo "${LIST_INTERFACES} VNET" | grep -qwo "${INTERFACE}"; then
|
||||
echo -e "${COLOR_GREEN}Valid: (${INTERFACE}).${COLOR_RESET}"
|
||||
info "Valid: (${INTERFACE})."
|
||||
else
|
||||
error_notify "${COLOR_RED}Invalid: (${INTERFACE}).${COLOR_RESET}"
|
||||
error_exit "Invalid: (${INTERFACE})."
|
||||
fi
|
||||
}
|
||||
|
||||
validate_netconf() {
|
||||
if [ -n "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
|
||||
error_notify "${COLOR_RED}Invalid network configuration.${COLOR_RESET}"
|
||||
error_exit "Invalid network configuration."
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -255,12 +248,12 @@ create_jail() {
|
||||
## MAKE SURE WE'RE IN THE RIGHT PLACE
|
||||
cd "${bastille_jail_path}"
|
||||
echo
|
||||
echo -e "${COLOR_GREEN}NAME: ${NAME}.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}IP: ${IP}.${COLOR_RESET}"
|
||||
info "NAME: ${NAME}."
|
||||
info "IP: ${IP}."
|
||||
if [ -n "${INTERFACE}" ]; then
|
||||
echo -e "${COLOR_GREEN}INTERFACE: ${INTERFACE}.${COLOR_RESET}"
|
||||
info "INTERFACE: ${INTERFACE}."
|
||||
fi
|
||||
echo -e "${COLOR_GREEN}RELEASE: ${RELEASE}.${COLOR_RESET}"
|
||||
info "RELEASE: ${RELEASE}."
|
||||
echo
|
||||
|
||||
if [ -z "${THICK_JAIL}" ]; then
|
||||
@@ -280,12 +273,12 @@ create_jail() {
|
||||
if [ "$?" -ne 0 ]; then
|
||||
## notify and clean stale files/directories
|
||||
bastille destroy "${NAME}"
|
||||
error_notify "${COLOR_RED}Failed to copy release files, please retry create!${COLOR_RESET}"
|
||||
error_exit "Failed to copy release files. Please retry create!"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo -e "${COLOR_GREEN}Creating a thickjail, this may take a while...${COLOR_RESET}"
|
||||
info "Creating a thickjail. This may take a while..."
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
## perform release base replication
|
||||
@@ -310,7 +303,7 @@ create_jail() {
|
||||
if [ "$?" -ne 0 ]; then
|
||||
## notify and clean stale files/directories
|
||||
bastille destroy "${NAME}"
|
||||
error_notify "${COLOR_RED}Failed release base replication, please retry create!${COLOR_RESET}"
|
||||
error_exit "Failed release base replication. Please retry create!"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
@@ -319,7 +312,7 @@ create_jail() {
|
||||
if [ "$?" -ne 0 ]; then
|
||||
## notify and clean stale files/directories
|
||||
bastille destroy "${NAME}"
|
||||
error_notify "${COLOR_RED}Failed to copy release files, please retry create!${COLOR_RESET}"
|
||||
error_exit "Failed to copy release files. Please retry create!"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -333,61 +326,68 @@ create_jail() {
|
||||
ln -s usr/home home
|
||||
fi
|
||||
|
||||
## rc.conf
|
||||
## + syslogd_flags="-ss"
|
||||
## + sendmail_enable="NO"
|
||||
## + sendmail_submit_enable="NO"
|
||||
## + sendmail_outbound_enable="NO"
|
||||
## + sendmail_msp_queue_enable="NO"
|
||||
## + cron_flags="-J 60" ## cedwards 20181118
|
||||
if [ ! -f "${bastille_jail_rc_conf}" ]; then
|
||||
touch "${bastille_jail_rc_conf}"
|
||||
sysrc -f "${bastille_jail_rc_conf}" syslogd_flags="-ss"
|
||||
sysrc -f "${bastille_jail_rc_conf}" sendmail_enable="NO"
|
||||
sysrc -f "${bastille_jail_rc_conf}" sendmail_submit_enable="NO"
|
||||
sysrc -f "${bastille_jail_rc_conf}" sendmail_outbound_enable="NO"
|
||||
sysrc -f "${bastille_jail_rc_conf}" sendmail_msp_queue_enable="NO"
|
||||
sysrc -f "${bastille_jail_rc_conf}" cron_flags="-J 60"
|
||||
## TZ: configurable (default: Etc/UTC)
|
||||
ln -s "/usr/share/zoneinfo/${bastille_tzdata}" etc/localtime
|
||||
|
||||
## VNET specific
|
||||
if [ -n "${VNET_JAIL}" ]; then
|
||||
## rename interface to generic vnet0
|
||||
uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//')
|
||||
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" "ifconfig_${uniq_epair}_name"=vnet0
|
||||
# Post-creation jail misc configuration
|
||||
# Create a dummy fstab file
|
||||
touch "etc/fstab"
|
||||
# Disables adjkerntz, avoids spurious error messages
|
||||
sed -i '' 's|[0-9],[0-9]\{2\}.*[0-9]-[0-9].*root.*kerntz -a|#& # Disabled by bastille|' "etc/crontab"
|
||||
|
||||
## if 0.0.0.0 set DHCP
|
||||
## else set static address
|
||||
if [ "${IP}" == "0.0.0.0" ]; then
|
||||
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP"
|
||||
else
|
||||
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}"
|
||||
if [ -n "${bastille_network_gateway}" ]; then
|
||||
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" defaultrouter="${bastille_network_gateway}"
|
||||
else
|
||||
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" defaultrouter="$(netstat -rn | awk '/default/ {print $2}')"
|
||||
fi
|
||||
fi
|
||||
|
||||
## VNET requires jib script
|
||||
if [ ! "$(command -v jib)" ]; then
|
||||
if [ -f /usr/share/examples/jails/jib ] && [ ! -f /usr/local/bin/jib ]; then
|
||||
install -m 0544 /usr/share/examples/jails/jib /usr/local/bin/jib
|
||||
fi
|
||||
## VNET specific
|
||||
if [ -n "${VNET_JAIL}" ]; then
|
||||
## VNET requires jib script
|
||||
if [ ! "$(command -v jib)" ]; then
|
||||
if [ -f /usr/share/examples/jails/jib ] && [ ! -f /usr/local/bin/jib ]; then
|
||||
install -m 0544 /usr/share/examples/jails/jib /usr/local/bin/jib
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
## resolv.conf (default: copy from host)
|
||||
if [ ! -f "${bastille_jail_resolv_conf}" ]; then
|
||||
cp -L "${bastille_resolv_conf}" "${bastille_jail_resolv_conf}"
|
||||
fi
|
||||
|
||||
## TZ: configurable (default: Etc/UTC)
|
||||
ln -s "/usr/share/zoneinfo/${bastille_tzdata}" etc/localtime
|
||||
else
|
||||
## Generate minimal configuration for empty jail
|
||||
generate_minimal_conf
|
||||
fi
|
||||
|
||||
# Set strict permissions on the jail by default
|
||||
chmod 0700 "${bastille_jailsdir}/${NAME}"
|
||||
|
||||
# Jail must be started before applying the default template. -- cwells
|
||||
bastille start "${NAME}"
|
||||
|
||||
if [ -n "${VNET_JAIL}" ]; then
|
||||
if [ -n ${bastille_template_vnet} ]; then
|
||||
## rename interface to generic vnet0
|
||||
uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//')
|
||||
|
||||
_gateway=''
|
||||
_ifconfig=SYNCDHCP
|
||||
if [ "${IP}" != "0.0.0.0" ]; then # not using DHCP, so set static address.
|
||||
_ifconfig="inet ${IP}"
|
||||
if [ -n "${bastille_network_gateway}" ]; then
|
||||
_gateway="${bastille_network_gateway}"
|
||||
else
|
||||
_gateway="$(netstat -rn | awk '/default/ {print $2}')"
|
||||
fi
|
||||
fi
|
||||
bastille template "${NAME}" ${bastille_template_vnet} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg IFCONFIG="${_ifconfig}"
|
||||
fi
|
||||
elif [ -n "${THICK_JAIL}" ]; then
|
||||
if [ -n ${bastille_template_thick} ]; then
|
||||
bastille template "${NAME}" ${bastille_template_thick} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
||||
fi
|
||||
elif [ -n "${EMPTY_JAIL}" ]; then
|
||||
if [ -n ${bastille_template_empty} ]; then
|
||||
bastille template "${NAME}" ${bastille_template_empty} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
||||
fi
|
||||
else # Thin jail.
|
||||
if [ -n ${bastille_template_thin} ]; then
|
||||
bastille template "${NAME}" ${bastille_template_thin} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Apply values changed by the template. -- cwells
|
||||
bastille restart "${NAME}"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -429,7 +429,7 @@ else
|
||||
VNET_JAIL="1"
|
||||
;;
|
||||
-*)
|
||||
echo -e "${COLOR_RED}Unknown Option.${COLOR_RESET}"
|
||||
error_notify "Unknown Option."
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
@@ -458,9 +458,14 @@ fi
|
||||
if [ -z "${EMPTY_JAIL}" ]; then
|
||||
## verify release
|
||||
case "${RELEASE}" in
|
||||
*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
|
||||
*-CURRENT|*-CURRENT-I386|*-CURRENT-i386|*-current)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]')
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
|
||||
validate_release
|
||||
;;
|
||||
*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
|
||||
validate_release
|
||||
;;
|
||||
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
|
||||
@@ -489,19 +494,19 @@ if [ -z "${EMPTY_JAIL}" ]; then
|
||||
validate_release
|
||||
;;
|
||||
*)
|
||||
echo -e "${COLOR_RED}Unknown Release.${COLOR_RESET}"
|
||||
error_notify "Unknown Release."
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
## check for name/root/.bastille
|
||||
if [ -d "${bastille_jailsdir}/${NAME}/root/.bastille" ]; then
|
||||
error_notify "${COLOR_RED}Jail: ${NAME} already created. ${NAME}/root/.bastille exists.${COLOR_RESET}"
|
||||
error_exit "Jail: ${NAME} already created. ${NAME}/root/.bastille exists."
|
||||
fi
|
||||
|
||||
## check for required release
|
||||
if [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
error_notify "${COLOR_RED}Release must be bootstrapped first; see 'bastille bootstrap'.${COLOR_RESET}"
|
||||
error_exit "Release must be bootstrapped first; see 'bastille bootstrap'."
|
||||
fi
|
||||
|
||||
## check if ip address is valid
|
||||
@@ -512,14 +517,14 @@ if [ -z "${EMPTY_JAIL}" ]; then
|
||||
fi
|
||||
|
||||
## check if interface is valid
|
||||
if [ -n "${INTERFACE}" ]; then
|
||||
if [ -n "${INTERFACE}" ]; then
|
||||
validate_netif
|
||||
validate_netconf
|
||||
else
|
||||
validate_netconf
|
||||
fi
|
||||
else
|
||||
echo -e "${COLOR_GREEN}Creating empty jail: ${NAME}.${COLOR_RESET}"
|
||||
info "Creating empty jail: ${NAME}."
|
||||
fi
|
||||
|
||||
## check if a running jail matches name or already exist
|
||||
@@ -527,4 +532,27 @@ if [ -n "${NAME}" ]; then
|
||||
running_jail
|
||||
fi
|
||||
|
||||
# May not exist on deployments created before Bastille 0.7.20200714, so creating it. -- cwells
|
||||
if [ ! -e "${bastille_templatesdir}/default" ]; then
|
||||
ln -s "${bastille_sharedir}/templates/default" "${bastille_templatesdir}/default"
|
||||
fi
|
||||
|
||||
# These variables were added after Bastille 0.7.20200714, so they may not exist in the user's config.
|
||||
# We're checking for existence of the variables rather than empty since empty is a valid value. -- cwells
|
||||
if [ -z ${bastille_template_base+x} ]; then
|
||||
bastille_template_base='default/base'
|
||||
fi
|
||||
if [ -z ${bastille_template_empty+x} ]; then
|
||||
bastille_template_empty='default/empty'
|
||||
fi
|
||||
if [ -z ${bastille_template_thick+x} ]; then
|
||||
bastille_template_thick='default/thick'
|
||||
fi
|
||||
if [ -z ${bastille_template_thin+x} ]; then
|
||||
bastille_template_thin='default/thin'
|
||||
fi
|
||||
if [ -z ${bastille_template_vnet+x} ]; then
|
||||
bastille_template_vnet='default/vnet'
|
||||
fi
|
||||
|
||||
create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}"
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille destroy [option] | [container|release]${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille destroy [option] | [container|release]"
|
||||
}
|
||||
|
||||
destroy_jail() {
|
||||
@@ -45,19 +44,17 @@ destroy_jail() {
|
||||
if [ "${FORCE}" = "1" ]; then
|
||||
bastille stop "${TARGET}"
|
||||
else
|
||||
echo -e "${COLOR_RED}Jail running.${COLOR_RESET}"
|
||||
echo -e "${COLOR_RED}See 'bastille stop ${TARGET}'.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_notify "Jail running."
|
||||
error_exit "See 'bastille stop ${TARGET}'."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d "${bastille_jail_base}" ]; then
|
||||
echo -e "${COLOR_RED}Jail not found.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Jail not found."
|
||||
fi
|
||||
|
||||
if [ -d "${bastille_jail_base}" ]; then
|
||||
echo -e "${COLOR_GREEN}Deleting Jail: ${TARGET}.${COLOR_RESET}"
|
||||
info "Deleting Jail: ${TARGET}."
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
if [ -n "${TARGET}" ]; then
|
||||
@@ -82,13 +79,13 @@ destroy_jail() {
|
||||
## archive jail log
|
||||
if [ -f "${bastille_jail_log}" ]; then
|
||||
mv "${bastille_jail_log}" "${bastille_jail_log}"-"$(date +%F)"
|
||||
echo -e "${COLOR_GREEN}Note: jail console logs archived.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}${bastille_jail_log}-$(date +%F)${COLOR_RESET}"
|
||||
info "Note: jail console logs archived."
|
||||
info "${bastille_jail_log}-$(date +%F)"
|
||||
fi
|
||||
|
||||
## clear any active rdr rules
|
||||
if [ ! -z "$(pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null)" ]; then
|
||||
echo -e "${COLOR_GREEN}Clearing RDR rules:${COLOR_RESET}"
|
||||
info "Clearing RDR rules:"
|
||||
pfctl -a "rdr/${TARGET}" -Fn
|
||||
fi
|
||||
echo
|
||||
@@ -113,18 +110,17 @@ destroy_rel() {
|
||||
JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g")
|
||||
for _jail in ${JAIL_LIST}; do
|
||||
if grep -qwo "${TARGET}" "${bastille_jailsdir}/${_jail}/fstab" 2>/dev/null; then
|
||||
echo -e "${COLOR_RED}Notice: (${_jail}) depends on ${TARGET} base.${COLOR_RESET}"
|
||||
error_notify "Notice: (${_jail}) depends on ${TARGET} base."
|
||||
BASE_HASCHILD="1"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ ! -d "${bastille_rel_base}" ]; then
|
||||
echo -e "${COLOR_RED}Release base not found.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Release base not found."
|
||||
else
|
||||
if [ "${BASE_HASCHILD}" -eq "0" ]; then
|
||||
echo -e "${COLOR_GREEN}Deleting base: ${TARGET}.${COLOR_RESET}"
|
||||
info "Deleting base: ${TARGET}"
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
if [ -n "${TARGET}" ]; then
|
||||
@@ -158,7 +154,7 @@ destroy_rel() {
|
||||
fi
|
||||
echo
|
||||
else
|
||||
echo -e "${COLOR_RED}Cannot destroy base with containers child.${COLOR_RESET}"
|
||||
error_notify "Cannot destroy base with child containers."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -180,7 +176,7 @@ case "${1}" in
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
echo -e "${COLOR_RED}Unknown Option.${COLOR_RESET}"
|
||||
error_notify "Unknown Option."
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
@@ -193,9 +189,14 @@ fi
|
||||
|
||||
## check what should we clean
|
||||
case "${TARGET}" in
|
||||
*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
|
||||
*-CURRENT|*-CURRENT-I386|*-CURRENT-i386|*-current)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]')
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
|
||||
destroy_rel
|
||||
;;
|
||||
*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
|
||||
destroy_rel
|
||||
;;
|
||||
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille edit TARGET [filename]${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille edit TARGET [filename]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,26 +42,16 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -gt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
if [ $# == 2 ]; then
|
||||
TARGET_FILENAME="${2}"
|
||||
elif [ $# -eq 1 ]; then
|
||||
TARGET_FILENAME="${1}"
|
||||
fi
|
||||
|
||||
if [ -z "${EDITOR}" ]; then
|
||||
EDITOR=vi
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(bastille list jails)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(bastille list jails | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
if [ -n "${TARGET_FILENAME}" ]; then
|
||||
"${EDITOR}" "${bastille_jailsdir}/${_jail}/${TARGET_FILENAME}"
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille export TARGET.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille export TARGET [option] | PATH"
|
||||
}
|
||||
|
||||
# Handle special-case commands first
|
||||
@@ -43,77 +42,93 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
# Check for unsupported actions
|
||||
if [ "${TARGET}" = "ALL" ]; then
|
||||
error_exit "Batch export is unsupported."
|
||||
fi
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
OPTION="${1}"
|
||||
EXPATH="${2}"
|
||||
|
||||
error_notify()
|
||||
{
|
||||
# Notify message on error and exit
|
||||
echo -e "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
# Handle some options
|
||||
if [ -n "${OPTION}" ]; then
|
||||
if [ "${OPTION}" = "-t" -o "${OPTION}" = "--txz" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
# Temporarily disable ZFS so we can create a standard backup archive
|
||||
bastille_zfs_enable="NO"
|
||||
fi
|
||||
elif echo "${OPTION}" | grep -q "\/"; then
|
||||
if [ -d "${OPTION}" ]; then
|
||||
EXPATH="${OPTION}"
|
||||
else
|
||||
error_exit "Error: Path not found."
|
||||
fi
|
||||
else
|
||||
error_notify "Invalid option!"
|
||||
usage
|
||||
fi
|
||||
fi
|
||||
|
||||
# Export directory check
|
||||
if [ -n "${EXPATH}" ]; then
|
||||
if [ -d "${EXPATH}" ]; then
|
||||
# Set the user defined export directory
|
||||
bastille_backupsdir="${EXPATH}"
|
||||
else
|
||||
error_exit "Error: Path not found."
|
||||
fi
|
||||
fi
|
||||
|
||||
jail_export()
|
||||
{
|
||||
# Attempt to export the container
|
||||
DATE=$(date +%F-%H%M%S)
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
FILE_EXT="xz"
|
||||
echo -e "${COLOR_GREEN}Exporting '${TARGET}' to a compressed .${FILE_EXT} archive.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}Sending zfs data stream...${COLOR_RESET}"
|
||||
# Take a recursive temporary snapshot
|
||||
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
FILE_EXT="xz"
|
||||
info "Exporting '${TARGET}' to a compressed .${FILE_EXT} archive."
|
||||
info "Sending ZFS data stream..."
|
||||
# Take a recursive temporary snapshot
|
||||
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
|
||||
|
||||
# Export the container recursively and cleanup temporary snapshots
|
||||
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}" | \
|
||||
xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_export_${DATE}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
|
||||
fi
|
||||
else
|
||||
# Create standard backup archive
|
||||
FILE_EXT="txz"
|
||||
echo -e "${COLOR_GREEN}Exporting '${TARGET}' to a compressed .${FILE_EXT} archive...${COLOR_RESET}"
|
||||
cd "${bastille_jailsdir}" && tar -cf - "${TARGET}" | xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
|
||||
fi
|
||||
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_notify "${COLOR_RED}Failed to export '${TARGET}' container.${COLOR_RESET}"
|
||||
else
|
||||
# Generate container checksum file
|
||||
cd "${bastille_backupsdir}"
|
||||
sha256 -q "${TARGET}_${DATE}.${FILE_EXT}" > "${TARGET}_${DATE}.sha256"
|
||||
echo -e "${COLOR_GREEN}Exported '${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}' successfully.${COLOR_RESET}"
|
||||
exit 0
|
||||
# Export the container recursively and cleanup temporary snapshots
|
||||
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}" | \
|
||||
xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_export_${DATE}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}Container '${TARGET}' does not exist.${COLOR_RESET}"
|
||||
# Create standard backup archive
|
||||
FILE_EXT="txz"
|
||||
info "Exporting '${TARGET}' to a compressed .${FILE_EXT} archive..."
|
||||
cd "${bastille_jailsdir}" && tar -cf - "${TARGET}" | xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
|
||||
fi
|
||||
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_exit "Failed to export '${TARGET}' container."
|
||||
else
|
||||
# Generate container checksum file
|
||||
cd "${bastille_backupsdir}"
|
||||
sha256 -q "${TARGET}_${DATE}.${FILE_EXT}" > "${TARGET}_${DATE}.sha256"
|
||||
info "Exported '${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}' successfully."
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Check for user specified file location
|
||||
if echo "${TARGET}" | grep -q '\/'; then
|
||||
GETDIR="${TARGET}"
|
||||
TARGET=$(echo ${TARGET} | awk -F '\/' '{print $NF}')
|
||||
bastille_backupsdir=$(echo ${GETDIR} | sed "s/${TARGET}//")
|
||||
fi
|
||||
|
||||
# Check if backups directory/dataset exist
|
||||
if [ ! -d "${bastille_backupsdir}" ]; then
|
||||
error_notify "${COLOR_RED}Backups directory/dataset does not exist, See 'bastille bootstrap'.${COLOR_RESET}"
|
||||
error_exit "Backups directory/dataset does not exist. See 'bastille bootstrap'."
|
||||
fi
|
||||
|
||||
# Check if is a ZFS system
|
||||
if [ "${bastille_zfs_enable}" != "YES" ]; then
|
||||
# Check if container is running and ask for stop in UFS systems
|
||||
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_notify "${COLOR_RED}${TARGET} is running, See 'bastille stop'.${COLOR_RESET}"
|
||||
error_exit "${TARGET} is running. See 'bastille stop'."
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille htop TARGET${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille htop TARGET"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,26 +42,16 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -ne 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
bastille_jail_path=$(jls -j "${_jail}" path)
|
||||
if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then
|
||||
echo -e "${COLOR_RED}htop not found on ${_jail}.${COLOR_RESET}"
|
||||
error_notify "htop not found on ${_jail}."
|
||||
elif [ -x "${bastille_jail_path}/usr/local/bin/htop" ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
jexec -l ${_jail} /usr/local/bin/htop
|
||||
fi
|
||||
echo -e "${COLOR_RESET}"
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille import file [option].${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille import file [option]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first
|
||||
@@ -51,46 +50,40 @@ TARGET="${1}"
|
||||
OPTION="${2}"
|
||||
shift
|
||||
|
||||
error_notify() {
|
||||
# Notify message on error and exit
|
||||
echo -e "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
validate_archive() {
|
||||
# Compare checksums on the target archive
|
||||
# Skip validation for unsupported archives
|
||||
if [ "${FILE_EXT}" != ".tar.gz" ] && [ "${FILE_EXT}" != ".tar" ]; then
|
||||
if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
|
||||
if [ -f "${bastille_backupsdir}/${FILE_TRIM}.sha256" ]; then
|
||||
echo -e "${COLOR_GREEN}Validating file: ${TARGET}...${COLOR_RESET}"
|
||||
info "Validating file: ${TARGET}..."
|
||||
SHA256_DIST=$(cat "${bastille_backupsdir}/${FILE_TRIM}.sha256")
|
||||
SHA256_FILE=$(sha256 -q "${bastille_backupsdir}/${TARGET}")
|
||||
if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then
|
||||
error_notify "${COLOR_RED}Failed validation for ${TARGET}.${COLOR_RESET}"
|
||||
error_exit "Failed validation for ${TARGET}."
|
||||
else
|
||||
echo -e "${COLOR_GREEN}File validation successful!${COLOR_RESET}"
|
||||
info "File validation successful!"
|
||||
fi
|
||||
else
|
||||
# Check if user opt to force import
|
||||
if [ "${OPTION}" = "-f" -o "${OPTION}" = "force" ]; then
|
||||
echo -e "${COLOR_YELLOW}Warning: Skipping archive validation!${COLOR_RESET}"
|
||||
warn "Warning: Skipping archive validation!"
|
||||
else
|
||||
error_notify "${COLOR_RED}Checksum file not found, See 'bastille import TARGET -f'${COLOR_RESET}"
|
||||
error_exit "Checksum file not found. See 'bastille import TARGET -f'."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo -e "${COLOR_YELLOW}Warning: Skipping archive validation!${COLOR_RESET}"
|
||||
warn "Warning: Skipping archive validation!"
|
||||
fi
|
||||
}
|
||||
|
||||
update_zfsmount() {
|
||||
# Update the mountpoint property on the received zfs data stream
|
||||
# Update the mountpoint property on the received ZFS data stream
|
||||
OLD_ZFS_MOUNTPOINT=$(zfs get -H mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" | awk '{print $3}')
|
||||
NEW_ZFS_MOUNTPOINT="${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
if [ "${NEW_ZFS_MOUNTPOINT}" != "${OLD_ZFS_MOUNTPOINT}" ]; then
|
||||
echo -e "${COLOR_GREEN}Updating zfs mountpoint...${COLOR_RESET}"
|
||||
info "Updating ZFS mountpoint..."
|
||||
zfs set mountpoint="${bastille_jailsdir}/${TARGET_TRIM}/root" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
|
||||
fi
|
||||
|
||||
@@ -108,7 +101,7 @@ update_jailconf() {
|
||||
JAIL_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
|
||||
if [ -f "${JAIL_CONFIG}" ]; then
|
||||
if ! grep -qw "path = ${bastille_jailsdir}/${TARGET_TRIM}/root;" "${JAIL_CONFIG}"; then
|
||||
echo -e "${COLOR_GREEN}Updating jail.conf...${COLOR_RESET}"
|
||||
info "Updating jail.conf..."
|
||||
sed -i '' "s|exec.consolelog.*=.*;|exec.consolelog = ${bastille_logsdir}/${TARGET_TRIM}_console.log;|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|path.*=.*;|path = ${bastille_jailsdir}/${TARGET_TRIM}/root;|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|mount.fstab.*=.*;|mount.fstab = ${bastille_jailsdir}/${TARGET_TRIM}/fstab;|" "${JAIL_CONFIG}"
|
||||
@@ -120,13 +113,13 @@ update_fstab() {
|
||||
# Update fstab .bastille mountpoint on thin containers only
|
||||
# Set some variables
|
||||
FSTAB_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/fstab"
|
||||
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
|
||||
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
|
||||
FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET_TRIM}/root/.bastille" "${FSTAB_CONFIG}")
|
||||
FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0"
|
||||
if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then
|
||||
# If both variables are set, compare and update as needed
|
||||
if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille" "${FSTAB_CONFIG}"; then
|
||||
echo -e "${COLOR_GREEN}Updating fstab...${COLOR_RESET}"
|
||||
info "Updating fstab..."
|
||||
sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}"
|
||||
fi
|
||||
fi
|
||||
@@ -135,7 +128,7 @@ update_fstab() {
|
||||
generate_config() {
|
||||
# Attempt to read previous config file and set required variables accordingly
|
||||
# If we can't get a valid interface, fallback to lo1 and warn user
|
||||
echo -e "${COLOR_GREEN}Generating jail.conf...${COLOR_RESET}"
|
||||
info "Generating jail.conf..."
|
||||
|
||||
if [ "${FILE_EXT}" = ".zip" ]; then
|
||||
# Gather some bits from foreign/iocage config files
|
||||
@@ -195,7 +188,7 @@ generate_config() {
|
||||
IPX_ADDR="ip4.addr"
|
||||
IP_CONFIG="-"
|
||||
IP6_MODE="disable"
|
||||
echo -e "${COLOR_YELLOW}Warning: See 'bastille edit ${TARGET_TRIM} jail.conf' for manual network configuration${COLOR_RESET}"
|
||||
warn "Warning: See 'bastille edit ${TARGET_TRIM} jail.conf' for manual network configuration."
|
||||
fi
|
||||
|
||||
if [ "${FILE_EXT}" = ".tar.gz" ]; then
|
||||
@@ -203,7 +196,7 @@ generate_config() {
|
||||
if [ -z "${CONFIG_RELEASE}" ]; then
|
||||
# Fallback to host version
|
||||
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
|
||||
echo -e "${COLOR_YELLOW}Warning: ${CONFIG_RELEASE} was set by default!${COLOR_RESET}"
|
||||
warn "Warning: ${CONFIG_RELEASE} was set by default!"
|
||||
fi
|
||||
mkdir "${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille"
|
||||
echo "${bastille_releasesdir}/${CONFIG_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0" \
|
||||
@@ -248,7 +241,7 @@ update_config() {
|
||||
if [ -z "${CONFIG_RELEASE}" ]; then
|
||||
# Fallback to host version
|
||||
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
|
||||
echo -e "${COLOR_YELLOW}Warning: ${CONFIG_RELEASE} was set by default!${COLOR_RESET}"
|
||||
warn "Warning: ${CONFIG_RELEASE} was set by default!"
|
||||
fi
|
||||
mkdir "${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille"
|
||||
echo "${bastille_releasesdir}/${CONFIG_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0" \
|
||||
@@ -289,11 +282,11 @@ update_symlinks() {
|
||||
|
||||
# Just warn user to bootstrap the release if missing
|
||||
if [ ! -d "${bastille_releasesdir}/${CONFIG_RELEASE}" ]; then
|
||||
echo -e "${COLOR_YELLOW}Warning: ${CONFIG_RELEASE} must be bootstrapped, See 'bastille bootstrap'.${COLOR_RESET}"
|
||||
warn "Warning: ${CONFIG_RELEASE} must be bootstrapped. See 'bastille bootstrap'."
|
||||
fi
|
||||
|
||||
# Update old symlinks
|
||||
echo -e "${COLOR_GREEN}Updating symlinks...${COLOR_RESET}"
|
||||
info "Updating symlinks..."
|
||||
for _link in ${SYMLINKS}; do
|
||||
if [ -L "${_link}" ]; then
|
||||
ln -sf /.bastille/${_link} ${_link}
|
||||
@@ -303,8 +296,8 @@ update_symlinks() {
|
||||
|
||||
create_zfs_datasets() {
|
||||
# Prepare the ZFS environment and restore from file
|
||||
echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}Preparing zfs environment...${COLOR_RESET}"
|
||||
info "Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive."
|
||||
info "Preparing ZFS environment..."
|
||||
|
||||
# Create required ZFS datasets, mountpoint inherited from system
|
||||
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
@@ -315,7 +308,7 @@ remove_zfs_datasets() {
|
||||
# Perform cleanup on failure
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
error_notify "${COLOR_RED}Failed to extract files from '${TARGET}' archive.${COLOR_RESET}"
|
||||
error_exit "Failed to extract files from '${TARGET}' archive."
|
||||
}
|
||||
|
||||
jail_import() {
|
||||
@@ -328,8 +321,8 @@ jail_import() {
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
if [ "${FILE_EXT}" = ".xz" ]; then
|
||||
# Import from compressed xz on ZFS systems
|
||||
echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} archive.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}Receiving zfs data stream...${COLOR_RESET}"
|
||||
info "Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} archive."
|
||||
info "Receiving ZFS data stream..."
|
||||
xz ${bastille_decompress_xz_options} "${bastille_backupsdir}/${TARGET}" | \
|
||||
zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
|
||||
@@ -341,7 +334,7 @@ jail_import() {
|
||||
create_zfs_datasets
|
||||
|
||||
# Extract required files to the new datasets
|
||||
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
tar --exclude='root' -Jxf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
tar -Jxf "${bastille_backupsdir}/${TARGET}" --strip-components 2 -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${TARGET_TRIM}/root"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
@@ -349,17 +342,17 @@ jail_import() {
|
||||
fi
|
||||
elif [ "${FILE_EXT}" = ".zip" ]; then
|
||||
# Attempt to import a foreign/iocage container
|
||||
echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive.${COLOR_RESET}"
|
||||
# Sane bastille zfs options
|
||||
info "Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive."
|
||||
# Sane bastille ZFS options
|
||||
ZFS_OPTIONS=$(echo ${bastille_zfs_options} | sed 's/-o//g')
|
||||
|
||||
# Extract required files from the zip archive
|
||||
cd "${bastille_backupsdir}" && unzip -j "${TARGET}"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_notify "${COLOR_RED}Failed to extract files from '${TARGET}' archive.${COLOR_RESET}"
|
||||
error_exit "Failed to extract files from '${TARGET}' archive."
|
||||
rm -f "${FILE_TRIM}" "${FILE_TRIM}_root"
|
||||
fi
|
||||
echo -e "${COLOR_GREEN}Receiving zfs data stream...${COLOR_RESET}"
|
||||
info "Receiving ZFS data stream..."
|
||||
zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${FILE_TRIM}"
|
||||
zfs set ${ZFS_OPTIONS} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" < "${FILE_TRIM}_root"
|
||||
@@ -383,7 +376,7 @@ jail_import() {
|
||||
create_zfs_datasets
|
||||
|
||||
# Extract required files to the new datasets
|
||||
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
tar --exclude='ezjail/' -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
@@ -398,7 +391,7 @@ jail_import() {
|
||||
workout_components
|
||||
|
||||
# Extract required files to the new datasets
|
||||
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${CONF_TRIM}" -C "${bastille_jailsdir}/${TARGET_TRIM}" "${JAIL_CONF}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${DIRS_PLUS}" -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${JAIL_PATH}"
|
||||
if [ -f "${bastille_jailsdir}/${TARGET_TRIM}/${TARGET_TRIM}" ]; then
|
||||
@@ -411,24 +404,24 @@ jail_import() {
|
||||
update_config
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}Unknown archive format.${COLOR_RESET}"
|
||||
error_exit "Unknown archive format."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Import from standard supported archives on UFS systems
|
||||
if [ "${FILE_EXT}" = ".txz" ]; then
|
||||
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
tar -Jxf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
|
||||
elif [ "${FILE_EXT}" = ".tar.gz" ]; then
|
||||
# Attempt to import/configure foreign/ezjail container
|
||||
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
mkdir "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
mv "${bastille_jailsdir}/${TARGET_TRIM}/ezjail" "${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
generate_config
|
||||
elif [ "${FILE_EXT}" = ".tar" ]; then
|
||||
# Attempt to import/configure foreign/qjail container
|
||||
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
mkdir -p "${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
workout_components
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${CONF_TRIM}" -C "${bastille_jailsdir}/${TARGET_TRIM}" "${JAIL_CONF}"
|
||||
@@ -438,22 +431,22 @@ jail_import() {
|
||||
fi
|
||||
update_config
|
||||
else
|
||||
error_notify "${COLOR_RED}Unsupported archive format.${COLOR_RESET}"
|
||||
error_exit "Unsupported archive format."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_notify "${COLOR_RED}Failed to import from '${TARGET}' archive.${COLOR_RESET}"
|
||||
error_exit "Failed to import from '${TARGET}' archive."
|
||||
else
|
||||
# Update the jail.conf and fstab if required
|
||||
# This is required on foreign imports only
|
||||
update_jailconf
|
||||
update_fstab
|
||||
echo -e "${COLOR_GREEN}Container '${TARGET_TRIM}' imported successfully.${COLOR_RESET}"
|
||||
info "Container '${TARGET_TRIM}' imported successfully."
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}Jails directory/dataset does not exist, See 'bastille bootstrap'.${COLOR_RESET}"
|
||||
error_exit "Jails directory/dataset does not exist. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -466,7 +459,7 @@ fi
|
||||
|
||||
# Check if backups directory/dataset exist
|
||||
if [ ! -d "${bastille_backupsdir}" ]; then
|
||||
error_notify "${COLOR_RED}Backups directory/dataset does not exist, See 'bastille bootstrap'.${COLOR_RESET}"
|
||||
error_exit "Backups directory/dataset does not exist. See 'bastille bootstrap'."
|
||||
fi
|
||||
|
||||
# Check if archive exist then trim archive name
|
||||
@@ -477,17 +470,17 @@ if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
|
||||
TARGET_TRIM=$(echo "${TARGET}" | sed "s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.xz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.txz//;s/_[0-9]*-[0-9]*-[0-9]*.zip//;s/-[0-9]\{12\}.[0-9]\{2\}.tar.gz//;s/@[0-9]\{12\}.[0-9]\{2\}.tar//")
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}Unrecognized archive name.${COLOR_RESET}"
|
||||
error_exit "Unrecognized archive name."
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}Archive '${TARGET}' not found.${COLOR_RESET}"
|
||||
error_exit "Archive '${TARGET}' not found."
|
||||
fi
|
||||
|
||||
# Check if a running jail matches name or already exist
|
||||
if [ -n "$(jls name | awk "/^${TARGET_TRIM}$/")" ]; then
|
||||
error_notify "${COLOR_RED}A running jail matches name.${COLOR_RESET}"
|
||||
error_exit "A running jail matches name."
|
||||
elif [ -d "${bastille_jailsdir}/${TARGET_TRIM}" ]; then
|
||||
error_notify "${COLOR_RED}Container: ${TARGET_TRIM} already exist.${COLOR_RESET}"
|
||||
error_exit "Container: ${TARGET_TRIM} already exists."
|
||||
fi
|
||||
|
||||
jail_import
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille limits TARGET option value${COLOR_RESET}"
|
||||
error_notify "Usage: bastille limits TARGET option value"
|
||||
echo -e "Example: bastille limits JAILNAME memoryuse 1G"
|
||||
exit 1
|
||||
}
|
||||
@@ -51,34 +51,30 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
OPTION="${2}"
|
||||
VALUE="${3}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
OPTION="${1}"
|
||||
VALUE="${2}"
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
|
||||
_rctl_rule="jail:${_jail}:${OPTION}:deny=${VALUE}/jail"
|
||||
_rctl_rule_log="jail:${_jail}:${OPTION}:log=${VALUE}/jail"
|
||||
|
||||
## if entry doesn't exist, add; else show existing entry
|
||||
if ! grep -qs "${_rctl_rule}" "${bastille_jailsdir}/${_jail}/rctl.conf"; then
|
||||
# Check whether the entry already exists and, if so, update it. -- cwells
|
||||
if grep -qs "jail:${_jail}:${OPTION}:deny" "${bastille_jailsdir}/${_jail}/rctl.conf"; then
|
||||
_escaped_option=$(echo "${OPTION}" | sed 's/\//\\\//g')
|
||||
_escaped_rctl_rule=$(echo "${_rctl_rule}" | sed 's/\//\\\//g')
|
||||
sed -i '' -E "s/jail:${_jail}:${_escaped_option}:deny.+/${_escaped_rctl_rule}/" "${bastille_jailsdir}/${_jail}/rctl.conf"
|
||||
else # Just append the entry. -- cwells
|
||||
echo "${_rctl_rule}" >> "${bastille_jailsdir}/${_jail}/rctl.conf"
|
||||
echo "${_rctl_rule_log}" >> "${bastille_jailsdir}/${_jail}/rctl.conf"
|
||||
fi
|
||||
|
||||
echo -e "${OPTION} ${VALUE}"
|
||||
rctl -a "${_rctl_rule}"
|
||||
rctl -a "${_rctl_rule}" "${_rctl_rule_log}"
|
||||
echo -e "${COLOR_RESET}"
|
||||
done
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille list [-j] [release|template|(jail|container)|log|limit|(import|export|backup)].${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille list [-j] [release|template|(jail|container)|log|limit|(import|export|backup)]"
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille mount TARGET host_path container_path [filesystem_type options dump pass_number]${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille mount TARGET host_path container_path [filesystem_type options dump pass_number]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -45,18 +44,7 @@ esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET=$1
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
else
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
if [ $# -eq 2 ]; then
|
||||
elif [ $# -eq 2 ]; then
|
||||
_fstab="$@ nullfs ro 0 0"
|
||||
else
|
||||
_fstab="$@"
|
||||
@@ -71,38 +59,38 @@ _checks=$(echo "${_fstab}" | awk '{print $5" "$6}')
|
||||
|
||||
## if any variables are empty, bail out
|
||||
if [ -z "${_hostpath}" ] || [ -z "${_jailpath}" ] || [ -z "${_type}" ] || [ -z "${_perms}" ] || [ -z "${_checks}" ]; then
|
||||
echo -e "${COLOR_RED}FSTAB format not recognized.${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}Format: /host/path jail/path nullfs ro 0 0${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}Read: ${_fstab}${COLOR_RESET}"
|
||||
error_notify "FSTAB format not recognized."
|
||||
warn "Format: /host/path jail/path nullfs ro 0 0"
|
||||
warn "Read: ${_fstab}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## if host path doesn't exist or type is not "nullfs"
|
||||
if [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then
|
||||
echo -e "${COLOR_RED}Detected invalid host path or incorrect mount type in FSTAB.${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}Format: /host/path jail/path nullfs ro 0 0${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}Read: ${_fstab}${COLOR_RESET}"
|
||||
error_notify "Detected invalid host path or incorrect mount type in FSTAB."
|
||||
warn "Format: /host/path jail/path nullfs ro 0 0"
|
||||
warn "Read: ${_fstab}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## if mount permissions are not "ro" or "rw"
|
||||
if [ "${_perms}" != "ro" ] && [ "${_perms}" != "rw" ]; then
|
||||
echo -e "${COLOR_RED}Detected invalid mount permissions in FSTAB.${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}Format: /host/path jail/path nullfs ro 0 0${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}Read: ${_fstab}${COLOR_RESET}"
|
||||
error_notify "Detected invalid mount permissions in FSTAB."
|
||||
warn "Format: /host/path jail/path nullfs ro 0 0"
|
||||
warn "Read: ${_fstab}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## if check & pass are not "0 0 - 1 1"; bail out
|
||||
if [ "${_checks}" != "0 0" ] && [ "${_checks}" != "1 0" ] && [ "${_checks}" != "0 1" ] && [ "${_checks}" != "1 1" ]; then
|
||||
echo -e "${COLOR_RED}Detected invalid fstab options in FSTAB.${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}Format: /host/path jail/path nullfs ro 0 0${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}Read: ${_fstab}${COLOR_RESET}"
|
||||
error_notify "Detected invalid fstab options in FSTAB."
|
||||
warn "Format: /host/path jail/path nullfs ro 0 0"
|
||||
warn "Read: ${_fstab}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
|
||||
## aggregate variables into FSTAB entry
|
||||
_jailpath="${bastille_jailsdir}/${_jail}/root/${_jailpath}"
|
||||
@@ -111,16 +99,14 @@ for _jail in ${JAILS}; do
|
||||
## Create mount point if it does not exist. -- cwells
|
||||
if [ ! -d "${bastille_jailsdir}/${_jail}/root/${_jailpath}" ]; then
|
||||
if ! mkdir -p "${bastille_jailsdir}/${_jail}/root/${_jailpath}"; then
|
||||
echo -e "${COLOR_RED}Failed to create mount point inside jail.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Failed to create mount point inside jail."
|
||||
fi
|
||||
fi
|
||||
|
||||
## if entry doesn't exist, add; else show existing entry
|
||||
if ! egrep -q "[[:blank:]]${_jailpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then
|
||||
if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"; then
|
||||
echo -e "${COLOR_RED}Failed to create fstab entry: ${_fstab_entry}${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Failed to create fstab entry: ${_fstab_entry}"
|
||||
fi
|
||||
echo "Added: ${_fstab_entry}"
|
||||
else
|
||||
|
||||
@@ -28,11 +28,10 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille pkg TARGET command [args]${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille pkg TARGET command [args]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,22 +41,12 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
jexec -l "${_jail}" /usr/sbin/pkg "$@"
|
||||
echo
|
||||
done
|
||||
|
||||
@@ -25,12 +25,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille rdr TARGET [clear] | [list] | [tcp <host_port> <jail_port>] | [udp <host_port> <jail_port>]${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille rdr TARGET [clear] | [list] | [tcp <host_port> <jail_port>] | [udp <host_port> <jail_port>]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -49,35 +48,32 @@ shift
|
||||
|
||||
# Can only redirect to single jail
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
echo -e "${COLOR_RED}Can only redirect to single jail${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Can only redirect to a single jail."
|
||||
fi
|
||||
|
||||
# Check jail name valid
|
||||
JAIL_NAME=$(jls -j "${TARGET}" name 2>/dev/null)
|
||||
if [ -z "${JAIL_NAME}" ]; then
|
||||
echo -e "${COLOR_RED}Jail not found: ${TARGET}${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Jail not found: ${TARGET}"
|
||||
fi
|
||||
|
||||
# Check jail ip4 address valid
|
||||
JAIL_IP=$(jls -j "${TARGET}" ip4.addr 2>/dev/null)
|
||||
if [ -z "${JAIL_IP}" -o "${JAIL_IP}" = "-" ]; then
|
||||
echo -e "${COLOR_RED}Jail IP not found: ${TARGET}${COLOR_RESET}"
|
||||
exit 1
|
||||
if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then
|
||||
JAIL_IP=$(jls -j "${TARGET}" ip4.addr 2>/dev/null)
|
||||
if [ -z "${JAIL_IP}" -o "${JAIL_IP}" = "-" ]; then
|
||||
error_exit "Jail IP not found: ${TARGET}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check rdr-anchor is setup in pf.conf
|
||||
if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then
|
||||
echo -e "${COLOR_RED}rdr-anchor not found in pf.conf${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "rdr-anchor not found in pf.conf"
|
||||
fi
|
||||
|
||||
# Check ext_if is setup in pf.conf
|
||||
EXT_IF=$(grep '^[[:space:]]*ext_if[[:space:]]*=' /etc/pf.conf)
|
||||
if [ -z "${JAIL_NAME}" ]; then
|
||||
echo -e "${COLOR_RED}ext_if not defined in pf.conf${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ext_if not defined in pf.conf"
|
||||
fi
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
@@ -95,7 +91,7 @@ while [ $# -gt 0 ]; do
|
||||
usage
|
||||
fi
|
||||
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
|
||||
printf '%s\nrdr on $ext_if inet proto tcp to port %d -> %s port %d\n' "$EXT_IF" "$2" "$JAIL_IP" "$3" ) \
|
||||
printf '%s\nrdr on $ext_if inet proto tcp to port %s -> %s port %s\n' "$EXT_IF" "$2" "$JAIL_IP" "$3" ) \
|
||||
| pfctl -a "rdr/${JAIL_NAME}" -f-
|
||||
shift 3
|
||||
;;
|
||||
@@ -104,7 +100,7 @@ while [ $# -gt 0 ]; do
|
||||
usage
|
||||
fi
|
||||
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
|
||||
printf '%s\nrdr on $ext_if inet proto udp to port %d -> %s port %d\n' "$EXT_IF" "$2" "$JAIL_IP" "$3" ) \
|
||||
printf '%s\nrdr on $ext_if inet proto udp to port %s -> %s port %s\n' "$EXT_IF" "$2" "$JAIL_IP" "$3" ) \
|
||||
| pfctl -a "rdr/${JAIL_NAME}" -f-
|
||||
shift 3
|
||||
;;
|
||||
|
||||
@@ -28,25 +28,18 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille rename [TARGET] [NEW_NAME].${COLOR_RESET}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
error_notify() {
|
||||
# Notify message on error and exit
|
||||
echo -e "$*" >&2
|
||||
exit 1
|
||||
error_exit "Usage: bastille rename TARGET NEW_NAME"
|
||||
}
|
||||
|
||||
validate_name() {
|
||||
local NAME_VERIFY=${NEWNAME}
|
||||
local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')
|
||||
if [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then
|
||||
error_notify "${COLOR_RED}Container names may not contain special characters!${COLOR_RESET}"
|
||||
error_exit "Container names may not contain special characters!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -57,13 +50,11 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 2 ]; then
|
||||
if [ $# -ne 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
NEWNAME="${2}"
|
||||
shift
|
||||
NEWNAME="${1}"
|
||||
|
||||
update_jailconf() {
|
||||
# Update jail.conf
|
||||
@@ -97,43 +88,39 @@ update_fstab() {
|
||||
|
||||
change_name() {
|
||||
# Attempt container name change
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
echo -e "${COLOR_GREEN}Attempting to rename '${TARGET}' to ${NEWNAME}...${COLOR_RESET}"
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ] && [ -n "${bastille_zfs_prefix}" ]; then
|
||||
# Check and rename container ZFS dataset accordingly
|
||||
# Perform additional checks in case of non-zfs existing containers
|
||||
if zfs list | grep -qw "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}"; then
|
||||
if ! zfs rename -f "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}"; then
|
||||
error_notify "${COLOR_RED}Can't rename '${TARGET}' dataset.${COLOR_RESET}"
|
||||
fi
|
||||
else
|
||||
# Check and rename container directory instead
|
||||
if ! zfs list | grep -qw "jails/${TARGET}$"; then
|
||||
mv "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Check if container is a zfs/dataset before rename attempt
|
||||
# Perform additional checks in case of bastille.conf miss-configuration
|
||||
if zfs list | grep -qw "jails/${TARGET}$"; then
|
||||
ZFS_DATASET_ORIGIN=$(zfs list | grep -w "jails/${TARGET}$" | awk '{print $1}')
|
||||
ZFS_DATASET_TARGET=$(echo "${ZFS_DATASET_ORIGIN}" | sed "s|\/${TARGET}||")
|
||||
if [ -n "${ZFS_DATASET_ORIGIN}" ] && [ -n "${ZFS_DATASET_TARGET}" ]; then
|
||||
if ! zfs rename -f "${ZFS_DATASET_ORIGIN}" "${ZFS_DATASET_TARGET}/${NEWNAME}"; then
|
||||
error_notify "${COLOR_RED}Can't rename '${TARGET}' dataset.${COLOR_RESET}"
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}Can't determine the zfs origin path of '${TARGET}'.${COLOR_RESET}"
|
||||
info "Attempting to rename '${TARGET}' to ${NEWNAME}..."
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ] && [ -n "${bastille_zfs_prefix}" ]; then
|
||||
# Check and rename container ZFS dataset accordingly
|
||||
# Perform additional checks in case of non-ZFS existing containers
|
||||
if zfs list | grep -qw "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}"; then
|
||||
if ! zfs rename -f "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}"; then
|
||||
error_exit "Can't rename '${TARGET}' dataset."
|
||||
fi
|
||||
else
|
||||
# Just rename the jail directory
|
||||
mv "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
|
||||
# Check and rename container directory instead
|
||||
if ! zfs list | grep -qw "jails/${TARGET}$"; then
|
||||
mv "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
error_notify "${COLOR_RED}${TARGET} not found. See bootstrap.${COLOR_RESET}"
|
||||
# Check if container is a zfs/dataset before rename attempt
|
||||
# Perform additional checks in case of bastille.conf miss-configuration
|
||||
if zfs list | grep -qw "jails/${TARGET}$"; then
|
||||
ZFS_DATASET_ORIGIN=$(zfs list | grep -w "jails/${TARGET}$" | awk '{print $1}')
|
||||
ZFS_DATASET_TARGET=$(echo "${ZFS_DATASET_ORIGIN}" | sed "s|\/${TARGET}||")
|
||||
if [ -n "${ZFS_DATASET_ORIGIN}" ] && [ -n "${ZFS_DATASET_TARGET}" ]; then
|
||||
if ! zfs rename -f "${ZFS_DATASET_ORIGIN}" "${ZFS_DATASET_TARGET}/${NEWNAME}"; then
|
||||
error_exit "Can't rename '${TARGET}' dataset."
|
||||
fi
|
||||
else
|
||||
error_exit "Can't determine the ZFS origin path of '${TARGET}'."
|
||||
fi
|
||||
else
|
||||
# Just rename the jail directory
|
||||
mv "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Update jail configuration files accordingly
|
||||
@@ -142,22 +129,20 @@ change_name() {
|
||||
|
||||
# Check exit status and notify
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_notify "${COLOR_RED}An error has occurred while attempting to rename '${TARGET}'.${COLOR_RESET}"
|
||||
error_exit "An error has occurred while attempting to rename '${TARGET}'."
|
||||
else
|
||||
echo -e "${COLOR_GREEN}Renamed '${TARGET}' to '${NEWNAME}' successfully.${COLOR_RESET}"
|
||||
info "Renamed '${TARGET}' to '${NEWNAME}' successfully."
|
||||
fi
|
||||
}
|
||||
|
||||
## check if a running jail matches name or already exist
|
||||
if [ "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_notify "${COLOR_RED}Warning: ${TARGET} is running or the name does match.${COLOR_RESET}"
|
||||
elif [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
|
||||
error_notify "${COLOR_RED}Jail: ${NEWNAME} already exist.${COLOR_RESET}"
|
||||
fi
|
||||
|
||||
## validate jail name
|
||||
if [ -n "${NEWNAME}" ]; then
|
||||
validate_name
|
||||
fi
|
||||
|
||||
## check if a jail already exists with the new name
|
||||
if [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
|
||||
error_exit "Jail: ${NEWNAME} already exists."
|
||||
fi
|
||||
|
||||
change_name
|
||||
|
||||
@@ -28,11 +28,10 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille service TARGET service_name action${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille service TARGET service_name action"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,23 +41,12 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET=$1
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
jexec -l "${_jail}" /usr/sbin/service "$@"
|
||||
echo
|
||||
done
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille start TARGET${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille start TARGET"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -57,28 +56,37 @@ if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(bastille list jails | awk "/^${TARGET}$/")
|
||||
## check if exist
|
||||
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
echo -e "${COLOR_RED}[${TARGET}]: Not found.${COLOR_RESET}"
|
||||
error_exit "[${TARGET}]: Not found."
|
||||
fi
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
## test if running
|
||||
if [ "$(jls name | awk "/^${_jail}$/")" ]; then
|
||||
echo -e "${COLOR_RED}[${_jail}]: Already started.${COLOR_RESET}"
|
||||
error_notify "[${_jail}]: Already started."
|
||||
|
||||
## test if not running
|
||||
elif [ ! "$(jls name | awk "/^${_jail}$/")" ]; then
|
||||
# Verify that the configured interface exists. -- cwells
|
||||
if [ "$(bastille config $_jail get vnet)" != 'enabled' ]; then
|
||||
_interface=$(bastille config $_jail get interface)
|
||||
if ! ifconfig | grep "^${_interface}:" >/dev/null; then
|
||||
error_notify "Error: ${_interface} interface does not exist."
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
## warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry
|
||||
ip=$(grep 'ip4.addr' "${bastille_jailsdir}/${_jail}/jail.conf" | awk '{print $3}' | sed 's/\;//g')
|
||||
if [ -n "${ip}" ]; then
|
||||
if ifconfig | grep -w "${ip}" >/dev/null; then
|
||||
echo -e "${COLOR_RED}Error: IP address (${ip}) already in use.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_notify "Error: IP address (${ip}) already in use."
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
## start the container
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}"
|
||||
|
||||
## add rctl limits
|
||||
@@ -88,6 +96,13 @@ for _jail in ${JAILS}; do
|
||||
done < "${bastille_jailsdir}/${_jail}/rctl.conf"
|
||||
fi
|
||||
|
||||
## add rdr rules
|
||||
if [ -s "${bastille_jailsdir}/${_jail}/rdr.conf" ]; then
|
||||
while read _rules; do
|
||||
bastille rdr "${_jail}" ${_rules}
|
||||
done < "${bastille_jailsdir}/${_jail}/rdr.conf"
|
||||
fi
|
||||
|
||||
## add ip4.addr to firewall table:jails
|
||||
if [ -n "${bastille_network_loopback}" ]; then
|
||||
if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille stop TARGET${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille stop TARGET"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,26 +42,10 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -ne 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
## check if exist or not running
|
||||
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
echo -e "${COLOR_RED}[${TARGET}]: Not found.${COLOR_RESET}"
|
||||
elif [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
echo -e "${COLOR_RED}[${TARGET}]: Not started.${COLOR_RESET}"
|
||||
fi
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
## test if running
|
||||
if [ "$(jls name | awk "/^${_jail}$/")" ]; then
|
||||
@@ -72,6 +55,10 @@ for _jail in ${JAILS}; do
|
||||
pfctl -q -t jails -T delete "$(jls -j ${_jail} ip4.addr)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$(bastille rdr ${_jail} list)" ]; then
|
||||
bastille rdr ${_jail} clear
|
||||
fi
|
||||
|
||||
## remove rctl limits
|
||||
if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then
|
||||
@@ -81,7 +68,7 @@ for _jail in ${JAILS}; do
|
||||
fi
|
||||
|
||||
## stop container
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}"
|
||||
fi
|
||||
echo
|
||||
|
||||
@@ -28,11 +28,10 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille sysrc TARGET args${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille sysrc TARGET args"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,23 +41,12 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
jexec -l "${_jail}" /usr/sbin/sysrc "$@"
|
||||
echo -e "${COLOR_RESET}"
|
||||
done
|
||||
|
||||
@@ -28,12 +28,84 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
bastille_usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille template TARGET project/template.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille template TARGET|--convert project/template"
|
||||
}
|
||||
|
||||
post_command_hook() {
|
||||
_jail=$1
|
||||
_cmd=$2
|
||||
_args=$3
|
||||
|
||||
case $_cmd in
|
||||
rdr)
|
||||
if ! grep -qs "${_args}" "${bastille_jailsdir}/${_jail}/rdr.conf"; then
|
||||
echo "${_args}" >> "${bastille_jailsdir}/${_jail}/rdr.conf"
|
||||
fi
|
||||
echo -e ${_args}
|
||||
esac
|
||||
}
|
||||
|
||||
get_arg_name() {
|
||||
echo "${1}" | sed -E 's/=.*//'
|
||||
}
|
||||
|
||||
parse_arg_value() {
|
||||
# Parses the value after = and then escapes back/forward slashes and single quotes in it. -- cwells
|
||||
echo "${1}" | sed -E 's/[^=]+=?//' | sed -e 's/\\/\\\\/g' -e 's/\//\\\//g' -e 's/'\''/'\''\\'\'\''/g'
|
||||
}
|
||||
|
||||
get_arg_value() {
|
||||
_name_value_pair="${1}"
|
||||
shift
|
||||
_arg_name="$(get_arg_name "${_name_value_pair}")"
|
||||
|
||||
# Remaining arguments in $@ are the script arguments, which take precedence. -- cwells
|
||||
for _script_arg in "$@"; do
|
||||
case ${_script_arg} in
|
||||
--arg)
|
||||
# Parse whatever is next. -- cwells
|
||||
_next_arg='true' ;;
|
||||
*)
|
||||
if [ "${_next_arg}" = 'true' ]; then # This is the parameter after --arg. -- cwells
|
||||
_next_arg=''
|
||||
if [ "$(get_arg_name "${_script_arg}")" = "${_arg_name}" ]; then
|
||||
parse_arg_value "${_script_arg}"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check the ARG_FILE if one was provided. --cwells
|
||||
if [ -n "${ARG_FILE}" ]; then
|
||||
# To prevent a false empty value, only parse the value if this argument exists in the file. -- cwells
|
||||
if grep "^${_arg_name}=" "${ARG_FILE}" > /dev/null 2>&1; then
|
||||
parse_arg_value "$(grep "^${_arg_name}=" "${ARG_FILE}")"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# Return the default value, which may be empty, from the name=value pair. -- cwells
|
||||
parse_arg_value "${_name_value_pair}"
|
||||
}
|
||||
|
||||
render() {
|
||||
_file_path="${1}/${2}"
|
||||
if [ -d "${_file_path}" ]; then # Recursively render every file in this directory. -- cwells
|
||||
echo "Rendering Directory: ${_file_path}"
|
||||
find "${_file_path}" \( -type d -name .git -prune \) -o -type f
|
||||
find "${_file_path}" \( -type d -name .git -prune \) -o -type f -print0 | $(eval "xargs -0 sed -i '' ${ARG_REPLACEMENTS}")
|
||||
elif [ -f "${_file_path}" ]; then
|
||||
echo "Rendering File: ${_file_path}"
|
||||
eval "sed -i '' ${ARG_REPLACEMENTS} '${_file_path}'"
|
||||
else
|
||||
warn "Path not found for render: ${2}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,113 +115,218 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 2 ]; then
|
||||
if [ $# -lt 1 ]; then
|
||||
bastille_usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
## global variables
|
||||
TEMPLATE="${1}"
|
||||
shift
|
||||
bastille_template=${bastille_templatesdir}/${TEMPLATE}
|
||||
if [ -z "${HOOKS}" ]; then
|
||||
HOOKS='LIMITS INCLUDE PRE FSTAB PF PKG OVERLAY CONFIG SYSRC SERVICE CMD RENDER'
|
||||
fi
|
||||
|
||||
# Special case conversion of hook-style template files into a Bastillefile. -- cwells
|
||||
if [ "${TARGET}" = '--convert' ]; then
|
||||
if [ -d "${TEMPLATE}" ]; then # A relative path was provided. -- cwells
|
||||
cd "${TEMPLATE}"
|
||||
elif [ -d "${bastille_template}" ]; then
|
||||
cd "${bastille_template}"
|
||||
else
|
||||
error_exit "Template not found: ${TEMPLATE}"
|
||||
fi
|
||||
|
||||
echo "Converting template: ${TEMPLATE}"
|
||||
|
||||
HOOKS="ARG ${HOOKS}"
|
||||
for _hook in ${HOOKS}; do
|
||||
if [ -s "${_hook}" ]; then
|
||||
# Default command is the hook name and default args are the line from the file. -- cwells
|
||||
_cmd="${_hook}"
|
||||
_args_template='${_line}'
|
||||
|
||||
# Replace old hook names with Bastille command names. -- cwells
|
||||
case ${_hook} in
|
||||
CONFIG|OVERLAY)
|
||||
_cmd='CP'
|
||||
_args_template='${_line} /'
|
||||
;;
|
||||
FSTAB)
|
||||
_cmd='MOUNT' ;;
|
||||
PF)
|
||||
_cmd='RDR' ;;
|
||||
PRE)
|
||||
_cmd='CMD' ;;
|
||||
esac
|
||||
|
||||
while read _line; do
|
||||
if [ -z "${_line}" ]; then
|
||||
continue
|
||||
fi
|
||||
eval "_args=\"${_args_template}\""
|
||||
echo "${_cmd} ${_args}" >> Bastillefile
|
||||
done < "${_hook}"
|
||||
echo '' >> Bastillefile
|
||||
rm "${_hook}"
|
||||
fi
|
||||
done
|
||||
|
||||
info "Template converted: ${TEMPLATE}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case ${TEMPLATE} in
|
||||
http?://github.com/*/*|http?://gitlab.com/*/*)
|
||||
TEMPLATE_DIR=$(echo "${TEMPLATE}" | awk -F / '{ print $4 "/" $5 }')
|
||||
if [ ! -d "${bastille_templatesdir}/${TEMPLATE_DIR}" ]; then
|
||||
echo -e "${COLOR_GREEN}Bootstrapping ${TEMPLATE}...${COLOR_RESET}"
|
||||
info "Bootstrapping ${TEMPLATE}..."
|
||||
if ! bastille bootstrap "${TEMPLATE}"; then
|
||||
echo -e "${COLOR_RED}Failed to bootstrap template: ${TEMPLATE}.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Failed to bootstrap template: ${TEMPLATE}"
|
||||
fi
|
||||
fi
|
||||
TEMPLATE="${TEMPLATE_DIR}"
|
||||
bastille_template=${bastille_templatesdir}/${TEMPLATE}
|
||||
;;
|
||||
*/*)
|
||||
if [ ! -d "${bastille_templatesdir}/${TEMPLATE}" ]; then
|
||||
echo -e "${COLOR_RED}${TEMPLATE} not found.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "${TEMPLATE} not found."
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo -e "${COLOR_RED}Template name/URL not recognized.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Template name/URL not recognized."
|
||||
esac
|
||||
|
||||
if [ -z "${JAILS}" ]; then
|
||||
echo -e "${COLOR_RED}Container ${TARGET} is not running.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Container ${TARGET} is not running."
|
||||
fi
|
||||
|
||||
if [ -z "${HOOKS}" ]; then
|
||||
HOOKS='LIMITS INCLUDE PRE FSTAB PF PKG OVERLAY CONFIG SYSRC SERVICE CMD'
|
||||
# Check for an --arg-file parameter. -- cwells
|
||||
for _script_arg in "$@"; do
|
||||
case ${_script_arg} in
|
||||
--arg-file)
|
||||
# Parse whatever is next. -- cwells
|
||||
_next_arg='true' ;;
|
||||
*)
|
||||
if [ "${_next_arg}" = 'true' ]; then # This is the parameter after --arg-file. -- cwells
|
||||
_next_arg=''
|
||||
ARG_FILE="${_script_arg}"
|
||||
break
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "${ARG_FILE}" ] && [ ! -f "${ARG_FILE}" ]; then
|
||||
error_exit "File not found: ${ARG_FILE}"
|
||||
fi
|
||||
|
||||
## global variables
|
||||
bastille_template=${bastille_templatesdir}/${TEMPLATE}
|
||||
for _jail in ${JAILS}; do
|
||||
info "[${_jail}]:"
|
||||
info "Applying template: ${TEMPLATE}..."
|
||||
|
||||
## jail-specific variables.
|
||||
bastille_jail_path=$(jls -j "${_jail}" path)
|
||||
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}Applying template: ${TEMPLATE}...${COLOR_RESET}"
|
||||
if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then
|
||||
_jail_ip=$(jls -j "${_jail}" ip4.addr 2>/dev/null)
|
||||
if [ -z "${_jail_ip}" -o "${_jail_ip}" = "-" ]; then
|
||||
error_notify "Jail IP not found: ${_jail}"
|
||||
_jail_ip='' # In case it was -. -- cwells
|
||||
fi
|
||||
fi
|
||||
|
||||
## TARGET
|
||||
if [ -s "${bastille_template}/TARGET" ]; then
|
||||
if grep -qw "${_jail}" "${bastille_template}/TARGET"; then
|
||||
echo -e "${COLOR_GREEN}TARGET: !${_jail}.${COLOR_RESET}"
|
||||
info "TARGET: !${_jail}."
|
||||
echo
|
||||
continue
|
||||
fi
|
||||
if ! grep -Eq "(^|\b)(${_jail}|ALL)($|\b)" "${bastille_template}/TARGET"; then
|
||||
echo -e "${COLOR_GREEN}TARGET: ?${_jail}.${COLOR_RESET}"
|
||||
info "TARGET: ?${_jail}."
|
||||
echo
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build a list of sed commands like this: -e 's/${username}/root/g' -e 's/${domain}/example.com/g'
|
||||
# Values provided by default (without being defined by the user) are listed here. -- cwells
|
||||
ARG_REPLACEMENTS="-e 's/\${JAIL_IP}/${_jail_ip}/g' -e 's/\${JAIL_NAME}/${_jail}/g'"
|
||||
# This is parsed outside the HOOKS loop so an ARG file can be used with a Bastillefile. -- cwells
|
||||
if [ -s "${bastille_template}/ARG" ]; then
|
||||
while read _line; do
|
||||
if [ -z "${_line}" ]; then
|
||||
continue
|
||||
fi
|
||||
_arg_name=$(get_arg_name "${_line}")
|
||||
_arg_value=$(get_arg_value "${_line}" "$@")
|
||||
if [ -z "${_arg_value}" ]; then
|
||||
warn "No value provided for arg: ${_arg_name}"
|
||||
fi
|
||||
ARG_REPLACEMENTS="${ARG_REPLACEMENTS} -e 's/\${${_arg_name}}/${_arg_value}/g'"
|
||||
done < "${bastille_template}/ARG"
|
||||
fi
|
||||
|
||||
if [ -s "${bastille_template}/Bastillefile" ]; then
|
||||
# Ignore blank lines and comments. -- cwells
|
||||
SCRIPT=$(grep -v '^\s*$' "${bastille_template}/Bastillefile" | grep -v '^\s*#')
|
||||
SCRIPT=$(grep -v '^[[:blank:]]*$' "${bastille_template}/Bastillefile" | grep -v '^[[:blank:]]*#')
|
||||
# Use a newline as the separator. -- cwells
|
||||
IFS='
|
||||
'
|
||||
set -f
|
||||
for _line in ${SCRIPT}; do
|
||||
# First word converted to lowercase is the Bastille command. -- cwells
|
||||
_cmd=$(echo "${_line}" | awk '{print tolower($1);}')
|
||||
_args=$(echo "${_line}" | awk '{$1=""; sub(/^ */, ""); print;}')
|
||||
# Rest of the line with "arg" variables replaced will be the arguments. -- cwells
|
||||
_args=$(echo "${_line}" | awk '{$1=""; sub(/^ */, ""); print;}' | eval "sed ${ARG_REPLACEMENTS}")
|
||||
|
||||
# Apply overrides for commands/aliases and arguments. -- cwells
|
||||
case $_cmd in
|
||||
arg) # This is a template argument definition. -- cwells
|
||||
_arg_name=$(get_arg_name "${_args}")
|
||||
_arg_value=$(get_arg_value "${_args}" "$@")
|
||||
if [ -z "${_arg_value}" ]; then
|
||||
warn "No value provided for arg: ${_arg_name}"
|
||||
fi
|
||||
# Build a list of sed commands like this: -e 's/${username}/root/g' -e 's/${domain}/example.com/g'
|
||||
ARG_REPLACEMENTS="${ARG_REPLACEMENTS} -e 's/\${${_arg_name}}/${_arg_value}/g'"
|
||||
continue
|
||||
;;
|
||||
cmd)
|
||||
# Escape single-quotes in the command being executed. -- cwells
|
||||
_args=$(echo "${_args}" | sed "s/'/'\\\\''/g")
|
||||
# Allow redirection within the jail. -- cwells
|
||||
_args="sh -c '${_args}'"
|
||||
;;
|
||||
cp)
|
||||
cp|copy)
|
||||
_cmd='cp'
|
||||
# Convert relative "from" path into absolute path inside the template directory. -- cwells
|
||||
if [ "${_args%${_args#?}}" != '/' ]; then
|
||||
if [ "${_args%${_args#?}}" != '/' ] && [ "${_args%${_args#??}}" != '"/' ]; then
|
||||
_args="${bastille_template}/${_args}"
|
||||
fi
|
||||
;;
|
||||
fstab|mount)
|
||||
_cmd='mount' ;;
|
||||
include)
|
||||
_cmd='template' ;;
|
||||
overlay)
|
||||
_cmd='cp'
|
||||
_args="${bastille_template}/${_args} /"
|
||||
;;
|
||||
pkg)
|
||||
_args="install -y ${_args}" ;;
|
||||
render) # This is a path to one or more files needing arguments replaced by values. -- cwells
|
||||
render "${bastille_jail_path}" "${_args}"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
if ! eval "bastille ${_cmd} ${_jail} ${_args}"; then
|
||||
echo -e "${COLOR_RED}Failed to execute command: ${BASTILLE_COMMAND}${COLOR_RESET}"
|
||||
set +f
|
||||
unset IFS
|
||||
exit 1
|
||||
error_exit "Failed to execute command: ${_cmd}"
|
||||
fi
|
||||
|
||||
post_command_hook "${_jail}" "${_cmd}" "${_args}"
|
||||
done
|
||||
set +f
|
||||
unset IFS
|
||||
@@ -157,14 +334,14 @@ for _jail in ${JAILS}; do
|
||||
|
||||
for _hook in ${HOOKS}; do
|
||||
if [ -s "${bastille_template}/${_hook}" ]; then
|
||||
# Default command is the lowercase hook name and default args are the line from the file. -- cwells
|
||||
_cmd=$(echo "${_hook}" | awk '{print tolower($1);}')
|
||||
# Default command is the lowercase hook name and default args are the line from the file. -- cwells
|
||||
_cmd=$(echo "${_hook}" | awk '{print tolower($1);}')
|
||||
_args_template='${_line}'
|
||||
|
||||
# Override default command/args for some hooks. -- cwells
|
||||
case ${_hook} in
|
||||
CONFIG)
|
||||
echo -e "${COLOR_YELLOW}CONFIG deprecated; rename to OVERLAY.${COLOR_RESET}"
|
||||
warn "CONFIG deprecated; rename to OVERLAY."
|
||||
_args_template='${bastille_template}/${_line} /'
|
||||
_cmd='cp' ;;
|
||||
FSTAB)
|
||||
@@ -175,13 +352,17 @@ for _jail in ${JAILS}; do
|
||||
_args_template='${bastille_template}/${_line} /'
|
||||
_cmd='cp' ;;
|
||||
PF)
|
||||
echo -e "${COLOR_GREEN}NOT YET IMPLEMENTED.${COLOR_RESET}"
|
||||
info "NOT YET IMPLEMENTED."
|
||||
continue ;;
|
||||
PRE)
|
||||
_cmd='cmd' ;;
|
||||
RENDER) # This is a path to one or more files needing arguments replaced by values. -- cwells
|
||||
render "${bastille_jail_path}" "${_line}"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${_hook} -- START${COLOR_RESET}"
|
||||
info "[${_jail}]:${_hook} -- START"
|
||||
if [ "${_hook}" = 'CMD' ] || [ "${_hook}" = 'PRE' ]; then
|
||||
bastille cmd "${_jail}" /bin/sh < "${bastille_template}/${_hook}" || exit 1
|
||||
elif [ "${_hook}" = 'PKG' ]; then
|
||||
@@ -189,18 +370,20 @@ for _jail in ${JAILS}; do
|
||||
bastille pkg "${_jail}" audit -F
|
||||
else
|
||||
while read _line; do
|
||||
if [ -z "${_line}" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ -z "${_line}" ]; then
|
||||
continue
|
||||
fi
|
||||
# Replace "arg" variables in this line with the provided values. -- cwells
|
||||
_line=$(echo "${_line}" | eval "sed ${ARG_REPLACEMENTS}")
|
||||
eval "_args=\"${_args_template}\""
|
||||
bastille "${_cmd}" "${_jail}" ${_args} || exit 1
|
||||
done < "${bastille_template}/${_hook}"
|
||||
fi
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${_hook} -- END${COLOR_RESET}"
|
||||
info "[${_jail}]:${_hook} -- END"
|
||||
echo
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e "${COLOR_GREEN}Template complete.${COLOR_RESET}"
|
||||
info "Template applied: ${TEMPLATE}"
|
||||
echo
|
||||
done
|
||||
|
||||
11
usr/local/share/bastille/templates/default/base/Bastillefile
Normal file
11
usr/local/share/bastille/templates/default/base/Bastillefile
Normal file
@@ -0,0 +1,11 @@
|
||||
ARG HOST_RESOLV_CONF=/etc/resolv.conf
|
||||
|
||||
CMD touch /etc/rc.conf
|
||||
SYSRC syslogd_flags="-ss"
|
||||
SYSRC sendmail_enable="NO"
|
||||
SYSRC sendmail_submit_enable="NO"
|
||||
SYSRC sendmail_outbound_enable="NO"
|
||||
SYSRC sendmail_msp_queue_enable="NO"
|
||||
SYSRC cron_flags="-J 60"
|
||||
|
||||
CP "${HOST_RESOLV_CONF}" etc/resolv.conf
|
||||
@@ -0,0 +1,4 @@
|
||||
ARG BASE_TEMPLATE=default/base
|
||||
ARG HOST_RESOLV_CONF=/etc/resolv.conf
|
||||
|
||||
INCLUDE ${BASE_TEMPLATE} --arg HOST_RESOLV_CONF="${HOST_RESOLV_CONF}"
|
||||
@@ -0,0 +1,4 @@
|
||||
ARG BASE_TEMPLATE=default/base
|
||||
ARG HOST_RESOLV_CONF=/etc/resolv.conf
|
||||
|
||||
INCLUDE ${BASE_TEMPLATE} --arg HOST_RESOLV_CONF="${HOST_RESOLV_CONF}"
|
||||
13
usr/local/share/bastille/templates/default/vnet/Bastillefile
Normal file
13
usr/local/share/bastille/templates/default/vnet/Bastillefile
Normal file
@@ -0,0 +1,13 @@
|
||||
ARG BASE_TEMPLATE=default/base
|
||||
ARG HOST_RESOLV_CONF=/etc/resolv.conf
|
||||
|
||||
INCLUDE ${BASE_TEMPLATE} --arg HOST_RESOLV_CONF="${HOST_RESOLV_CONF}"
|
||||
|
||||
ARG EPAIR
|
||||
ARG GATEWAY
|
||||
ARG IFCONFIG="SYNCDHCP"
|
||||
|
||||
SYSRC ifconfig_${EPAIR}_name=vnet0
|
||||
SYSRC ifconfig_vnet0="${IFCONFIG}"
|
||||
# GATEWAY will be empty for a DHCP config. -- cwells
|
||||
CMD if [ -n "${GATEWAY}" ]; then /usr/sbin/sysrc defaultrouter="${GATEWAY}"; fi
|
||||
@@ -28,11 +28,10 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille top TARGET${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille top TARGET"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,23 +41,12 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -ne 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
jexec -l "${_jail}" /usr/bin/top
|
||||
echo -e "${COLOR_RESET}"
|
||||
done
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille umount TARGET container_path${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille umount TARGET container_path"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,42 +42,29 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
if [ $# -ne 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET=$1
|
||||
shift
|
||||
|
||||
MOUNT_PATH=$1
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
else
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
|
||||
_jailpath="${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH}"
|
||||
|
||||
if [ ! -d "${_jailpath}" ]; then
|
||||
echo -e "${COLOR_RED}The specified mount point does not exist inside the jail.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "The specified mount point does not exist inside the jail."
|
||||
fi
|
||||
|
||||
# Unmount the volume. -- cwells
|
||||
if ! umount "${_jailpath}"; then
|
||||
echo -e "${COLOR_RED}Failed to unmount volume: ${MOUNT_PATH}${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Failed to unmount volume: ${MOUNT_PATH}"
|
||||
fi
|
||||
|
||||
# Remove the entry from fstab so it is not automounted in the future. -- cwells
|
||||
if ! sed -E -i '' "\, +${_jailpath} +,d" "${bastille_jailsdir}/${_jail}/fstab"; then
|
||||
echo -e "${COLOR_RED}Failed to delete fstab entry: ${_fstab_entry}${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Failed to delete fstab entry: ${_fstab_entry}"
|
||||
fi
|
||||
|
||||
echo "Unmounted: ${MOUNT_PATH}"
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille update [release|container].${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille update [release|container] | [option]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,46 +42,72 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
OPTION="${2}"
|
||||
|
||||
# Handle options
|
||||
case "${OPTION}" in
|
||||
-f|--force)
|
||||
OPTION="-F"
|
||||
;;
|
||||
*)
|
||||
OPTION=
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check for unsupported actions
|
||||
if [ "${TARGET}" = "ALL" ]; then
|
||||
error_exit "Batch upgrade is unsupported."
|
||||
fi
|
||||
|
||||
if freebsd-version | grep -qi HBSD; then
|
||||
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Not yet supported on HardenedBSD."
|
||||
fi
|
||||
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
if ! grep -qw ".bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
|
||||
if [ "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
# Update a thick container.
|
||||
CURRENT_VERSION=$(/usr/sbin/jexec -l "${TARGET}" freebsd-version 2>/dev/null)
|
||||
if [ -z "${CURRENT_VERSION}" ]; then
|
||||
echo -e "${COLOR_RED}Can't determine '${TARGET}' version.${COLOR_RESET}"
|
||||
exit 1
|
||||
else
|
||||
env PAGER="/bin/cat" freebsd-update --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" \
|
||||
fetch install --currently-running "${CURRENT_VERSION}"
|
||||
fi
|
||||
else
|
||||
echo -e "${COLOR_RED}${TARGET} is not running.${COLOR_RESET}"
|
||||
echo -e "${COLOR_RED}See 'bastille start ${TARGET}'.${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
jail_check() {
|
||||
# Check if the jail is thick and is running
|
||||
if [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'."
|
||||
else
|
||||
echo -e "${COLOR_RED}${TARGET} is not a thick container.${COLOR_RESET}"
|
||||
exit 1
|
||||
if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
|
||||
error_exit "${TARGET} is not a thick container."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
}
|
||||
|
||||
jail_update() {
|
||||
# Update a thick container
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
jail_check
|
||||
CURRENT_VERSION=$(/usr/sbin/jexec -l "${TARGET}" freebsd-version 2>/dev/null)
|
||||
if [ -z "${CURRENT_VERSION}" ]; then
|
||||
error_exit "Can't determine '${TARGET}' version."
|
||||
else
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" \
|
||||
fetch install --currently-running "${CURRENT_VERSION}"
|
||||
fi
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
release_update() {
|
||||
# Update a release base(affects child containers)
|
||||
if [ -d "${bastille_releasesdir}/${TARGET}" ]; then
|
||||
# Update container base(affects child containers).
|
||||
env PAGER="/bin/cat" freebsd-update --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" \
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" \
|
||||
fetch install --currently-running "${TARGET}"
|
||||
else
|
||||
echo -e "${COLOR_RED}${TARGET} not found. See bootstrap.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
# Check what we should update
|
||||
if echo "${TARGET}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then
|
||||
release_update
|
||||
else
|
||||
jail_update
|
||||
fi
|
||||
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille upgrade release newrelease.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille upgrade release newrelease | target newrelease | target install | [option]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,23 +42,90 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 2 ]; then
|
||||
if [ $# -gt 3 ] || [ $# -lt 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
RELEASE="$1"
|
||||
shift
|
||||
NEWRELEASE="$1"
|
||||
TARGET="$1"
|
||||
NEWRELEASE="$2"
|
||||
OPTION="$3"
|
||||
|
||||
# Check for unsupported actions
|
||||
if [ "${TARGET}" = "ALL" ]; then
|
||||
error_exit "Batch upgrade is unsupported."
|
||||
fi
|
||||
|
||||
if freebsd-version | grep -qi HBSD; then
|
||||
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Not yet supported on HardenedBSD."
|
||||
fi
|
||||
|
||||
# Handle options
|
||||
case "${OPTION}" in
|
||||
-f|--force)
|
||||
OPTION="-F"
|
||||
;;
|
||||
*)
|
||||
OPTION=
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" -r "${NEWRELEASE}" upgrade
|
||||
jail_check() {
|
||||
# Check if the jail is thick and is running
|
||||
if [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'."
|
||||
else
|
||||
if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
|
||||
error_exit "${TARGET} is not a thick container."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
release_check() {
|
||||
# Validate the release
|
||||
if ! echo "${NEWRELEASE}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then
|
||||
error_exit "${NEWRELEASE} is not a valid release."
|
||||
fi
|
||||
}
|
||||
|
||||
release_upgrade() {
|
||||
# Upgrade a release
|
||||
if [ -d "${bastille_releasesdir}/${TARGET}" ]; then
|
||||
release_check
|
||||
freebsd-update ${OPTION} -b "${bastille_releasesdir}/${TARGET}" -r "${NEWRELEASE}" upgrade
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
jail_upgrade() {
|
||||
# Upgrade a thick container
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
jail_check
|
||||
release_check
|
||||
CURRENT_VERSION=$(jexec -l ${TARGET} freebsd-version)
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" --currently-running "${CURRENT_VERSION}" -r ${NEWRELEASE} upgrade
|
||||
echo
|
||||
echo -e "${COLOR_YELLOW}Please run 'bastille upgrade ${TARGET} install' to finish installing updates.${COLOR_RESET}"
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
jail_updates_install() {
|
||||
# Finish installing upgrade on a thick container
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
jail_check
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" install
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
# Check what we should upgrade
|
||||
if echo "${TARGET}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then
|
||||
release_upgrade
|
||||
elif [ "${NEWRELEASE}" = "install" ]; then
|
||||
jail_updates_install
|
||||
else
|
||||
echo -e "${COLOR_RED}${RELEASE} not found. See bootstrap.${COLOR_RESET}"
|
||||
exit 1
|
||||
jail_upgrade
|
||||
fi
|
||||
|
||||
@@ -28,25 +28,22 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
bastille_usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille verify [release|template].${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille verify [release|template]"
|
||||
}
|
||||
|
||||
verify_release() {
|
||||
if freebsd-version | grep -qi HBSD; then
|
||||
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Not yet supported on HardenedBSD."
|
||||
fi
|
||||
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" --currently-running "${RELEASE}" IDS
|
||||
else
|
||||
echo -e "${COLOR_RED}${RELEASE} not found. See bootstrap.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "${RELEASE} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -54,28 +51,26 @@ verify_template() {
|
||||
_template_path=${bastille_templatesdir}/${BASTILLE_TEMPLATE}
|
||||
_hook_validate=0
|
||||
|
||||
for _hook in TARGET INCLUDE PRE OVERLAY FSTAB PF PKG SYSRC SERVICE CMD; do
|
||||
for _hook in TARGET INCLUDE PRE OVERLAY FSTAB PF PKG SYSRC SERVICE CMD Bastillefile; do
|
||||
_path=${_template_path}/${_hook}
|
||||
if [ -s "${_path}" ]; then
|
||||
_hook_validate=$((_hook_validate+1))
|
||||
echo -e "${COLOR_GREEN}Detected ${_hook} hook.${COLOR_RESET}"
|
||||
info "Detected ${_hook} hook."
|
||||
|
||||
## line count must match newline count
|
||||
if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c $'\n' "${_path}") ]; then
|
||||
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
|
||||
echo -e "${COLOR_RED}${BASTILLE_TEMPLATE}:${_hook} [failed].${COLOR_RESET}"
|
||||
echo -e "${COLOR_RED}Line numbers don't match line breaks.${COLOR_RESET}"
|
||||
info "[${_hook}]:"
|
||||
error_notify "${BASTILLE_TEMPLATE}:${_hook} [failed]."
|
||||
error_notify "Line numbers don't match line breaks."
|
||||
echo
|
||||
echo -e "${COLOR_RED}Template validation failed.${COLOR_RESET}"
|
||||
exit 1
|
||||
|
||||
error_exit "Template validation failed."
|
||||
## if INCLUDE; recursive verify
|
||||
elif [ ${_hook} = 'INCLUDE' ]; then
|
||||
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
|
||||
info "[${_hook}]:"
|
||||
cat "${_path}"
|
||||
echo
|
||||
while read _include; do
|
||||
echo -e "${COLOR_GREEN}[${_hook}]:[${_include}]:${COLOR_RESET}"
|
||||
info "[${_hook}]:[${_include}]:"
|
||||
|
||||
case ${_include} in
|
||||
http?://github.com/*/*|http?://gitlab.com/*/*)
|
||||
@@ -87,19 +82,18 @@ verify_template() {
|
||||
bastille verify "${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO}"
|
||||
;;
|
||||
*)
|
||||
echo -e "${COLOR_RED}Template INCLUDE content not recognized.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Template INCLUDE content not recognized."
|
||||
;;
|
||||
esac
|
||||
done < "${_path}"
|
||||
|
||||
## if tree; tree -a bastille_template/_dir
|
||||
elif [ ${_hook} = 'OVERLAY' ]; then
|
||||
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
|
||||
info "[${_hook}]:"
|
||||
cat "${_path}"
|
||||
echo
|
||||
while read _dir; do
|
||||
echo -e "${COLOR_GREEN}[${_hook}]:[${_dir}]:${COLOR_RESET}"
|
||||
info "[${_hook}]:[${_dir}]:"
|
||||
if [ -x /usr/local/bin/tree ]; then
|
||||
/usr/local/bin/tree -a "${_template_path}/${_dir}"
|
||||
else
|
||||
@@ -108,7 +102,7 @@ verify_template() {
|
||||
echo
|
||||
done < "${_path}"
|
||||
else
|
||||
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
|
||||
info "[${_hook}]:"
|
||||
cat "${_path}"
|
||||
echo
|
||||
fi
|
||||
@@ -117,15 +111,15 @@ verify_template() {
|
||||
|
||||
## remove bad templates
|
||||
if [ ${_hook_validate} -lt 1 ]; then
|
||||
echo -e "${COLOR_RED}No valid template hooks found.${COLOR_RESET}"
|
||||
echo -e "${COLOR_RED}Template discarded.${COLOR_RESET}"
|
||||
error_notify "No valid template hooks found."
|
||||
error_notify "Template discarded."
|
||||
rm -rf "${bastille_template}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## if validated; ready to use
|
||||
if [ ${_hook_validate} -gt 0 ]; then
|
||||
echo -e "${COLOR_GREEN}Template ready to use.${COLOR_RESET}"
|
||||
info "Template ready to use."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -28,17 +28,16 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille zfs TARGET [set|get|snap] [key=value|date]'${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille zfs TARGET [set|get|snap] [key=value|date]'"
|
||||
}
|
||||
|
||||
zfs_snapshot() {
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
|
||||
echo
|
||||
done
|
||||
@@ -46,7 +45,7 @@ done
|
||||
|
||||
zfs_set_value() {
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
zfs "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
|
||||
echo
|
||||
done
|
||||
@@ -54,7 +53,7 @@ done
|
||||
|
||||
zfs_get_value() {
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
zfs get "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
|
||||
echo
|
||||
done
|
||||
@@ -62,7 +61,7 @@ done
|
||||
|
||||
zfs_disk_usage() {
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
zfs list -t all -o name,used,avail,refer,mountpoint,compress,ratio -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
|
||||
echo
|
||||
done
|
||||
@@ -77,44 +76,29 @@ esac
|
||||
|
||||
## check ZFS enabled
|
||||
if [ ! "${bastille_zfs_enable}" = "YES" ]; then
|
||||
echo -e "${COLOR_RED}ZFS not enabled.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ZFS not enabled."
|
||||
fi
|
||||
|
||||
## check zpool defined
|
||||
if [ -z "${bastille_zfs_zpool}" ]; then
|
||||
echo -e "${COLOR_RED}ZFS zpool not defined.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ZFS zpool not defined."
|
||||
fi
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | awk "/^${TARGET}$/")
|
||||
fi
|
||||
|
||||
case "$2" in
|
||||
case "$1" in
|
||||
set)
|
||||
ATTRIBUTE=$3
|
||||
JAILS=${JAILS}
|
||||
ATTRIBUTE=$2
|
||||
zfs_set_value
|
||||
;;
|
||||
get)
|
||||
ATTRIBUTE=$3
|
||||
JAILS=${JAILS}
|
||||
ATTRIBUTE=$2
|
||||
zfs_get_value
|
||||
;;
|
||||
snap|snapshot)
|
||||
TAG=$3
|
||||
JAILS=${JAILS}
|
||||
TAG=$2
|
||||
zfs_snapshot
|
||||
;;
|
||||
df|usage)
|
||||
|
||||
Reference in New Issue
Block a user