shanemcc / pxe-manager Goto Github PK
View Code? Open in Web Editor NEWVery simple web-app for managing PXE Boot environments.
License: Other
Very simple web-app for managing PXE Boot environments.
License: Other
Hi Shane,
Please can you look at adding API support to allow automated creation of server deployment images.
Ideally authentication would be required/supported.
Thanks!
Dom
It would be nice to have some kind of Bootable Image extending.
For example, start with "CentOS" image, then create a "CentOS + Plesk" image that extends from the base image.
Any changes to "CentOS" would be reflected in "CentOS + Plesk"
Allow specifying regexes to ensure that string's match a valid format.
Hello @ShaneMcC, thanks for this awesome project which i really like. I was used to Foreman but even though I really enjoy working with it, it's way to heavy for use just as a kickstart generator.
So I'm considering using pxe-manager, which is nice and pretty easy to use for simple uses cases, though, I think some improvements would benefit the community.
It'll be really nice if custom global variables could be added to pxe-manger.
Being able to create a global variable which can then be used in different image templates or servers without the need of recreating it every time in each template will be very useful.
Also, if you can add password type in normal variables definitions, that would be great, especially for password entries.
And speaking of password, at least for kickstart, it'll be great to have a input where you enter clear password and it'll then be encrypted for kickstart file instead of doing it manually in the terminal with openssl passwd -6
Currently it looks like only LoginAuthProvider (of which others inherit from) looks at $config['authProvider']['default']
- all auth providers should look at this for unauthenticated users.
I'm running pxe-manager in docker using the main Dockerfile from this depot, and although everything seems to be running fine, when I create a new image nothing is saved, and my image list stays empty.
There are no error messages in logs or anything, so I'm not sure what's going wrong.
I tried with and without mapping /var/lib/tftpboot
and /pxemanager/data
to a local folder, same result.
any ideas of what's going on or how I could debug this?
Most routes with periods in (such as those with /api/0.1
, or .json
) don't escape the .
character, meaning anything is valid.
How can i add an image? Where should i put files?
AuthProvider that auths against LDAP.
Permissions should come from LDAP Groups.
This cool bug means that the image routes with (.json)? at the end don't get their arguments parsed properly.
You could probably work around it by defining separate JSON routes, but it might be worth just documenting that it needs PHP <7.4 and updating the Dockerfile accordingly?
Hi,
due to the use of iPXE and being the only bootp bin used in our environment, routes needed some adjustment.
In the iPXE embedded script I have set the following:
:net0
isset ${net0/mac} || goto no_nic
dhcp net0 || goto net1
chain http://${next-server}:80/pxe/pxedata/${net0/mac} || goto net1
So in order for the machine to boot whenever it is set to first boot on the Network card, I had to enable the pxe-manager option allowInsecurePXEData
However, when the machine is already provisioned and disabled in pxe-manager, the machine will always get the pxedata which will then be used to re-provision the machine. In order to avoid this infinite loop, I edit the php code to src/routes/ServerRoutes.php
and added a new if condition $server->getEnabled() == true
if ($this->config['allowInsecurePXEData']) {
$router->get('/pxedata/([^/]+)', function($macaddr) use ($router, $displayEngine, $api) {
$server = $api->getServerFromMAC($macaddr);
if (!($server instanceof Server)) { return $this->showUnknown($displayEngine); }
$image = $server->getBootableImage();
if ($image instanceof BootableImage && $server->getEnabled() == true) {
$api->createServerLog($serverid, 'SYSTEM', 'insecure pxedata accessed by ' . getUserInfoString());
die($server->getDisplayEngine()->render($image->getID() . '/pxedata'));
} else {
die();
}
});
}
I also added this trick to other routes so data could only be retrieved when the machine is enabled for provisioning. Which is, IMO a bit more secure in the end.
Hope it helps
PHP Fatal error: Uncaught PDOException: could not find driver in /var/www/pxe-manager/functions.php:15\nStack trace:\n#0 /var/www/pxe-manager/functions.php(15): PDO->__construct('sqlite:/var/www...')\n#1 /var/www/pxe-manager/public/index.php(2): require_once('/var/www/pxe-ma...')\n#2 {main}\n thrown in /var/www/pxe-manager/functions.php on line 15
Add a "none" variable type.
This should hide the variable from the server page. Anything provided in the "Data" section would be passed as the variable content if the variable gets accessed.
This would mainly be used by child-templates to deal with inheritance where variables are inherited that are not used/needed by the child. (Eg if it is only extending the post-install script, but the parent image requires variables for the kickstart script)
Hi,
since I started using pxe-manager, I thought it could be nice to share some template so the community and other pxe-manager admins can use it.
The following is an advanced Foreman like template and it works with Redhat 9 (plow) but it should also work with Rocky Linux 9 as well as Alma Linux, though, I didn't tried it with those distro. Maybe with some changes here and there, it should also work for RHEL/CentOS version 8.
The PXE data assume that you are using iPXE for bootp but if you're not using uefi, you can modify it for pxelinux. See below
First, here are the template variables:
Name | Description | Data | Type | Required |
---|---|---|---|---|
iface_name | Primary interface name (eth0) | Text String | Yes | |
ip | IP address (192.168.1.x) | IPv4 Address | Yes | |
netmask | Netmask (255.255.255.0) | IPv4 Address | Yes | |
gateway | Gateway (192.168.1.1) | IPv4 Address | Yes | |
nameservers | Name servers ip (192.168.1.1,192.168.1.2) | Text String | Yes | |
domain | Domain / Search (domain.com) | Text String | Yes | |
bond_iface_name | Bond interface name (bond0) | Text String | No | |
bond_members | Bond interface members name (eth0,eth1) | Text String | No | |
bond_mode | Bond mode (active-backup,primary=eth0) | Text String | No | |
pxe_static_ip | Enable pxeboot with static IP | No|Yes | Select Option | No |
root_password | root password (should be encrypted using 'openssl passwd -6') | Text String | No | |
keyboard | Keyboard layout (us) | Text String | No | |
packages | Additonal packages to install | Multi-Line Text Data | No | |
rhel_subscription_org | Redhat subscription organization | Text String | No | |
rhel_subscription_key | Redhat subscription key | Text String | No | |
ntpservers | NTP servers addresses (0.pool.ntp.org,1.pool.ntp.org) | Text String | No | |
emailadmin | Admin email address to send root mail to | Text String | No | |
remote_ssh_user | Remote ssh user (myuser) | Text String | No | |
remote_ssh_keys | Public SSH authorized keys | Multi-Line Text Data | No | |
selinux | Enable Selinux | Yes|No | Select Option | No |
puppet | Enable Puppet agent | No|Yes | Select Option | No |
install_disk | Install system on disk device name (sda) | Text String | No | |
remove_install_logs | Remove install logs | No|Yes | Select Option | No |
wipefs | Erase all previous filesystems/partitions or raid signatures | Yes|No | Select Option | Yes |
PXE Data (only for use with pxelinux):
#!pxelinux
default install
prompt 0
timeout 50
menu title PXE Boot
menu tabmsg Press [Tab] to edit arguments
{% block label %}
label install
menu default
menu label Install {{ getServerInfo('image') }} on {{ getServerInfo('name') }}
kernel rhel9/vmlinuz
append initrd=rhel9/initrd.img ip=dhcp nameserver=nameserver={{ nameservers|replace({"\n": "", "\r": ",", " ": ","})|split(',')|first}} inst.ks={{ getScriptURL() }} BOOTIF=01-{{ getServerInfo('mac')|replace({':': '-'}) }} ks.sendmac inst.ks.sendmac
ipappend 2
{% endblock %}
PXE Data (iPXE):
#!ipxe
set base http://ks.domain.com/redhat/9AS/os
{% if pxe_static_ip == "Yes" and bond_iface_name and bond_members and bond_mode and ip and netmask and gateway and nameservers %}
kernel ${base}/images/pxeboot/vmlinuz initrd=initrd.img inst.repo=${base} inst.ks={{ getScriptURL() }} BOOTIF=01-{{ getServerInfo('mac')|replace({':': '-'}) }} ks.sendmac inst.ks.sendmac ip={{ ip }}::{{ gateway }}:{{ netmask }}:{{ getServerInfo('name') }}:{{ bond_iface_name}}:{{ bond_members|replace({"\n": "", "\r": ",", " ": ","}) }}:mode={{ getVariable('bond_mode') }} nameserver={{ nameservers|replace({"\n": "", "\r": ",", " ": ","})|split(',')|first}} ksdevice=bootif
{% elseif pxe_static_ip == "Yes" and iface_name and ip and netmask and gateway and nameservers %}
kernel ${base}/images/pxeboot/vmlinuz initrd=initrd.img inst.repo=${base} inst.ks={{ getScriptURL() }} BOOTIF=01-{{ getServerInfo('mac')|replace({':': '-'}) }} ks.sendmac inst.ks.sendmac ip={{ ip }}::{{ gateway }}:{{ netmask }}:{{ getServerInfo('name') }}:{{ iface_name }}:none nameserver={{ nameservers|replace({"\n": "", "\r": ",", " ": ","})|split(',')|first}} ksdevice=bootif
{% else %}
kernel ${base}/images/pxeboot/vmlinuz initrd=initrd.img inst.repo=${base} inst.ks={{ getScriptURL() }}
{% endif %}
initrd ${base}/images/pxeboot/initrd.img
imgstat
boot
Kickstart/Preseed Data:
%pre
{% if wipefs == "Yes" %}
udevadm settle
dmsetup remove_all
# De-activate any exiting Volume Groups
vgchange -an system
vgchange -an os
vgchange -an data
vgchange -an rhel
# Clear software raid devices if any
raid_devices=$(mktemp /tmp/mdstat.XXXXXXXXX)
cat /proc/mdstat | grep ^md | cut -d : -f 1 > $raid_devices
if [ -s $raid_devices ];then
for raid in `cat $raid_devices`;do
wipefs -f -a /dev/$raid
mdadm --stop -f /dev/$raid
if [ $? != "0" ];then
udevadm settle
dmsetup remove_all
mdadm --stop -f /dev/$raid
fi
done
else
echo "All raid devices are cleared"
fi
rm -vf $raid_devices
# Wipe any partitions if found
available_disks=$(mktemp /tmp/disks.XXXXXXXXX)
ls -r /dev/sd* > $available_disks
for disk in `cat $available_disks`;do
wipefs -f -a $disk
done
rm -vf $available_disks
{% endif %}
%end
### Performs the kickstart installation in text mode.
### By default, kickstart installations are performed in graphical mode.
text
### Accepts the End User License Agreement.
eula --agreed
{% block installsource %}
### Installs from
url --url http://ks.domain.com/redhat/9AS/os
{% endblock %}
### Sets the language to use during installation and the default language to use on the installed system.
lang en_US.UTF-8
### Sets the default keyboard type for the system.
keyboard --vckeymap={{ keyboard|default('us') }} --xlayouts={{ keyboard|default('us') }}
### Sets the system time zone.
{% if ntpservers %}
{% for ntpserver in ntpservers|split(',') %}
timesource --ntp-server={{ ntpserver }}
{% endfor %}
{% else %}
timesource --ntp-server=0.pool.ntp.org
timesource --ntp-server=1.pool.ntp.org
{% endif %}
timezone Europe/Zurich --utc
{% block network %}
{% if bond_iface_name and bond_members and bond_mode and ip and netmask and gateway and nameservers %}
network --noipv6 --bootproto=static --ip={{ getVariable('ip') }} --netmask={{ getVariable('netmask') }} --gateway={{ getVariable('gateway') }} --nameserver={{ nameservers|replace({"\n": "", "\r": ",", " ": ","}) }} --device={{ getVariable('bond_iface_name') }} --bondslaves={{ bond_members|replace({"\n": "", "\r": ",", " ": ","}) }} --bondopts=mode={{ getVariable('bond_mode') }} --hostname={{ getServerInfo('name') }} --activate
{% for member in bond_members|split(',') %}
network --noipv6 --noipv4 --device={{ member }} --onboot=no --no-activate
{% endfor %}
{% elseif ip and netmask and gateway and nameservers %}
network --noipv6 --bootproto=static --ip={{ getVariable('ip') }} --netmask={{ getVariable('netmask') }} --gateway={{ getVariable('gateway') }} --nameserver={{ nameservers|replace({"\n": "", "\r": ",", " ": ","}) }} --hostname={{ getServerInfo('name') }} --device={{ getServerInfo('mac') }} --bindto=mac
{% else %}
network --bootproto=dhcp --hostname={{ getServerInfo('name') }}
{% endif %}
{% endblock %}
### Root password (Default is: admin)
rootpw --iscrypted {{ root_password|default('$6$OpP07KPb4vK1q7RT$FEhgJKEIlVH2oKaIFhAqs9HOFslGfKqs1DSTrLgHaJ.BWruYgDAAkFZDXcZNn06c6zj3Yq5NXmS4Lqckd5y.8/') }}
### Do not configure X on the installed system.
skipx
{% block firewall %}
### Configure firewall settings for the system.
### --enabled reject incoming connections that are not in response to outbound requests
### --ssh allow sshd service through the firewall
firewall --enabled --service=ssh
{% endblock %}
{% block authselect %}
### Sets up the authentication options for the system.
### The SSDD profile sets sha512 to hash passwords. Passwords are shadowed by default
### See the manual page for authselect-profile for a complete list of possible options.
authselect --enableshadow --passalgo=sha512 --kickstart select sssd
{% endblock %}
{% block selinux %}
{% if selinux == "Yes" %}
selinux --enforcing
{% else %}
selinux --disabled
{% endif %}
{% endblock %}
{% block partition %}
### Sets how the boot loader should be installed.
{% if install_disk %}
bootloader --location=mbr --boot-drive={{install_disk}} --append="nofb quiet splash=quiet"
{% else %}
bootloader --location=mbr --boot-drive=sda --append="nofb quiet splash=quiet"
{% endif %}
### Initialize any invalid partition tables found on disks.
zerombr
### Removes partitions from the system, prior to creation of new partitions.
### By default, no partitions are removed.
### --linux erases all Linux partitions.
### --initlabel Initializes a disk (or disks) by creating a default disk label for all disks in their respective architecture.
{% if install_disk %}
clearpart --all --initlabel --drives={{install_disk}}
ignoredisk --only-use={{install_disk}}
{% else %}
clearpart --all --initlabel --drives=sda
{% endif %}
### Create primary system partitions.
# /!\ This partitioning require a disk size that has at least 80Gb /!\
part /boot --fstype xfs --size=1024 --label=BOOTFS
part /boot/efi --fstype vfat --size=1024 --label=EFIFS
part pv.01 --size=100 --grow
### Create logical volumes
volgroup rhel --pesize=4096 pv.01
logvol swap --fstype swap --name=lv_swap --vgname=rhel --size=4096 --label=SWAPFS
logvol / --fstype xfs --name=lv_root --vgname=rhel --size=12288 --label=ROOTFS
logvol /home --fstype xfs --name=lv_home --vgname=rhel --size=4096 --label=HOMEFS --fsoptions="nodev,nosuid"
logvol /opt --fstype xfs --name=lv_opt --vgname=rhel --size=8192 --label=OPTFS --fsoptions="nodev"
logvol /tmp --fstype xfs --name=lv_tmp --vgname=rhel --size=10240 --label=TMPFS --fsoptions="nodev,noexec,nosuid"
logvol /var/log --fstype xfs --name=lv_log --vgname=rhel --size=10240 --label=LOGFS --fsoptions="nodev,noexec,nosuid"
logvol /var/log/audit --fstype xfs --name=lv_audit --vgname=rhel --size=4096 --label=AUDITFS --fsoptions="nodev,noexec,nosuid"
logvol /var --fstype xfs --name=lv_var --vgname=rhel --size=20480 --label=VARFS --fsoptions="nodev"
{% endblock %}
{% block systempackages %}
%packages --ignoremissing --excludedocs
@core
@^minimal-environment
iotop
nfs-utils
setroubleshoot
system-storage-manager
traceroute
telnet
net-tools
kexec-tools
chrony
perl
wget
curl
cloud-init
vim
%end
{% endblock %}
{% block syspurpose %}
{% if rhel_subscription_org and rhel_subscription_key %}
### System Purpose
syspurpose --role="Red Hat Enterprise Linux Server"
syspurpose --sla="Standard"
syspurpose --usage="Production"
{% endif %}
{% endblock %}
%pre-install
wget -qO /dev/null "{{ getLogUrl('info', 'Started "PRE-INSTALL"') }}"
%end
%post --log=/root/post-install.log
echo "Start post installation process"
wget -qO /dev/null "{{ getLogUrl('info', 'Started "POST"') }}"
# Sync time
echo "Updating system time"
chronyc makestep
hwclock --systohc
{% block subscriptionmanager %}
echo "Subscribing to RHEL"
{% if rhel_subscription_org and rhel_subscription_key %}
subscription-manager register --org={{ rhel_subscription_org }} --activationkey={{ rhel_subscription_key }}
subscription-manager repos --enable codeready-builder-for-rhel-9-x86_64-rpms
{% endif %}
{% endblock %}
{% block epelrepo %}
echo "Install epel repo"
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
{% endblock %}
{% block cloudinit %}
echo "Get cloud-init config"
wget -qO /etc/cloud/cloud.cfg.d/10_post-install.cfg -Y off {{ getPostInstallURL() }}
{% endblock %}
{% block packages %}
{% if packages %}
echo "Install additional packages"
dnf -y install {{ packages|replace({"\n": "", "\r": " "}) }}
{% endif %}
dnf makecache
dnf -y update
{% endblock %}
{% block aliases %}
{% if emailadmin %}
echo "Set email admin alias"
cat <<EOF >>/etc/aliases
root: {{ emailadmin }}
EOF
newaliases
{% endif %}
{% endblock %}
{% block ndns %}
echo "Disable auto-update of /etc/resolv.conf by NetworManager"
echo -e "[main]\ndns=none" > /etc/NetworkManager/conf.d/99-local.conf
{% endblock %}
{% block resolvconf %}
echo "Set default domain"
echo "search {{ domain|default('domain.com')}}" >> /etc/resolv.conf
{% endblock %}
{% block hosts %}
{% if ip and domain %}
echo "Set {{ getServerInfo('name') }}.{{ domain }} to /etc/hosts"
echo "{{ ip }} {{ getServerInfo('name') }}.{{ domain }} {{ getServerInfo('name') }}" >> /etc/hosts
{% endif%}
{% endblock %}
{% block authorizedkeys %}
echo "Configure SSH authorized_keys"
{% if remote_ssh_user and remote_ssh_keys %}
user_exists=false
getent passwd {{ remote_ssh_user }} >/dev/null 2>&1 && user_exists=true
{% if ssh_user != 'root' %}
{% set home_dir="/home" %}
if ! $user_exists; then
useradd -m {{ remote_ssh_user }} && user_exists=true
fi
{% endif %}
if $user_exists; then
mkdir -p "{{home_dir}}/{{ remote_ssh_user }}/.ssh"
cat << EOF >> {{home_dir}}/{{ remote_ssh_user }}/.ssh/authorized_keys
{{ remote_ssh_keys }}
EOF
chmod 0700 "{{home_dir}}/{{ remote_ssh_user }}/.ssh"
chmod 0600 "{{home_dir}}/{{ remote_ssh_user }}/.ssh/authorized_keys"
chown -R "{{ remote_ssh_user }}" "{{home_dir}}/{{ remote_ssh_user }}/.ssh"
{% if selinux == "Yes" %}
command -v restorecon && restorecon -RvF "{{home_dir}}/{{ remote_ssh_user }}/.ssh" || true
{% endif %}
{% if ssh_user != 'root' %}
cat << EOF > /etc/sudoers.d/20_{{ remote_ssh_user }}
{{ remote_ssh_user }} ALL = (root) NOPASSWD : ALL
Defaults:{{ remote_ssh_user }} !requiretty
EOF
{% endif %}
fi
{% endif %}
{% endblock %}
{% block puppet %}
{% if puppet == "Yes" %}
echo "Installing puppet agent"
curl -k https://puppet.domain.com/packages/current/install.bash | /usr/bin/sudo bash -s main:server=puppet.domain.com agent:certname={{ getServerInfo('name') }} agent:environment=production
{% endif %}
{% endblock %}
{% block selinuxautorelabel %}
{% if selinux == "Yes" %}
echo "Enforce complete relabel"
selinuxenabled && /bin/touch /.autorelabel
{% endif %}
{% endblock %}
# Enable locate database
/usr/bin/systemctl enable mlocate-updatedb.timer
/usr/bin/systemctl start mlocate-updatedb.timer
echo "Build done!"
wget -qO /dev/null "{{ getLogUrl('info', 'Ended "POST"') }}"
# Disable host provisioning after installation
echo "Disabling {{ getServerInfo('name') }} in host provisioning server"
wget -Y off -qO /dev/null {{ getServiceURL() }}/disable
sync
grub2-mkconfig
%end
### Reboot after the installation is complete.
reboot
Post-install script:
{% block cloudinit %}
### This yaml formated config file handles cloud-init config
disable_ec2_metadata: false
datasource_list: [ "ConfigDrive", "None"]
datasource:
None:
userdata_raw: |
#!/bin/bash
touch /etc/cloud/cloud-init.disabled
touch /var/run/reboot-required
rm -f /etc/cloud/cloud.cfg.d/10_post-install.cfg
{% if remove_install_logs == "Yes" %}
rm -f /root/original-ks.cfg
rm -f /root/anaconda-ks.cfg
rm -f /root/post-install.log
{% endif %}
metadata:
instance-id: {{ getServerInfo('name') }}
local-hostname: {{ getServerInfo('name') }}
network:
config: disabled
{% endblock %}
Feel free to edit, comment and share.
Hope that helps.
Cheers.
Button to create a new server based on an old one.
Data that is set for a given variable should be checked that it is valid.
root@netboot:/var/www/pxe-manager# composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
[ErrorException]
"continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"?
install [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev] [--no-plugins] [--no-custom-installers] [--no-autoloader] [--no-scripts] [--no-progress] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--ignore-platform-reqs] [--] []...
Hello @ShaneMcC, thanks for this awesome project which i really like. I was used to Foreman but even though I really enjoy working with it, it's way to heavy for use just as a kickstart generator.
So I'm considering using pxe-manager, which is nice and pretty easy to use for simple uses cases, though, I think some improvements would benefit the community.
First, in Foreman template, you can create a template and in this template include snippet that are kind of templates that are only meant to be included in image template.
It'lld be really nice if you can implement something similar to what Foreman is doing with its template snippet. Below, here's an example:
<%#
Main post script, if it fails the last post is still executed.
%>
%post --log=/mnt/sysimage/root/install.post.log
logger "Starting anaconda <%= @host %> postinstall"
exec < /dev/tty3 > /dev/tty3
#changing to VT 3 so that we can see whats going on....
/usr/bin/chvt 3
<%= snippet_if_exists(template_name + " custom post") %>
<% if subnet.respond_to?(:dhcp_boot_mode?) || @host.subnet6.respond_to?(:dhcp_boot_mode?) -%>
<%= snippet 'Redhat - kickstart networking setup' %>
<% end -%>
In this example you have <%= snippet 'Redhat - kickstart networking setup' %>
which is basically an include of the template name Redhat - kickstart networking setup
for network configuration that can be used in others templates as well, without the need of recreating it on each template, which I think is great for keeping things clean.
What's your thoughts on that ?
CentOS lets you specify a post-install script as part of the kickstart however debian does not.
Add a "post-install script"
Hello @ShaneMcC, thanks for this awesome project which i really like. I was used to Foreman but even though I really enjoy working with it, it's way to heavy for use just as a kickstart generator.
So I'm considering using pxe-manager, which is nice and pretty easy to use for simple uses cases, though, I think some improvements would benefit the community.
In Foreman, you can add to servers, IPMI addresses which can be used for powering, restarting, set boot to pxe, etc, any server that has IPMI enabled. Would you considering adding such feature in pxe-manager ?
When you delete an active server, their PXE configration file remains on disk and is not deleted.
We should have some kind of authentication, at the very least for things like creating/editing images.
Sometimes you may want to prevent a BootableImage being used on new servers, without impacting old ones.
Setting this flag to false should hide it from the Bootable Image dropdown when editing/creating a server unless it already has this image selected.
Add a blank CSS asset to allow for easy CSS changes for user themes.
Don't allow deleting image that has children
Add an AuthProvider that requires a username/password.
This should also allow editing of user access levels.
Variable type to allow multiple-choice values.
Options for multi-select and single-select.
Hi there,
just a quick one, adding a sort option so we could order by ID, Name, lastmodified, Enabled, or Image name, on Images and Servers pages will be great.
When we added iPXE support for #12 in a45dae9 there was no concept of authentication.
Since then we've added it, and with it the ability to restrict what certain users (or non-user) can see.
Most of the endpoints that expose data about a server without passing the authentication checks require that you know the servicehash which stops people randomly guessing the URLs quite so easily (as you need to know both the service ID and the service hash).
On the contrary, /pxedata just requires the MAC Address and from this you can then learn the servicehash to get access to the rest of the data.
The reasoning behind this endpoint was to make it reasonably trivial to set the iPXE URL in DHCP to point at the right pxedata, but we shouldn't be just exposing it like this by default.
With #21 users will be able to replicate similar functionality to this by pointing servers to custom scripts that can get the servicehash and redirect towards the correct service URL if they really don't want to chain via pxelinux first.
Add "Duplicate Image" button to create a new image based on an old one.
There should be a default bootable image that can't be removed that we use when no other image is selected (eg after removing an image, any servers that used the image should revert to this default.)
Add support for using ipxe files rather than just PXELinux.
Add a new service command to grab the pxedata
If PXEData starts with: "#!ipxe" then we can write the following to the pxelinux config:
KERNEL ipxe.lkrn
APPEND dhcp && chain --autofree {{ getServiceURL() }}/pxedata
This will then load our pxedata as an ipxe script instead.
If the configured override url could be exposed as a {{ getOverrideURL() }} or a variable available in twig functions, this would enable a seperate http repository of files to be hosted on the same server but a different path without impacting on pxe-manager
Hello,
I'm giving this a try in an LXC container running ubuntu 22.04 headless
I mostly followed the instructions during install, skipped the firewall stuff as my network config is not passthrough (using dhcp proxy in the same broadcast as my "real" dhcp server) and I also used different settings for dnsmasq
I get a problem when I make it to "composer install", fails with the following error
"PHP Parse error: syntax error, unexpected '|', expecting variable (T_VARIABLE) in /usr/share/php/Composer/IO/BaseIO.php on line 163"
Did some initial search found
This video, which claims it's a php version error
And this other issue, which also suggests it's a php version and maybe use --ignore-platform-reqs
php version reports
root@pxemanager:/var/www/pxe-manager# php --version
PHP 7.4.30 (cli) (built: Aug 1 2022 15:06:35) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.30, Copyright (c), by Zend Technologies
Since the installation instruction call libapache2-mod-php7.4 git php7.4-sqlite3 by version number, I imagine there's something significant about php 7.4 ?
I tried running composer install --ignore-platform-reqs
This did not change the error message
I'm not sure what to try next, I'll try upgrade or downgrading php maybe
I've noticed these lines, maybe adding the ppa:ondrej/apache2 repository and running upgrade will do something
CAVEATS:
PLEASE READ: If you like my work and want to give me a little motivation, please consider donating regularly: https://donate.sury.org/
Add ability to define entire pxelinux configs rather than just a single label entry.
I figure something like allowing the first line to be "#!pxelinux" or so and then just writing out the contents as-is would suffice. (Kinda similar to how we deal with ipxe)
It would be super handy if there were support for importing/exporting image configuration though the web UI.
Bonus points if you support bulk export/import and the ability to import from a URL (ie I give it a pastebin URL and it imports from that).
Thanks!
It would be nice if it was possible for deployments to be able to send some log entries back to the deployment server.
They should.
I'd recommend;
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.conf
sysctl -p
To enable ip forwarding to persist after reboots and installation of ipset-persistent so ipset rules persist after a reboot
Also ipset values are for 192.168.0.0/24 when instructions use 192.168.1.0/24 for DHCP pool.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.