11. Roles¶
This part is an agregations of all the BlueBanquise roles readme.
11.1. CORE¶
11.1.1. Access control¶
<IP_ADDRESS>. Description¶
This role ensure the node current status comply with ep_access_control variable.
<IP_ADDRESS>. Instructions¶
None
<IP_ADDRESS>. Output¶
Set SELinux, AppArmor, etc status.
<IP_ADDRESS>. To be added¶
Check if no packages are needed when enforcing after a selinux –disabled kickstart.
<IP_ADDRESS>. Changelog¶
1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.2. BlueBanquise¶
<IP_ADDRESS>. Description¶
This role install Ansible and dependencies on BlueBanquise controllers. Mainly used for bootstrapping the stack or multi iceberg.
<IP_ADDRESS>. Instructions¶
None
<IP_ADDRESS>. Input¶
None
<IP_ADDRESS>. Changelog¶
1.0.2: Clean. johnnykeats<EMAIL_ADDRESS>1.0.1: Add Ansible dependencies for additional filters. Bruno Travouillon<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.3. Conman¶
<IP_ADDRESS>. Description¶
This role provides a conman daemon that logs ipmi serial consoles.
<IP_ADDRESS>. Instructions¶
To login into a console, use:
conman mynode
To exit, simply press & then . .
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
icebergs_system
hostvars[hosts]
ep_equipment_type (triggers if == “server”)
ep_equipment_authentication.user
ep_equipment_authentication.password
- bmc
.ip4
<IP_ADDRESS>. Changelog¶
1.0.3: Clean. johnnykeats<EMAIL_ADDRESS>1.0.2: Tested on ubuntu 18.04 and validated. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.4. Display_tuning¶
<IP_ADDRESS>. Description¶
This role provides some nice colors and screenrc.
<IP_ADDRESS>. Input¶
None
<IP_ADDRESS>. Output¶
Files generated:
/usr/bin/free_root_disk
/root/.screenrc
/root/.vimrc
Files modified:
/root/.bashrc
<IP_ADDRESS>. Changelog¶
1.0.1: Clean. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.5. DHCP server¶
<IP_ADDRESS>. Description¶
This role provides a standard and simple dhcp server combined with the iPXE roms of BlueBanquise. It should be enough for most networks.
Please use advanced version if you need advanced features like shared-networks, opt61/82 match, or need to force iPXE roms to be used, or use advanced iPXE driver.
<IP_ADDRESS>. Instructions¶
This role provides basic features for network relying on MAC only (or range of unknown hosts).
The role will only take into account networks from the current iceberg, and with naming related to administration network (by default iceX-Y). In single iceberg configuration, i.e. default, it will consider ice1-Y networks.
For a network to be included in the dhcp, the variable is_in_dhcp must be set to true in the related network configuration.
Note also that dhcp role will use the following optional parameters if they exist in network:
dhcp_unknown_range: define the range of the subnet, for unregistered hosts. Can be useful for temporary connections (laptops, etc) or to detect if an hardware is missing in the inventory.
gateway: define router in the subnet, and so gateway provided by the dhcp server.
Resulting example network could be:
networks:
ice1-1:
subnet: <IP_ADDRESS>
prefix: 16
netmask: <IP_ADDRESS>
broadcast: <IP_ADDRESS>
dhcp_unknown_range: <IP_ADDRESS> <IP_ADDRESS> # Is optional
gateway: <IP_ADDRESS> # Is optional
is_in_dhcp: true # Must be set to true for dhcp role to integrate this network
is_in_dns: true
services_ip:
pxe_ip: <IP_ADDRESS> # Will be used by dhcp for next server
dns_ip: <IP_ADDRESS> # Will be used by dhcp for dns server
repository_ip: <IP_ADDRESS>
authentication_ip: <IP_ADDRESS>
time_ip: <IP_ADDRESS> # Will be used by dhcp for time server
log_ip: <IP_ADDRESS>
Finally, note that the following parameters can be set in the inventory (group_vars/all/general_settings/network.yml):
default_lease_time
max_lease_time
Consider increasing the default values once your network is production ready.
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
icebergs_system
domain_name
- network[item]
.is_in_dhcp (triggers if == “true”)
.subnet
.netmask
.broadcast
.services_ip.pxe_ip
.services_ip.dns_ip
.services_ip.time_ip
hostvars[hosts]
- network_interfaces
.ip4
.mac
Optional inventory vars:
hostvars[inventory_hostname]
dhcp_server_default_lease_time
dhcp_server_max_lease_time
- network[item]
.dhcp_unknown_range
.gateway
hostvars[hosts]
- bmc
.ip4
.mac
.name
<IP_ADDRESS>. Output¶
Packages installed:
dhcp server
Files generated:
/etc/dhcp/dhcpd.conf
/etc/dhcp/dhcpd.networks.conf
/etc/dhcp/dhcpd.{{ network }}.conf
<IP_ADDRESS>. Changelog¶
1.0.7: Set defaults leases. Benoit Leveugle<EMAIL_ADDRESS>1.0.6: Update to new network_interfaces syntax. Benoit Leveugle<EMAIL_ADDRESS>1.0.5: Clean. johnnykeats<EMAIL_ADDRESS>1.0.4: Added support of multiple DNS servers. Bruno Travouillon<EMAIL_ADDRESS>1.0.3: Simplify standard dhcp, create advanced dhcp for complex configurations. Benoit Leveugle<EMAIL_ADDRESS>1.0.2: Added Ubuntu 18.04 compatibility. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.6. DNS server¶
<IP_ADDRESS>. Description¶
This role provides a basic dns server based on bind.
Warning: this dns server is designed to be used as a single dns for the whole cluster. If you need multiple dns servers in the same cluster, or replication, please use the advanced dns server role instead.
<IP_ADDRESS>. Instructions¶
This DNS role will automatically add all networks of the cluster, assuming their variable is_in_dns is set to true:
networks:
ice1-1:
subnet: <IP_ADDRESS>
prefix: 16
netmask: <IP_ADDRESS>
broadcast: <IP_ADDRESS>
is_in_dhcp: true
is_in_dns: true <<<<<<<<<<
services_ip:
dns_ip: <IP_ADDRESS>
It will generate 5 files:
/etc/named.conf that contains main configuration, and that will try to bind to all networks defined on the host it is deployed on, using services_ip.dns_ip variable ip of the network.
/var/named/forward that contains forward resolution of hosts
/var/named/forward.soa included by /var/named/forward
/var/named/reverse that contains reverse resolution of hosts
/var/named/reverse.soa included by /var/named/reverse
To configure forwarding and integrate this dns server into an existing IT configuration, use file group_vars/all/general_settings/external.yml. It is possible to add here an external dns to bind to for this internal dns, as a relay.
external_dns:
dns_server: <<<<<<<<<<
- <IP_ADDRESS>
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
domain_name
- network[item]
.services_ip.dns_ip
.subnet
.prefix
- network_interfaces
.ip4
hostvars[host]
- network_interfaces
.ip4
.mac
Optional inventory vars:
hostvars[inventory_hostname]
external_dns.dns_server
hostvars[hosts]
alias
- bmc
.ip4
.mac
.name
<IP_ADDRESS>. Output¶
Packages installed:
bind dns server
Files generated:
/etc/named.conf
/var/named/forward
/var/named/reverse
/var/named/forward.soa
/var/named/reverse.soa
<IP_ADDRESS>. Changelog¶
1.0.1: Added SOA. Bruno Travouillon<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.7. DNS client¶
<IP_ADDRESS>. Description¶
This role provides a basic /etc/resolv.conf file.
<IP_ADDRESS>. Instructions¶
It is possible to add here external DNS servers for clients. Configuration is made in group_vars/all/general_settings/external.yml:
external_dns:
dns_client: <<<<<<<<<<
- <IP_ADDRESS>
Note that this/these external(s) dns will be placed after the cluster internal dns in resolution order.
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
domain_name
- network[item]
.services_ip.dns_ip
Optional inventory vars:
hostvars[inventory_hostname]
external_dns.dns_client
<IP_ADDRESS>. Changelog¶
1.0.4: Clean. johnnykeats<EMAIL_ADDRESS>1.0.3: Added support of multiple DNS servers. Bruno Travouillon<EMAIL_ADDRESS>1.0.2: Added variable for role version. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.8. Firewall¶
<IP_ADDRESS>. Description¶
This role configures the firewall service on the hosts.
For each network interface of the host where the play runs, this role binds the source address subnet/prefix to the zone defined in firewall.zone if the network must be in the firewall.
<IP_ADDRESS>. Instructions¶
<IP_ADDRESS>.1. Inventory configuration¶
Enable or disable the firewall service in the equipment profile:
ep_firewall: true
To add a network of the host to a zone, define the zone name in firewall.zone in the network:
networks:
ice1-1:
subnet: <IP_ADDRESS>
prefix: 16
netmask: <IP_ADDRESS>
broadcast: <IP_ADDRESS>
gateway: <IP_ADDRESS>
firewall:
zone: internal
interconnect-1:
subnet: <IP_ADDRESS>
prefix: 16
firewall:
zone: trusted
To add or delete custom services that are not handled by any other role, define the firewall_zones parameter as below:
firewall_zones:
- zone: internal <<< zone name
services_enabled: <<< list of service to enable
- high-availability
- prometheus
services_disabled: <<< list of service to disable
- cockpit
It is possible to add or delete custom ports and rich rules with the same parameter:
firewall_zones:
- zone: internal <<< zone name
ports_enabled: <<< list of ports to enable
- 1234/tcp
ports_disabled: <<< list of ports to disable
- 5678/tcp
rich_rules_enabled: <<< list of rich rules to enable
- "rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443"
rich_rules_disabled: <<< list of rich rules to disable
- 'rule service name="ftp" audit limit value="1/m" accept'
icmp_block_inversion: yes
masquerade: yes
<IP_ADDRESS>.2. Integration with other roles¶
BlueBanquise ships with roles that already support some level of firewall configuration by adding services to the default zone (public). For each role, it is possible to override the default zone by setting ${rolename}_firewall_zone in the inventory.
For example, if you want to add the services of the pxe_stack roles to the internal zone, you must set the variable pxe_stack_firewall_zone: internal.
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
ep_firewall
- network[item]
.subnet
.prefix
- .firewall
.zone
- network_interfaces
.network
Optional inventory vars:
hostvars[inventory_hostname]
- firewall_zones
zone
services_enabled (list)
services_disabled (list)
ports_enabled (list)
ports_disabled (list)
rich_rules_enabled (list)
rich_rules_disabled (list)
icmp_blocks_enabled (list)
icmp_blocks_disabled (list)
icmp_block_inversion (bool)
masquerade (bool)
<IP_ADDRESS>. Changelog¶
1.0.0: Role creation. Bruno Travouillon<EMAIL_ADDRESS>11.1.9. Hosts file¶
<IP_ADDRESS>. Description¶
This role provides a basic /etc/hosts files.
<IP_ADDRESS>. Instructions¶
This role will gather all hosts from the inventory, and add them, using all their known internal network connections ip, into /etc/hosts file.
In case of multiple icebergs system, administrator can reduce the scope of this gathering using hosts_file.range variable in group_vars/all/general_settings/general.yml. Setting range to all will use all Ansible inventory hosts, while setting range to iceberg will reduce the gathering to the current host iceberg.
hosts_file: <<<<<<<<
range: all # can be all (all hosts) or iceberg (iceberg only)
External hosts defined in group_vars/all/general_settings/external.yml at variable external_hosts will be automatically added in the /etc/hosts file.
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[host]
- network_interfaces
.ip4
.mac
Optional inventory vars:
hostvars[hosts]
alias
global_alias
- bmc
.ip4
.mac
.name
<IP_ADDRESS>. Changelog¶
1.0.7: Clean code. Benoit Leveugle<EMAIL_ADDRESS>1.0.6: Update to new network_interfaces syntax. Benoit Leveugle<EMAIL_ADDRESS>1.0.5: Clean. johnnykeats<EMAIL_ADDRESS>1.0.4: Rewrite whole macro, add BMC alias. Benoit Leveugle<EMAIL_ADDRESS>1.0.3: Accelerated mode. Benoit Leveugle<EMAIL_ADDRESS>1.0.2: Added role version. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.10. Log server¶
<IP_ADDRESS>. Description¶
This role provides an rsyslog server to gather logs of all hosts.
<IP_ADDRESS>. Instructions¶
All logs are separated by systemd instances into /var/log/rsyslog/ .
<IP_ADDRESS>. Changelog¶
1.0.1: Fixed bad template. Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.11. Log client¶
<IP_ADDRESS>. Description¶
This role provides an rsyslog client, to be used in combinaison with the log_server role.
<IP_ADDRESS>. Instructions¶
NA
<IP_ADDRESS>. To be done¶
Integrate journalctl logging instead of rsyslog.
<IP_ADDRESS>. Changelog¶
1.0.1: Fixed bad template. Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.12. NFS server¶
<IP_ADDRESS>. Description¶
This role provides an automatic nfs server that export on good networks desired directories.
<IP_ADDRESS>. Instructions¶
All configuration is done in group_vars/all/general_settings/nfs.yml:
nfs:
softwares: # Internal name of the nfs share
mount: /opt/softwares # What path server should export
export: /opt/softwares # Which path clients should mount this NFS (will be automatically created by client role)
server: arngrim # The server that export this storage space
clients_groups: # Group of hosts that will mount it. Can be an equipment group, or a main group (mg), or any other ansible group
- mg_computes
- mg_logins
take_over_network: ice1-1 # Network used to share this storage space
export_arguments: ro,no_root_squash,async # Arguments for the server (export)
mount_arguments: ro,intr,nfsvers=4.2,bg # Arguments for the client (mount)
This role will not modify default nfs server configuration (number of threads, nfs v4.2 force, etc).
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
- nfs[item]
.mount
.export
.server
.clients_groups
.export_arguments
Optional inventory vars:
hostvars[inventory_hostname]
- nfs[item]
.take_over_network
<IP_ADDRESS>. Changelog¶
1.0.3: Clean. johnnykeats<EMAIL_ADDRESS>1.0.2: Added Ubuntu 18.04 compatibility. johnnykeats<EMAIL_ADDRESS>1.0.1: Fixed bad template. Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.13. NFS client¶
<IP_ADDRESS>. Description¶
This role provides an automatic nfs client that mount targets and create local directories if needed.
<IP_ADDRESS>. Instructions¶
All configuration is done in group_vars/all/general_settings/nfs.yml.
See the nfs_server role instructions for more details.
Simply note that paths that should be mounted will be automatically created by this role if they do not exist.
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
- nfs[item]
.mount
.export
.server
.clients_groups
.mount_arguments
Optional inventory vars:
hostvars[inventory_hostname]
- nfs[item]
.take_over_network
<IP_ADDRESS>. Output¶
Create missing folders and mount nfs on them.
Packages installed:
nfs client utils
<IP_ADDRESS>. Changelog¶
1.0.3: Clean. johnnykeats<EMAIL_ADDRESS>1.0.2: Added Ubuntu 18.04 compatibility. johnnykeats<EMAIL_ADDRESS>1.0.1: Fixed bad template. Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.14. NIC¶
<IP_ADDRESS>. Description¶
This role configure network interfaces to provide desired ip, prefix, gateway, etc.
<IP_ADDRESS>. Instructions¶
This role provide network configuration based on system files (ifcfg files for RHEL/Centos systems).
User need to restart network or interfaces one by one for changes to take effect after role execution.
Network interfaces configurations are done at host level:
network_interfaces:
- interface: enp0s3 # Interface name on system
ip4: <IP_ADDRESS> # ip v4 to be set
mac: 08:00:27:de:42:22 # MAC address of this NIC
network: ice1-1 # Logical network connected to
By default, connections are of type ethernet. It is possible to specify connection type, for example infiniband:
network_interfaces:
- interface: ib0
ip4: <IP_ADDRESS>
network: interconnect-1
type: infiniband
To configure an LACP bonding, specify slave interfaces, and then create the bond, using bond-slave type and bond type:
network_interfaces:
- interface: eth0
type: bond-slave
master: bond0
- interface: eth1
type: bond-slave
master: bond0
- interface: bond0
type: bond
vlan: false
bond_options: "mode=4 xmit_hash_policy=layer3+4 miimon=100 lacp_rate=1"
ip4: <IP_ADDRESS>
network: ice1-1
To configure a vlan, simply set vlan to true:
network_interfaces:
- interface: vlan100
vlan: true
vlan_id: 100
physical_device: eth2
ip4: <IP_ADDRESS>
network: net-100
A full example with vlan over bond would be:
network_interfaces:
- interface: eth3
network: lk1
ip4: <IP_ADDRESS>
- interface: bond0
type: bond
bond_options: "mode=4 xmit_hash_policy=layer3+4 miimon=100 lacp_rate=1"
network: ice1-1
ip4: <IP_ADDRESS>
- interface: bond0.100
type: vlan
network: ice1-2
ip4: <IP_ADDRESS>
vlan: true
vlan_id: 100
physical_device: bond0
- interface: bond0.1
type: vlan
network: ice1-3
ip4: <IP_ADDRESS>
vlan: true
vlan_id: 1
physical_device: bond0
- interface: enp136s0f0
type: bond-slave
master: bond0
- interface: enp136s0f1
type: bond-slave
master: bond0
It is also possible to configure multiple ip per interface, using:
network_interfaces:
- interface: eth3
network: lk1
ip4_multi:
- <IP_ADDRESS>/16
- <IP_ADDRESS>/16
- <IP_ADDRESS>/24
MTU and/or Gateway can be set in the network file, and will be applyed to NIC linked to this network.
networks:
ice1-1:
subnet: <IP_ADDRESS>
prefix: 16
netmask: <IP_ADDRESS>
broadcast: <IP_ADDRESS>
dhcp_unknown_range: <IP_ADDRESS> <IP_ADDRESS>
gateway: <IP_ADDRESS> <<<<<<<<<<
mtu: 9000 <<<<<<<<<<
is_in_dhcp: true
is_in_dns: true
services_ip:
pxe_ip: <IP_ADDRESS>
dns_ip: <IP_ADDRESS>
repository_ip: <IP_ADDRESS>
authentication_ip: <IP_ADDRESS>
time_ip: <IP_ADDRESS>
log_ip: <IP_ADDRESS>
<IP_ADDRESS>. To be done¶
Add Ubuntu and Opensuse compatibility if asked for.
<IP_ADDRESS>. Changelog¶
1.0.3: Update readme. Benoit Leveugle<EMAIL_ADDRESS>1.0.2: Update to new network_interfaces syntax. Benoit Leveugle<EMAIL_ADDRESS>1.0.1: Fix VLAN and BOND. Benoit Leveugle<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.15. PXE Stack¶
<IP_ADDRESS>. Description¶
This role provides the whole PXE stack. It is a key feature of the stack.
<IP_ADDRESS>. Instructions¶
This role will deploy all the needed files, binaries, and scripts to deploy remote hosts using PXE (or even USB and CD boot).
The role takes place just after the dhcp in the PXE deployment, and will configure all the iPXE chain needed after dhcp provided hosts with next-server ip address and filename to use.
<IP_ADDRESS>.1. Files location¶
- PXE boot files are located in /var/www/html/preboot_execution_environment/, with path depending of the operating system.
bin/ directory contains some needed bin files, typically grub2 files for EFI boot.
equipment_profiles/ directory contains equipment_profiles related files, i.e. ipxe file with group variables, and os configuration files (kickstart, preseed, autoyast).
nodes/ directory contains hosts dedicated files, i.e. ipxe file with hosts dedicated variables.
osdeploy/ directory contains static files, with patterns to boot each kind of supported distributions.
- Basic configuration files are located in /etc/bluebanquise/pxe/.
nodes_parameters.yml contains all nodes PXE needed parameters.
pxe_parameters.yml contains needed values for scripts to adapt to current pxe server host (these parameters do not apply to PXE booted hosts !!).
Scripts are located in /usr/bin/.
<IP_ADDRESS>.2. Inventory configuration¶
This role will rely on multiple parts of the inventory, and is probably the most “invasive” role of the whole stack.
equipment_profile parameters are used for each equipment_profile group. All boot configuration is made relying on it (operating system, cpu architecture, console, kernel parameters, etc.). It is recommended to ensure coherency of the equipment_profile files.
authentication parameters are used to provide root password and default ssh authorized key.
hosts network_interfaces dedicated variables, to be able to force static ip address at kernel boot.
<IP_ADDRESS>.3. bootset usage¶
Once the role is deployed, and hosts gathered into /etc/bluebanquise/pxe/nodes_parameters.yml, the bootset tool can be used to manipulate remote hosts PXE boot. By default, 3 states can be defined for each host:
osdeploy: the remote host will deploy/redeploy its operating system, using inventory equipment_profile parameters of its equipment profile group.
disk: the remote host will boot on disk. This parameter is automatically set after a successful osdeploy.
diskless: the remote host will boot using a diskless mechanism. This diskless boot is generic, and is handled by an optional external role.
Again, consider that if you set an host to osdeploy, and that it succeed its deployment, stack will automatically set the host into disk boot for next boot, to avoid infinite reinstallation loop.
To get bootset help, use:
bootset -h
To ask an host to deploy/redeploy its operating system, use:
bootset -n c001 -b osdeploy
With c001 the target host to be redeployed.
To set this host to boot on disk, use:
bootset -n c001 -b disk
It is also possible to work on a range of host, using nodeset formatting:
bootset -n c001,c002,c[010-020],login1 -b disk
Also, if combined with clustershell addon role, it is possible to use Ansible inventory groups:
bootset -n @mg_computes -b disk
If some inventory parameters related to the host have been updated recently, it may be required to force files regeneration instead of simply modifying them. To do so, use:
bootset -n c001 -b osdeploy -f update
Also, on some “difficult” networks, system administrator may require to force static ip at boot. This can be achieved using:
bootset -n c001 -b osdeploy -f network
Or in combinaison with update, using comma separated:
bootset -n c001 -b osdeploy -f update,network
The tool is relatively verbose, and should provide all needed information on the fly on what it is doing.
Last part, regarding diskless. An image name need to be provided:
bootset -n c001 -b diskless -i myimage
This part should be covered in a diskless related role, and is not in the scope of this role.
<IP_ADDRESS>.4. iPXE chain¶
PXE part of the BlueBanquise stack relies heavily on iPXE, and its chain mechanism. This chain has multiple purposes:
Most important, it is verbose, and can be manually manipulated or followed (watching http server logs).
It is flexible, and can adapt to nearly any configuration (disk boot, os deployment, diskless, …).
It can operate on all hardware, from server to laptop. It can even be started from USB or CD image for non PXE able systems.
Some steps may seems weird or unnecessary, but are here on purpose: verbosity and debug, as PXE part is always the trickiest.
Some vocabulary: in the following document, chain* or **chaining refers to the iPXE mechanism that download and execute a new file, after the current one.
Also, all files root is assumed /var/www/html/preboot_execution_environnement on the next-server (the server on which this pxe_stack role has been deployed).
The whole process can be resumed in one detailed schema:
To be macroscopic:
The remote host boot over PXE, in EFI/legacy-bios, using its own PXE/iPXE rom.
The dhcp deployed by BlueBanquise will provide the host with the BlueBanquise iPXE rom. This iPXE rom contains an EMBED script that will display the logo, get an ip from the dhcp server, show some information, and chain to file convergence.ipxe.
convergence.ipxe will simply get the current architecture. This operation cannot be done into the EMBED script has it needs some logic, that could bug. Sys admin need to easily debug this without the need to rebuild iPXE roms. Then iPXE chain to nodes/${hostname}.ipxe with hostname the hostname provided by the dhcp server.
nodes/${hostname}.ipxe will define all host dedicated parameters, and also what host should do: boot on disk, deploy os, or boot in diskless. Then iPXE chain to equipment_profiles/${equipment-profile}.ipxe, with equipment-profile a variable defined in the current file.
equipment_profiles/${equipment-profile}.ipxe contains the host equipment profile group parameters, like operating system, console, kernel parameters, etc. Then iPXE chain to menu.ipxe.
menu.ipxe will display a basic menu on screen, with default set to what node is expected to do (this was gathered in nodes/${hostname}.ipxe). Timeout is 10s by default before host execute the expected action. Then, iPXE chain to:
osdeploy/${eq-distribution}_${eq-distribution-major-version}.ipxe if host needs to deploy/redeploy its operating system. These osdeploy files are dynamic, and adapt to parameters gathered in host dedicated file and host equipment_profile file.
diskless/images/${diskless-image}/boot.ipxe if host needs to boot in diskless.
sanboot –no-describe –drive 0x80 if host is legacy/bios/pcbios based. This is a simple command that boot on disk.
bin/${arch}/grub2_efi_autofind.img if host is EFI based. This grub2 image will look for a disk with a know operating system, and boot on it.
In case of an OS deployment, if this deployment succeed, in the post install script section, remote host will ask, using a curl command on its side and an CGI python script on server side (/var/www/cgi-bin/bootswitch.cgi), to boot next to disk. This CGI python script will simply edit node/${hostname}.ipxe file and change its default boot to bootdisk.
All files are manually editable. Also, note that an unregistered host (so no hostnames provided by the dhcp) will try to load nodes/.ipxe file. By default, this file will simply provide an iPXE shell, but system administrator can tune this file to specific purposes.
To follow the deployment process, simply tail -f logs of http server, and see the whole process occurring.
<IP_ADDRESS>. To be done¶
Issue when deploying ubuntu 18.04. Very long hang after packages check. Install continue after like 10 minutes of hang. Not blocking but boring…
<IP_ADDRESS>. Changelog¶
1.1.5: Update role to match $basearch, add status feat to bootset. Benoit Leveugle<EMAIL_ADDRESS>1.1.4: Update to new network_interfaces syntax. Benoit Leveugle<EMAIL_ADDRESS>1.1.3: Clean. johnnykeats<EMAIL_ADDRESS>1.1.2: Add support of major distribution version. Bruno<EMAIL_ADDRESS>1.1.1: bootset.py refactoring. Adrien Ribeiro<EMAIL_ADDRESS>1.1.0: Rewamped the whole role. Benoit Leveugle<EMAIL_ADDRESS>1.0.2: Add Ubuntu 18.04 compatibility. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.16. Repositories server¶
<IP_ADDRESS>. Description¶
This role simply configures repositories server (only install and start web server).
<IP_ADDRESS>. Instructions¶
This role simply install an http server. Repositories files manipulations have to be done manually by system administrator. Refer to main documentation.
There is a split between boot images and packages repositories. Boot images include the installer system which starts the deployment after PXE boot, while packages repositories include the software that will be installed on the systems.
Boot images repositories structure follows a specific pattern and includes the minor release version in the path:
Distribution Version Architecture Repository
+ + + +
| +--+ | |
+-----------+ | | +----------+
| | | |
v v v v
/var/www/html/repositories/centos/7.6/x86_64/os/
Packages repositories structure follows a specific pattern, which defaults to the major release version in the path:
Distribution Version Architecture Repository
+ + + +
| +--+ | |
+-----------+ | | +----------+
| | | |
v v v v
/var/www/html/repositories/centos/7/x86_64/os/
System administrator should create these directories manually, and put boot images and packages inside.
Note: we recommend to use the same directory path to later sync the Errata published by upstream operating system vendor.
Then, repositories that will be setup on clients are stored by default in /etc/bluebanquise/inventory/group_vars/all/general_settings/repositories.yml.
Keep in mind that it is possible to precede this file in equipment_profiles groups, and so put a repository file in for example /etc/bluebanquise/inventory/group_vars/equipment_supermicro_sandy_compute that will be considered by these nodes over the default one. This can be useful to define different repositories for different equipment.
<IP_ADDRESS>. Input¶
None
<IP_ADDRESS>. Output¶
Http server packages installed.
<IP_ADDRESS>. Changelog¶
1.0.3: Clean. johnnykeats<EMAIL_ADDRESS>1.0.2: Regrouped all distribs into a main file. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.17. Repositories client¶
<IP_ADDRESS>. Description¶
This role simply configure repositories for client hosts.
<IP_ADDRESS>. Instructions¶
See repositories_server role instructions for general repositories path details.
Repositories are set in repositories variable. Two shapes are available: a simple one and an advanced one.
Simple one:
repositories:
- os
- bluebanquise
- myrepo
Advanced one, to be combined with simple one as desired:
repositories:
- os
- bluebanquise
- name: epel
baseurl: 'https://dl.fedoraproject.org/pub/epel/$releasever/$basearch/'
proxy: 'https://proxy:8080'
Available advanced variables are:
name
baseurl
enabled
exclude
gpgcheck
gpgkey
proxy
Repository static path is computed using variables defined in the equipment_profile.
operating_system:
distribution: centos # centos, redhat, debian, ubuntu, opensuse, etc.
distribution_major_version: 8
# Optional: define a minor distribution version to force (repositories/PXE)
#distribution_version: 8.0
# Optional: add an environment in the repositories path (eg. production, staging) (repositories/PXE)
#repositories_environment: production
If equipment_profile is:
ep_operating_system:
distribution: centos
distribution_major_version: 8
Then path will be: repositories/centos/8/$basearch/
If equipment_profile is:
ep_operating_system:
distribution: centos
distribution_major_version: 8
distribution_version: 8.1
Then path will be: repositories/centos/8.1/$basearch/
If equipment_profile is:
ep_operating_system:
distribution: centos
distribution_major_version: 8
distribution_version: 8.1
repositories_environment: production
Then path will be: repositories/production/centos/8.1/$basearch/
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
repositories[item]
- eq_operating_system
distribution
distribution_major_version
Optional inventory vars:
hostvars[inventory_hostname]
- eq_operating_system
distribution_version
repositories_environment
<IP_ADDRESS>. Output¶
Repositories are set.
<IP_ADDRESS>. To be done¶
Need to clear up the Ubuntu repositories process, still not clear how to handle own made repos and officials repos as Ubuntu add local repos everywhere in the sources.list file.
<IP_ADDRESS>. Changelog¶
1.0.7: Simplified version of the role. Benoit Leveugle<EMAIL_ADDRESS>1.0.6: Deprecate external_repositories. Bruno Travouillon<EMAIL_ADDRESS>1.0.5: Added support for excluding packages from CentOS and RHEL repositories. Neil Munday<EMAIL_ADDRESS>1.0.4: Clean. johnnykeats<EMAIL_ADDRESS>1.0.3: Add support of major release version. Bruno<EMAIL_ADDRESS>1.0.2: Added Ubuntu 18.04 compatibility. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.18. Set Hostname¶
<IP_ADDRESS>. Description¶
This role simply set a node hostname.
<IP_ADDRESS>. Instructions¶
NA.
<IP_ADDRESS>. Changelog¶
1.0.2: Clean. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.19. SSH master¶
<IP_ADDRESS>. Description¶
This role configures the ssh access of inventory known hosts to ensure ssh access through nodes main network.
<IP_ADDRESS>. Instructions¶
This role will generate a configuration file in /root/.ssh/config.
This file will contains all hosts of the Ansible inventory (or all hosts of the current iceberg if using icebergs mode), with the following parameters:
Host freya
Hostname %h-ice1-1
And possibly add :
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
If asked for.
Note that for this example host, freya, the target hostname for ssh is %h-ice1-1, which translates to freya-ice1-1. This can be seen when invoking ssh with verbosity:
[root@odin ]# ssh freya -vvv
OpenSSH_7.8p1, OpenSSL 1.1.1 FIPS 11 Sep 2018
debug1: Reading configuration data /root/.ssh/config
debug1: /root/.ssh/config line 10: Applying options for freya
debug1: Reading configuration data /etc/ssh/ssh_config
debug3: /etc/ssh/ssh_config line 52: Including file /etc/ssh/ssh_config.d/05-redhat.conf depth 0
debug1: Reading configuration data /etc/ssh/ssh_config.d/05-redhat.conf
debug3: /etc/ssh/ssh_config.d/05-redhat.conf line 2: Including file /etc/crypto-policies/back-ends/openssh.config depth 1
debug1: Reading configuration data /etc/crypto-policies/back-ends/openssh.config
debug3: gss kex names ok: [gss-gex-sha1-,gss-group14-sha1-]
debug3: kex names ok: [curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1]
debug1: /etc/ssh/ssh_config.d/05-redhat.conf line 8: Applying options for *
debug2: resolving "freya-ice1-1" port 22
debug2: ssh_connect_direct
debug1: Connecting to freya-ice1-1 [<IP_ADDRESS>] port 22.
You can see here ssh is not trying to reach freya but is using freya-ice-1-1. This has been made to ensure whatever the direct resolution is in /etc/hosts or DNS, ssh and so Ansible will always use the management network of the target host.
Also, keep in mind that when redeploying a host its SSH key changes, which requires to remove the former host key from the known_hosts file, then add the new key. It is possible to achieve this with the commands below:
# for host in $(nodeset -e $NODES); do \
sed -i -e "/^${host}/d" /root/.ssh/known_hosts; \
done
# clush -o '-o StrictHostKeyChecking=no' -w $NODES dmidecode -s system-uuid
It is possible to disable the strict host key checking in the inventory with the configuration below:
---
security:
ssh:
hostkey_checking: false
This was the default behaviour prior BlueBanquise 1.3. The ssh configuration file will include the following parameters:
Host freya
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
Hostname %h-ice1-1
This ensure no issues when redeploying an host, at the cost of security.
Note that this file generation is kind of “sensible”, and will surely be the first one to break in case of uncoherent inventory. If this happens, check your inventory, fix it, and remove manually /root/.ssh/config and relaunch its generation.
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[hosts]
network_interfaces[item]
Optional inventory vars:
hostvars[inventory_hostname]
security.ssh.hostkey_checking
<IP_ADDRESS>. Output¶
/root/.ssh/config file
<IP_ADDRESS>. To be done¶
Add ProxyJump for icebergs
<IP_ADDRESS>. Changelog¶
1.0.3: Update to new network_interfaces syntax. Benoit Leveugle<EMAIL_ADDRESS>1.0.2: Clean. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.20. SSH slave¶
<IP_ADDRESS>. Description¶
This role configure the ssh client authorized public key.
<IP_ADDRESS>. Instructions¶
This role will ensure remote hosts is having currently defined ssh authorized public keys in their /root/.ssh/authorized_keys file.
These keys are set in file group_vars/all/equipment_all/authentication.yml.
Keep in mind that this file can be preceded with equipment_profiles groups.
<IP_ADDRESS>. Output¶
/root/.ssh/authorized_keys contains ssh public keys from inventory
<IP_ADDRESS>. Changelog¶
1.0.2: Clean. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.1.21. Time server¶
<IP_ADDRESS>. Description¶
This role provides a time server/client based on Chrony.
<IP_ADDRESS>. Instructions¶
This role will react differently if in multi icebergs mode or not.
By default, in non multiple icebergs, server will be the time source reference. If using multiple icebergs hierarchy, then server can be a time reference if at top of the icebergs hierarchy, or simply a time relay with an higher stratum, if not a top server. This stratum calculation is done using iceberg_level variable defined in /etc/bluebanquise/inventory/cluster/icebergs/icebergX files.
It is possible to configure external time sources for clients or servers in /etc/bluebanquise/inventory/group_vars/all/general_settings/external.yml:
external_time: <<<<<<<<
time_server:
pool: # List of possible time pools
- pool.ntp.org
server: # List of possible time servers
- 0.pool.ntp.org
- 1.pool.ntp.org
time_client:
pool:
server:
If time_server is defined, the pool or server will be added in the server configuration. If time_client is defined, the pool or server will be added in the client configuration. It is possible to not install any time server but simply bind to an external pool/server using this file.
pool and servers are mutually exclusive. If you define both, the role will default to pool to write the Chrony configuration.
In case of a need, to force time synchronization on client side, use:
chronyc -a makestep
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
network_interfaces[item]
networks[item].prefix
Optional inventory vars:
hostvars[inventory_hostname]
external_time
external_pool
<IP_ADDRESS>. Output¶
/etc/chrony.conf file
chrony package
time zone set from inventory
<IP_ADDRESS>. To be done¶
Icebergs with stratum levels.
<IP_ADDRESS>. Changelog¶
1.0.4: Add iburst to allow faster boot time recovery, update macro. Benoit Leveugle<EMAIL_ADDRESS>1.0.3: Update to new network_interfaces syntax. Benoit Leveugle<EMAIL_ADDRESS>1.0.2: Clean. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.2. ADVANCED CORE¶
11.2.1. Advanced DHCP server¶
<IP_ADDRESS>. Description¶
This role provides an advanced dhcp server combined with the iPXE roms of BlueBanquise. Features like shared_network, opt82, opt61 or snp/snponly roms are provided here for very specific configurations or needs.
<IP_ADDRESS>. Instructions¶
Please read first documentation of the standard dhcp server role. Advanced dhcp server provides sames features than standard dhcp server role, but with more options.
Dhcp will only take into account networks from the current iceberg, and with naming related to administration network (by default iceX-Y).
Also, ensure dhcp is set to true for your network.
<IP_ADDRESS>.2. opt 61 and opt 82¶
It is possible to use advanced dhcp features to identify an host. The following parameters are available, for the host and its BMC. Note that only one of these must be set for an host/BMC at the same time:
mac: identify based on MAC address. Same than standard dhcp server.
dhcp_client_identifier: identify based on a patern (string, etc) to recognise an host. Also known as option 61.
host_identifier: identify based on an option (agent.circuit-id, agent.remote-id, etc) to recognise an host. Also known as option 82.
match: identify based on multiple options in combinaison to recognise an host. Also known as option 82 with hack.
If using match, because this features is using a specific ‘hack’ in the dhcp server, you must define this host in a shared network, even if this shared network contains a single network (see this very well made page for more information: http://www.miquels.cistron.nl/isc-dhcpd/).
<IP_ADDRESS>. Changelog¶
1.0.4: Update to new network_interfaces syntax. Benoit Leveugle<EMAIL_ADDRESS>1.0.3: Added support of multiple DNS servers. Bruno Travouillon<EMAIL_ADDRESS>1.0.2: Added Ubuntu 18.04 compatibility. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.2.2. Advanced DNS server¶
<IP_ADDRESS>. Description¶
This role provides an advanced dns server based on bind, and is expected to provide more and more features.
<IP_ADDRESS>. Instructions¶
This DNS role will automatically add all networks of the cluster, assuming their variable is_in_dns is set to true:
networks:
ice1-1:
subnet: <IP_ADDRESS>
prefix: 16
netmask: <IP_ADDRESS>
broadcast: <IP_ADDRESS>
is_in_dhcp: true
is_in_dns: true <<<<<<<<<<
services_ip:
dns_ip: <IP_ADDRESS>
It will generate 5 files:
/etc/named.conf that contains main configuration, and that will try to bind to all networks defined on the host it is deployed on, using services_ip.dns_ip variable ip of the network.
/var/named/forward that contains forward resolution of hosts
/var/named/forward.soa included in /var/named/forward
/var/named/reverse that contains reverse resolution of hosts
/var/named/reverse.soa included in /var/named/reverse
To configure forwarding and integrate this dns server into an existing IT configuration, use file group_vars/all/general_settings/external.yml. It is possible to add here an external dns to bind to for this internal dns, as a relay.
external_dns:
dns_server: <<<<<<<<<<
- <IP_ADDRESS>
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
domain_name
- network[item]
.services_ip.dns_ip
.subnet
.prefix
- network_interfaces
.ip4
hostvars[host]
- network_interfaces
.ip4
.mac
Optional inventory vars:
hostvars[inventory_hostname]
dns_master
dns_slaves
external_dns.dns_server
hostvars[hosts]
alias
- bmc
.ip4
.mac
.name
<IP_ADDRESS>. Output¶
Packages installed:
bind dns server
Files generated:
/etc/named.conf
/var/named/forward
/var/named/reverse
/var/named/forward.soa
/var/named/reverse.soa
<IP_ADDRESS>. Changelog¶
1.1.2: Moved role to advanced core. Benoit Leveugle<EMAIL_ADDRESS>1.1.1: Clean. johnnykeats<EMAIL_ADDRESS>1.1.0: Added DNS slaves support. Bruno Travouillon<EMAIL_ADDRESS>1.0.2: Added Ubuntu 18.04 compatibility. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3. ADDONS¶
11.3.1. Cloning¶
<IP_ADDRESS>. Description¶
This role provides ipxe files for Clonezilla live usage.
<IP_ADDRESS>. Instructions¶
The Clonezilla Live iso is needed for this role to run properly. The following iso version was used for validating this role: clonezilla-live-20191024-eoan-amd64.iso
The iso must be mounted in the preboot_execution_environment/clone/clonezilla folder or the content copied inside this directory.
Call bootset using -b clone -i myimage to clone a node into myimage, and -b deploy_clone -i myimage to deploy myimage on the target node.
By default, sda device is targeted, and clone parameters are:
ocs-sr -q2 -batch -j2 -z1 -i 2096 -fsck-src-part-y -senc -p reboot savedisk myimage.img sda
It is possible to force other clone parameters by setting extra-parameters during bootset invocation. For example, to clone sdb disk, use:
bootset -n mynode -i myimage -b clone -e "ocs-sr -q2 -batch -j2 -z1 -i 2096 -fsck-src-part-y -senc -p reboot savedisk myimage.img sdb"
Refer to clonezilla live documentation about other parameters.
Same apply to deploy clone. By Default, sda is targeted, and restore clone parameters are:
ocs-sr -g auto -e1 auto -e2 -r -j2 -batch -p reboot restoredisk myimage.img sda
It is possible to replace these parameters using extra parameters when invoking bootset.
<IP_ADDRESS>. Changelog¶
1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.2. ClusterShell¶
<IP_ADDRESS>. Description¶
This role provides clustershell and groups for clustershell (based on Ansible groups).
<IP_ADDRESS>. To be done¶
Tree execution mode is missing.
<IP_ADDRESS>. Changelog¶
1.0.1: Fixed bad template. Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.3. Diskless¶
<IP_ADDRESS>. Description¶
This role provides needed tools to deploy a basic diskless cluster.

NFS images are full nfs rw images, with psersistance, very simple to use, but need more infrastructure.
It is important to understand that this role is independant of the pxe_stack core role, and so each tools do not communicate.
Validated on RHEL8.
<IP_ADDRESS>. Basic instructions¶
Apply your playbook with the “diskless” role activated (see Example playbook part):
Copy the kernels in /boot you want to use for your images.
cp /boot/<kernels to use for diskless nodes> /var/www/html/preboot_execution_environment/diskless/kernels/
Launch disklessset and verify that the kernels are present in the tool, then quit.
# disklessset
BlueBanquise Diskless manager
1 - List available kernels
2 - Generate a new initramfs
3 - Generate a new diskless image
4 - Manage/list existing diskless images
5 - Remove a diskless image
-->: 1
[INFO] Loading kernels from /var/www/html/preboot_execution_environment/diskless/kernels/
Available kernels:
│
└── vmlinuz-4.18.0-193.6.3.el8_2.x86_64
Launch disklessset and ask an initramfs creation for this kernel
# disklessset
BlueBanquise Diskless manager
1 - List available kernels
2 - Generate a new initramfs
3 - Generate a new diskless image
4 - Manage/list existing diskless images
5 - Remove a diskless image
-->: 2
[INFO] Loading kernels from /var/www/html/preboot_execution_environment/diskless/kernels/
Select kernel:
1 - vmlinuz-4.18.0-193.6.3.el8_2.x86_64
-->: 1
Using disklessset, verify that this creation went well: “initiramfs present” must now be present after the kernel.
# disklessset
BlueBanquise Diskless manager
1 - List available kernels
2 - Generate a new initramfs
3 - Generate a new diskless image
4 - Manage/list existing diskless images
5 - Remove a diskless image
-->: 1
[INFO] Loading kernels from /var/www/html/preboot_execution_environment/diskless/kernels/
Available kernels:
│
└── vmlinuz-4.18.0-193.6.3.el8_2.x86_64 - initramfs present
Launch disklessset and create the livenet image. The command will guide you from here.
# disklessset
BlueBanquise Diskless manager
1 - List available kernels
2 - Generate a new initramfs
3 - Generate a new diskless image
4 - Manage/list existing diskless images
5 - Remove a diskless image
-->: 3
Starting new image creation phase.
Many questions will be asked, a recap will be provided before starting procedure.
Select livenet image:
Select image type:
1 - nfs
2 - livenet
-->: 2
[INFO] Loading kernels from /var/www/html/preboot_execution_environment/diskless/kernels/
Select the kernel you want to use wit this image from the list of available kernels:
Select kernel:
1 - vmlinuz-4.18.0-193.6.3.el8_2.x86_64
-->: 1
Please enter image name ?
-->: livenet1
Please enter clear root password of the new image: root
[INFO] Entering livenet dedicated part.
Choose a standard image, and give a size.
Please select livenet image generation profile:
1 - Standard: core (~1.2Gb)
2 - Small: openssh, dnf and NetworkManager (~248Mb)
3 - Minimal: openssh only (~129Mb)
-->: 1
Please choose image size (e.g. 5G):
(supported units: M=1024*1024, G=1024*1024*1024)
-->: 5G
Check that everything is alright before continuing:
Do you want to create a new livenet image with the following parameters:
Image name: livenet1
Kernel version: vmlinuz-4.18.0-193.6.3.el8_2.x86_64
Root password: root
Image profile: 1
Image size: 5120M
Confirm ? Enter yes or no: yes
[INFO] Cleaning and creating image folders.
[INFO] Generating new ipxe boot file.
[INFO] Creating empty image file, format and mount it.
5242880+0 records in
5242880+0 records out
5368709120 bytes (5.4 GB, 5.0 GiB) copied, 10.3195 s, 520 MB/s
meta-data=/root/diskless/workdir//LiveOS/rootfs.img isize=512 agcount=4, agsize=327680 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=1
data = bsize=4096 blocks=1310720, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[INFO] Generating cache link for dnf.
[INFO] Installing system into image.
...
Image is now generated. See Customizing Livenet image in next section on how to customize image before using it.
Using the command bootset, set the image one node will use.
# bootset -n c001 -b diskless -i livenet1
The -n parameter can be a nodeset.
Reboot the diskless node to make it boot onto the new image.
Example Playbook
- hosts: mngt0-1
roles:
- pxe_stack
- diskless
<IP_ADDRESS>. Customizing Livenet image¶
The image name used in the examples below is space_image.
The disklessset tool allows to customize livenet images before booting them, by mounting images and providing simple chroot inventory. System administrator can then tune or execute playbooks inside images.
Start the tool, select menu “4 - Manage existing diskless images”, then “5 - Manage livenet images”.
The next menu allows you to mount, unmount, or resize image.
Mount the image first. Images are mounted in /var/tmp/diskless/workdir/space_image/mnt.
It is now possible to copy files, install rpms, or tune any aspects of the mounted image.
The tool also generated a temporary Ansible inventory in /var/tmp/diskless/workdir/space_image/inventory/ .
To execute an Ansible playbook into the image, generate a new playbook with the following head:
- name: Computes diskless playbook
hosts: /var/tmp/diskless/workdir/space_image/mnt
connection: chroot
vars:
j2_current_iceberg: iceberg1 #<<< UPDATE IF NEEDED
j2_node_main_network: ice1-1 #<<< UPDATE
start_service: false
image_equipment_profile: equipment_typeC #<<< UPDATE
pre_tasks:
- name: Add current host to defined equipment_profile
add_host:
hostname: "{{ inventory_hostname }}"
groups: "{{ image_equipment_profile }}"
roles:
# ADD HERE YOUR ROLES
Now, update the needed values in this file:
j2_current_iceberg: Except if you are using multiple icebergs advanced feature, you should let this to iceberg1.
j2_node_main_network: Set here your main network to be used. This will allow the roles to determine the services ip to bind to.
image_equipment_profile: Set here your equipment_profile to be used. This will allow the roles to determine key values, for example find the repositories path to be used (distribution version, etc).
And add your desired roles under roles: in the file, like for any standard playbook.
Then execute it into the mounted image using the following command:
ansible-playbook computes.yml \
-i /etc/bluebanquise/inventory/ -i /etc/bluebanquise/internal/ -i /var/tmp/diskless/workdir/space_image/inventory/ \
--skip-tags identify
Notes:
The multiple -i defines Ansible inventories to gather. By default, in BlueBanquise, the first two inventories are used. We simply add the third one, corresponding to the mounting point.
The -e (extra vars) are here to specify to the stack which iceberg and main network are to be used in the configuration of the node. (System cannot know on which nodes the image will be used).
The –skip-tags identify prevents hostname and static ip to be set, since the image should be generic for multiple hosts.
Before closing, also remember to clean dnf cache into the image chroot to save space.
Now, using df command, check used space of the image, to resize it later if whished.
Using disklessset now, choose option 2 to unmount the image and squashfs it again.
It is possible now to use the tool to resize image, to reduce it to the desired value (to save ram on target host). Always keep at least 100MB in / for temporary files and few logs generated during run.
<IP_ADDRESS>. To be done¶
Clean code, add more error detection, and more verbosity.
<IP_ADDRESS>. Changelog¶
1.1.0: Role update. Benoit Leveugle<EMAIL_ADDRESS>Bruno Travouillon<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.4. OFED¶
<IP_ADDRESS>. Description¶
This role install and start all needed for OFED based interconnects (Mellanox, etc.).
<IP_ADDRESS>. Instructions¶
Only for Centos/Rhel.
<IP_ADDRESS>. To be done¶
Need to add support for Ubuntu and OpenSuse if exist.
<IP_ADDRESS>. Changelog¶
1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.5. OFED_SM¶
<IP_ADDRESS>. Description¶
This role install and start all needed for OFED subnet manager.
<IP_ADDRESS>. Instructions¶
Only for Centos/Rhel.
<IP_ADDRESS>. To be done¶
Need to add support for Ubuntu and OpenSuse if exist.
<IP_ADDRESS>. Changelog¶
1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.6. OpenLDAP client¶
<IP_ADDRESS>. Description¶
This role provides a basic but UNSECURE ldap client based on SSSD.
<IP_ADDRESS>. Instructions¶
NA
<IP_ADDRESS>. To be done¶
Enable encryption to secure this role.
<IP_ADDRESS>. Changelog¶
1.0.1: Fixed bad template. Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.7. OpenLDAP server¶
<IP_ADDRESS>. Description¶
This role provides a basic but UNSECURE ldap server. It also provides phpldapadmin configuration to manage LDAP.
<IP_ADDRESS>. Instructions¶
Login into http://localhost/phpldapadmin to manage LDAP.
Keep in mind this role is for the time being unsecure.
<IP_ADDRESS>. To be done¶
Enable encryption to secure this role.
<IP_ADDRESS>. Changelog¶
1.0.1: Fixed bad template. Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.8. NIC with nmcli¶
<IP_ADDRESS>. Description¶
This role configure network interfaces to provide desired ip, prefix, gateway, etc.
This role is still under work, as nmcli is not supported in RHEL 8 for now, and that this role need to handle much more features.
<IP_ADDRESS>. Instructions¶
NA
<IP_ADDRESS>. To be done¶
Add more features, as nmcli Ansible module can do much more.
VLANs
LACP/Bond
Non network linked NIC
Multi IP
<IP_ADDRESS>. Changelog¶
1.0.2: Adding Ubuntu 18.04 compatibility. johnnykeats<EMAIL_ADDRESS>1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.9. Powerman¶
<IP_ADDRESS>. Description¶
This role provides powerman, to manage nodes power via ipmi (BMC).
<IP_ADDRESS>. Instructions¶
To power on node, use:
powerman --on bar,foo[7,9-10]
Refer to: https://linux.die.net/man/1/powerman
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
icebergs_system
hostvars[hosts]
ep_equipment_authentication.user
ep_equipment_authentication.password
- bmc
.name
.ip4
<IP_ADDRESS>. Output¶
Packages installed:
powerman
freeipmi
Files generated:
/etc/powerman/powerman.conf
<IP_ADDRESS>. Changelog¶
1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.10. Prometheus server¶
<IP_ADDRESS>. Description¶
This role deploy prometheus server with alertmanager.
<IP_ADDRESS>. Instructions¶
<IP_ADDRESS>.1. Default ports¶
Prometheus is available at http://localhost:9090
Alertmanager is available at http://localhost:9093
Node_exporter is available at http://localhost:9100
<IP_ADDRESS>.2. General configuration¶
By default, role will inherit from values set in its defaults folder. You may wish to update these values to your needs, as these values set the different timings used by Prometheus.
To do so, create file inventory/group_vars/all/addons/prometheus.yml with the following content:
prometheus:
scrape_interval: 1m
evaluation_interval: 2m
alertmanager:
group_wait: 1m
group_interval: 10m
repeat_interval: 3h
And tune according to your needs.
Note
The prometheus_server role will try to read the prometheus_client related files, to generate its configuration (register exporters to scrape for each equipment profile group of nodes). See the prometheus_client role documentation for more details.
<IP_ADDRESS>.3. Alerting¶
By default, the role will only add a simple alerts file into the /etc/prometheus/alerts folder. This file contains a basic alert that fire when an exporter is down.
You will probably wish to add more alerts. Few alerts are proposed by the stack, and are provided as examples in the /usr/share/doc/bluebanquise/prometheus/ folder.
You can simply copy the whole files that are needed, or a part of them, and tune them according to your needs.
Note
When possible, we added our references from the web inside the example files.
<IP_ADDRESS>. To be done¶
Allow groups alerts selection.
<IP_ADDRESS>. Changelog¶
1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.11. Prometheus client¶
<IP_ADDRESS>. Description¶
This role deploy exporters on clients for Prometheus queries.
<IP_ADDRESS>. Instructions¶
Each role has its own http port. For example, Node_exporter is available at http://localhost:9100 .
In order for this role to install and start exporters on the host, a configuration is required in the Ansible inventory.
A file is needed for each equipment_profile group that should be monitored.
For example, to have equipment_typeC nodes installing and testing the node_exporter, you will need to create file inventory/group_vars/equipment_typeC/monitoring.yml with the following content:
monitoring:
exporters:
node_exporter:
package: node_exporter
service: node_exporter
port: 9100
And for example, on your management nodes, you may wish to have more exporters setup to monitor much more things. This would be here, assuming managements nodes are from equipment group equipment_typeM, a file inventory/group_vars/equipment_typeM/monitoring.yml with the following content:
monitoring:
exporters:
node_exporter:
package: node_exporter
service: node_exporter
port: 9100
ha_cluster_exporter:
package: ha_cluster_exporter
service: ha_cluster_exporter
port: 9664
slurm_exporter:
package: slurm_exporter
service: slurm_exporter
scrape_interval: 5m
scrape_timeout: 5m
port: 9817
You can see here that it is possible to customize the scrape_interval and scrape_timeout.
Note
Note that the ipmi_exporter and snmp_exporter do not need to be included here as their behavior are different (they act as relay for other targets) and so are directly deployed by the prometheus_server role.
<IP_ADDRESS>. To be done¶
Allow groups alerts selection.
<IP_ADDRESS>. Changelog¶
1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. johnnykeats<EMAIL_ADDRESS>11.3.12. Report¶
<IP_ADDRESS>. Description¶
This role try to provide sys admin few useful tools.
An automatic known issue paterns checker for the stack
Many visual reports (inventory, playbooks, network, facts)
<IP_ADDRESS>. Instructions¶
Report is available at http://localhost/report/index.html
<IP_ADDRESS>. To be done¶
Many things…
<IP_ADDRESS>. Changelog¶
1.0.1: Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.13. Root password¶
<IP_ADDRESS>. Description¶
This role updates the root password on the target hosts.
<IP_ADDRESS>. Instructions¶
The root password must be defined in the inventory:
authentication_root_password_sha512: $6$M3crarMVoUV3rALd$ZTre2CIyss7zOb4lkLoG23As9OAkYPw2BM88Y1F43n8CCyV5XWwAYEwBOrS8bcCBIMjIPdJG.ndOfzWyAVR4j0
To generate an sha512 password, use the following command (python >3.3):
python -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))'
<IP_ADDRESS>. Input¶
Mandatory inventory vars:
hostvars[inventory_hostname]
authentication_root_password_sha512
<IP_ADDRESS>. Changelog¶
1.0.0: Role creation. Bruno Travouillon<EMAIL_ADDRESS>11.3.14. SSSD¶
<IP_ADDRESS>. Description¶
This role provides a basic configuration of SSSD to connect to an LDAP client.
<IP_ADDRESS>. Instructions¶
LDAP servers URL must be configured in the inventory like the example below:
## List of logical networks
networks:
ice1-1:
subnet: <IP_ADDRESS>
prefix: 16
netmask: <IP_ADDRESS>
broadcast: <IP_ADDRESS>
dhcp_unknown_range: <IP_ADDRESS> <IP_ADDRESS>
gateway: <IP_ADDRESS>
is_in_dhcp: true
is_in_dns: true
services_ip:
pxe_ip: <IP_ADDRESS>
dns_ip: <IP_ADDRESS>
repository_ip: <IP_ADDRESS>
authentication_servers:
- ldaps://my-ldap-server-1
- ldap://my-ldap-server-2
time_ip: <IP_ADDRESS>
log_ip: <IP_ADDRESS>
The following example configure LDAP secured server my-ldap-server-1 as first server and my-ldap-server-2 as second server.
<IP_ADDRESS>. Changelog¶
1.0.2: Support multiple and secured connections to LDAP servers<EMAIL_ADDRESS>1.0.1: Fixed bad template. Documentation. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. oxedions<EMAIL_ADDRESS>11.3.15. Slurm¶
<IP_ADDRESS>. Description¶
This role provides slurm configuration for server, client and login nodes.
<IP_ADDRESS>. Instructions¶
IMPORTANT: first thing to do is to generate a new munge key file. To do so, go into files folder of the role and generate a new munge.key file using:
dd if=/dev/urandom bs=1 count=1024 > munge.key
We do not provide default munge key file, as it is considered a security risk.
Then, in the inventory addon folder (inventory/group_vars/all/addons) that should be created if not exist, add a slurm.yml file with the following content, tuned according to your needs:
slurm:
slurm_packaging: after_17 # Can be before_17 or after_17. If using BlueBanquise packages, use after_17. For OpenHPC 1.3, use before_17.
cluster_name: bluebanquise
control_machine: management1
MpiDefault: pmi2 # Optional
nodes_equipment_groups:
- equipment_typeC
To use this role for all 3 types of nodes, simply add a vars in the playbook when loading the role. Extra vars is slurm_profile.
For a controller (server), use:
- role: slurm
tags: slurm
vars:
slurm_profile: controller
For a compute node (client), use:
- role: slurm
tags: slurm
vars:
slurm_profile: node
And for a login (passive client), use:
- role: slurm
tags: slurm
vars:
slurm_profile: passive
<IP_ADDRESS>. To be done¶
slurmdbd + mariadb
static file
<IP_ADDRESS>. Changelog¶
1.0.2: Update role, remove munge key. Benoit Leveugle<EMAIL_ADDRESS>1.0.1: Documentation. Benoit Leveugle<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle<EMAIL_ADDRESS>11.3.16. Users basic¶
<IP_ADDRESS>. Description¶
This role provides a very basic users management, for simple clusters.
<IP_ADDRESS>. Instructions¶
Create file inventory/group_vars/all/addons/users_basic.yml with the following content:
users_basic:
users:
- name: johnnykeats
uid: 1078
gid: 1078
home: /home
shell: /bin/bash
comment: dream all the day # optional
password: $6$M3crarMVoUV3rALd$ZTre2CIyss7zOb4lkLoG23As9OAkYPw2BM88Y1F43n8CCyV5XWwAYEwBOrS8bcCBIMjIPdJG.ndOfzWyAVR4j0
Then edit this file according to your needs, and play this role on all hosts with users, including slurmctld server if using slurm.
Available arguments for each user are:
name
uid
gid
password
state
groups (optional)
create_home (optional)
update_password (optional)
shell (optional)
home (optional)
generate_ssh_key (optional)
ssh_key_bits (optional)
ssh_key_file (optional)
remove (optional)
comment (optional)
To ensure a user is not on a system, set state to “absent”. To also remove its home, set remove to “yes”.
To generate an sha512 password, use the following command (python >3.3):
python -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))'
Or (python 2):
python -c "import crypt,random,string; print crypt.crypt(raw_input('clear-text password: '), '\$6\$' + ''.join([random.choice(string.ascii_letters + string.digits) for _ in range(16)]))"
<IP_ADDRESS>. Changelog¶
1.1.0: Role enhancement. New inventory structure. Benoit Leveugle<EMAIL_ADDRESS>1.0.1: Documentation and resources. johnnykeats<EMAIL_ADDRESS>1.0.0: Role creation. Benoit Leveugle <benoit.leveugle@gmail.com>


I’ve seen a lot of newbies (and not newbies) having problems handling dates in PHP (and even with SQL and another languages). When I see someone having problems with dates, I always ask the same question. I type in a text editor “27/11/2012” and I ask him: What is it? If your answer is “This is a date” you should continue reading the post :)
“27/11/2012” in a text editor is not a date. It’s a string representing a date (my birthday this year, indeed :) ). We also must take into account that we cannot show a “raw” date. We only can apply a mask to a date if we want to show it. Because of that dates are normally stored internally as UNIX timestams or something similar.You can say that when we perform one SELECT statement with a date field we don’t see one timestamp. That’s because the tool that you are using to show the date field applies one mask to your date. The default mask can be also a problem. “01/02/2012” represents 01/February/2012 or 02/January/2012? We don’t know. Depends on the mask that we are using.
When we work with PHP is very usual to use dates. Sometimes we need to pass them to SQL queries, perform operations (such as add days, diffs, compare, …). When I started with PHP 10 years ago we use to use mktime(), date(), and insane operations with split/join with strings. That’s the past. Now we have DateTime.
It’s pretty straightforward to use it. We can use one static factory to create DateTime objects
$date = DateTime::createFromFormat('d/m/Y', '27/11/2012');
Now $date is a variable that stores a DateTime object. If we want to show it, we need to apply one format. For example:
$date = DateTime::createFromFormat('d/m/Y', '27/11/2012');
echo $date->format('m/d/Y'); // outputs 11/27/2012
I’m not going to create a tutorial of DateTime here. It’s very good described (as always) within PHP official documentation. There is something that I love with DateTime objects also:
$date1 = DateTime::createFromFormat('d/m/Y', '27/11/2012');
$date2 = DateTime::createFromFormat('d/m/Y', '27/11/2011');
if ($date1 > $date2) {
echo "It works!"
}
In my last projects when I need to use Dates I like to cast the variables as DateTime objects. Let me show you a little example:
<?php
class Dummy
{
/** @var DateTime */
private $date;
private $defaultFormat = 'd/m/Y';
public function setDate(DateTime $date)
{
$this->date = $date;
}
public function getDate()
{
return $this->date;
}
public function getFormattedDate($format = NULL)
{
return $this->date->format($this->getFormat($format));
}
public function setFormattedDate($formatedDate, $format = NULL)
{
$this->date = DateTime::createFromFormat($this->getFormat($format), $formatedDate);
}
public function setDefaultFormat($format)
{
$this->defaultFormat = $format;
}
private function getFormat($format)
{
return is_null($format) ? $this->defaultFormat : $format;
}
}
But maybe, as always, the best documentation are the Unit Tests
<?php
class DummyTest extends \PHPUnit_Framework_TestCase
{
public function testDate()
{
$date = DateTime::createFromFormat('d/m/Y', '1/2/2012');
$dummy = new Dummy();
$dummy->setDate($date);
$this->assertEquals($date, $dummy->getDate());
}
public function testDateWithAlternativeSetter()
{
$dummy = new Dummy();
$dummy->setFormattedDate('1/2/2012', 'd/m/Y');
$this->assertEquals(DateTime::createFromFormat('d/m/Y', '1/2/2012'), $dummy->getDate());
}
public function testDateWithAlternativeSetterWithDeffaultFormatSet()
{
$dummy = new Dummy();
$dummy->setDefaultFormat('d/m/Y');
$dummy->setFormattedDate('1/2/2012');
$this->assertEquals(DateTime::createFromFormat('d/m/Y', '1/2/2012'), $dummy->getDate());
}
public function testFormatGetterWithDefaultFormat()
{
$dummy = new Dummy();
$dummy->setFormattedDate('1/2/2012');
$this->assertEquals('2012', $dummy->getDate()->format('Y'));
}
public function testFormatGetter()
{
$dummy = new Dummy();
$dummy->setFormattedDate('1/2/2012');
$this->assertEquals('2012', $dummy->getFormattedDate('Y'));
}
public function testDiffDates()
{
$dummy = new Dummy();
$dummy->setFormattedDate('1/2/2012');
$date = DateTime::createFromFormat('d/m/Y', '1/2/2011');
$this->assertTrue($date < $dummy->getDate());
}
public function testModifyDates()
{
// leap-years
$dummy = new Dummy();
$dummy->setFormattedDate('28/02/1908');
$this->assertEquals('29/02/1908', $dummy->getDate()->modify("+1 day")->format('d/m/Y'));
// Non leap-years
$dummy = new Dummy();
$dummy->setFormattedDate('28/02/2001');
$this->assertEquals('01/03/2001', $dummy->getDate()->modify("+1 day")->format('d/m/Y'));
}
}
What do you think?


| Param | Description | Optional |
| user_id | Returns user data for this specific user id |
{
user_id:seed_sally_id
}
{
first_name: "Sally"
full_name: "Sally Bronsen"
id: "seed_sally_id"
is_manager: false
last_name: "Bronsen"
user_name: "sally"
}


Yoko Ono Pleads For Change In Gun Laws In The US On John Lennon’s 39th Death Anniversary
Yoko Ono went on to call on American politicians to change US gun laws
by IANSJohn Lennon’s wife Yoko Ono has marked the 39th anniversary of the Beatles legend death by revealing she still feels “hollow” and misses him daily.
Lennon was shot outside the couple’s Dakota Building apartment in New York on December 8, 1980, and Ono says she and his sons still struggle with the untimely death of their beloved husband and father, reports aceshowbiz.com.
“After 39 years, Sean, Julian and I still miss him. The death of a loved one is a hollowing experience,” she wrote on Twitter.
 We are turning this beautiful country into a War Zone. Together, let’s bring back America, the green land of peace.”
She also shared a statistic that said over 1,400,000 people have been killed by guns in America since Lennon’s death.


Thoughts on Productivity
I've heard about the pomodoro technique before and tried that again. I like the idea of creating short bursts of productive energy but find that sometimes I get in the zone and want to continue way past the allotted time limit. I have found that this technique combined with a quick meditation works well when I had little or no creative energy, and kind of reset my mind.
I'm chronic for starting a task, getting halfway through it, then starting another. One thing I have tried to do is skim through all tasks first as an initial overview, then group anything similar together. If I want to start something new partway through then it has to be from a similar task, that way it keeps my mind on track.
Lastly, I try to make my workspace as comfortable as possible without any massive distractions so I actually like my work environment and want to spend time here.
I love the incredible variety of productivity, time management and habit building techniques but it's almost like there's too much of a good thing, like an overload of information. But I find it interesting how essential the concept is to good workflow.


Uses of Package
edu.uiuc.ncsa.qdl.expressions
-
Packages that use edu.uiuc.ncsa.qdl.expressions Package Description edu.uiuc.ncsa.qdl.evaluate Evaluators evaluate the built-in functions for QDL as well as perform the usual algebraic operations.edu.uiuc.ncsa.qdl.exceptions All of the exceptions for QDL.edu.uiuc.ncsa.qdl.expressions Expressions are objects that take zero or more arguments and return a result.edu.uiuc.ncsa.qdl.functions edu.uiuc.ncsa.qdl.parsing Classes that support parsing and the parser itself.edu.uiuc.ncsa.qdl.state Classes that manage the state of an interpreter session.edu.uiuc.ncsa.qdl.statements The two basic syntactic units of QDL are expressions (which return results) and statements which are the other control structures, such as conditionals, loops, etc.edu.uiuc.ncsa.qdl.variables Variables in QDL and classes that support them. -
Classes in edu.uiuc.ncsa.qdl.expressions used by edu.uiuc.ncsa.qdl.evaluate Class Description Dyad Created by Jeff Gaynor
on 1/13/20 at 3:47 PMExpressionImpl Created by Jeff Gaynor
on 1/13/20 at 3:15 PMIndexList A simple list of indices for a stem.Monad A post or prefix operator, such a logical not or ++.Nilad This would be an operator that takes no arguments.Polyad For multiple arguments. -
Classes in edu.uiuc.ncsa.qdl.expressions used by edu.uiuc.ncsa.qdl.exceptions Class Description Polyad For multiple arguments. -
Classes in edu.uiuc.ncsa.qdl.expressions used by edu.uiuc.ncsa.qdl.expressions Class Description ComparisonDyad Created by Jeff Gaynor
on 10/26/21 at 12:34 PMConstantNode Created by Jeff Gaynor
on 1/13/20 at 4:08 PMDyad Created by Jeff Gaynor
on 1/13/20 at 3:47 PMExpressionImpl Created by Jeff Gaynor
on 1/13/20 at 3:15 PMExpressionNode This class mostly manages the structure of expressions (so arguments are the children) and evaluating them is delegating the result to theOpEvaluator
class.ExpressionStemNode Created by Jeff Gaynor
on 3/5/21 at 5:58 AMIndexArg Created by Jeff Gaynor
on 7/1/22 at 4:51 PMIndexArgs Created by Jeff Gaynor
on 7/1/22 at 4:50 PMIndexList A simple list of indices for a stem. -
Classes in edu.uiuc.ncsa.qdl.expressions used by edu.uiuc.ncsa.qdl.functions Class Description ExpressionImpl Created by Jeff Gaynor
on 1/13/20 at 3:15 PMExpressionNode This class mostly manages the structure of expressions (so arguments are the children) and evaluating them is delegating the result to theOpEvaluator
class. -
Classes in edu.uiuc.ncsa.qdl.expressions used by edu.uiuc.ncsa.qdl.parsing Class Description Dyad Created by Jeff Gaynor
on 1/13/20 at 3:47 PMExpressionNode This class mostly manages the structure of expressions (so arguments are the children) and evaluating them is delegating the result to theOpEvaluator
class.Monad A post or prefix operator, such a logical not or ++. -
Classes in edu.uiuc.ncsa.qdl.expressions used by edu.uiuc.ncsa.qdl.state Class Description Polyad For multiple arguments. -
Classes in edu.uiuc.ncsa.qdl.expressions used by edu.uiuc.ncsa.qdl.statements Class Description ExpressionNode This class mostly manages the structure of expressions (so arguments are the children) and evaluating them is delegating the result to theOpEvaluator
class. -
Classes in edu.uiuc.ncsa.qdl.expressions used by edu.uiuc.ncsa.qdl.variables Class Description ConstantNode Created by Jeff Gaynor
on 1/13/20 at 4:08 PMExpressionImpl Created by Jeff Gaynor
on 1/13/20 at 3:15 PMExpressionNode This class mostly manages the structure of expressions (so arguments are the children) and evaluating them is delegating the result to theOpEvaluator
class.ExpressionStemNode Created by Jeff Gaynor
on 3/5/21 at 5:58 AMIndexList A simple list of indices for a stem.


Multiselect Test: Remove OptGroup Tags On All Selected.
By selecting all of the options in either the "fruits" or "vegetables" sections of the below Multiselect, the corresponding group header will longer render until one of those options once again becomes deselected.


#{extends 'main.html' /} #{set title:'Claim new project' /} #{set hasForm: true /} #{set 'moreScripts'} #{/set} #{set 'moreStyles'} #{/set}
All of this is purely for reviewing purposes and will never be public.
Keep in mind we will need to review your project claim in order to grant you the right to publish this module. You will be informed by email of the outcome of the review as soon as possible.
Once you are allowed to publish a module, you can publish as many versions of this module as you want, and can grant other people permission to publish new versions on your behalf.


influenza viruses virus avian poultry isolated China human endemic []. transmission -year-old, female zoonotic Unknown province, infection viruses, birds infections Health Potentially G-W [,]. evidence male pathogenic Chicken illness shown Hong chickens wild Mild World lineage .Influenza OrganisationGeneva, Switzerland genes {border-style live receptor studies binding px;} respiratory #ffffff;} -month-old, Guangdong Kong Summary [,,]. countries high highly Chicken, Infect. South likely pandemic potential Assessment, Interface, Virus Yes, circulating gene (HN) Human-Animal Yes bird reassortant recent ‘Eastern’ HN, HPAIV July cases exposure infected internal pathogenicity strains adaptation contact low surveillance China, Dis../eid. However, characterization different farmed humans n/a single A(HN) Africa Bangladesh HN-free ONEe./journal.pone. Pakistan Virol../JVI.- adapted airborne contain ferrets host however, including known related subtype subtypes used AIV Turkey acid markets online: outbreaks particularly vaccination viral ‘Western’ Egypt Figure Furthermore, ILI January LBMs Poultry [,] antigenic appears case confirmed described isolates mammalian novel preference px; regions sialic study sub-lineage transmit tropism virus, {font-family ARI Acad. East Gen. Natl. Sci. Serology Table Virol../s--- [,,,]. analysis appear direct disease distribution font-size infect infection. lineages market mink molecular multiple potentially prevalence reassortment replication review spread suggests swine ... AIVs Asia Asia, Chinese Department Endemic Fever, Hunan Microbiol../j.vetmic... Middle SLN USA./pnas. Viruses [], chicken closely compared containing control double; emergence example, fitness genotype higher hosts major occasionally phenotype predominant route threat –Avian –present .collab: Additionally, Africa, America, American April BJ, ChinaJ. December HNx Infect.e./emi.. Influenza Israel, June Korea LPAIV Microbes North Quail [,,,,]. able allowing assessment, based better border-color border-width broiler caused circulation cleavage common commonly currently distinct dogs domestic evolution experimental farms field following generally genome hemagglutinin human-animal interface, members naturally poultry, present rates receptors remains routes seen serological similar site solid; species stable subtypes, transmissibility vaccinated years {font-style {font-weight α,-linked A/HN Anhui Avian Cambodia, Dis../-R. Egypt, Emerg. Eurasian Europe, G-E, GenBankAvailable HN-like Human Likely Med. Nigeria, Oman Quail, Thailand United Vietnam Vietnam, Virol../JVI...-. Virol../jgv.. West [,,,,,,]. age al.Human allow associated avian-like bold cassette characteristics chickens, clear conditions contemporary continue cough countries, courier; detection droplet early efficient em; epidemiological equine event experimentally factors gastrointestinal genetic genotypes geographical greater haemagglutinin infections. isolation lineages, majority markets, mild minor need neuraminidase new northern outbreak performed phylogenetic pigs polybasic potential. protein pt;} quail range reassortants region relatively repeated reported risk sampling serology seropositivity showed spillover strain subsequent suggest summary tested time unclear using vaccines virus. young –Emerg.


Days after fatal crash, air show canceled due to weather
by The Associated PressSTUART, Fla. (AP) — After vowing to go on following a fatal plane crash days earlier, organizers of a Florida air show are canceling the event because of weather.
Organizers of the Audi Stuart Air Show on Sunday tweeted that they were canceling the show out of safety concerns due to continuing rain.
One of the planned participants was killed Friday while preparing for the show.
Authorities say Dr. Joseph Masessa was running a practice routine when the plane went nose down into the runway. The National Transportation Safety Board was investigating.
Organizers of the air show described Masessa as a beloved performer, and Sunday’s show was being dedicated to him and another aviator.
Bad weather also forced air show events to be canceled on Saturday.
The Associated Press


"Hello! Virtual world"
COOLors Virtual Festival
COOLors Fest unveils the in-venue programming for its 22nd edition, presented from Tuesday, August 24 to Sunday, August 29, which celebrates the many facets of electronic music and digital creativity through 28 eclectic performances. When the summer season winds down and the cultural season begins, the Festival will highlight local and national talents by welcoming nearly sixty artists from all over the world.
The festival extends now to 6 days and nights—and integrates the professional Forum into the architecture of the week to enrich conversations and encounters with current technologically driven practices and philosophies. Tthe festival thrives on creating a context for discovery and exchange. Faithful to its values of inclusion and accessibility, COOLors is committed to a more equitable and representative programming of all diversities, in particular through the Amplify initiative.
Please contact us per Email for any further questions about COOLors Fest 2021!
<EMAIL_ADDRESS>COOLors Virtual Fest 2021 Logo
The logo of COOLors Virtual Fest 2021 was decided through the logo competition from 8 june to 7. July.
COOLors has built a unique model over the years that has proven seductively exportable. Tentacles stretch across 4 continents, to 6 other cities now, with each satellite adapting the festival’s template of values as a means to inspire new ways of engaging with the richness of electronic and digital artistry.
See the past COOLors Fests
Take a look at the last two COOLors festivals wich took place in Quebec and CDMX.


{% extends 'layout.html' %} {% block pageTitle %} State Pension Activation {% endblock %} {% block content %} ALPHA This is a new service – your feedback will help us to improve it. Call the State Pension claim line Monday to Friday, 8am to 6pm (except public holidays) Telephone: 0800 731 7898 Textphone: 0800 731 7339 Send feedback {% endblock %}
ALPHA This is a new service – your feedback will help us to improve it.
Monday to Friday, 8am to 6pm (except public holidays)


Elon Musk spotted hitting the town -- and a sign -- in the Tesla Cybertruck
by Fox NewsTesla's Cybertruck is still making a smash.
Tesla CEO Elon Musk was spotted chauffeuring a few friends to dinner at Nobu in Malibu, Calif., on Saturday night in a prototype of his company's upcoming electric pickup.
The Cybertruck suffered an embarrassing debut in November when its "armor" windows were smashed by a small metal ball tossed at them.
According to TMZ, the Cybertruck was left parked out front with security and attracting much attention while the party was dining. At one point, Musk came out with actor Ed Norton to give him a look.
As it left the restaurant, Musk's friend, musician Grimes, was photographed sitting next to him on the stainless steel vehicle's central front jump seat, which allows the cabin to fit six passengers, as in many conventional pickups.
The night didn't go perfectly, however. Musk was videotaped running over a sign with the full-size truck as he pulled out of the parking lot onto the Pacific Coast Highway.
Musk tweeted earlier in the evening that the production version of the Cybertruck could be slightly smaller to make it easier to fit in a garage.
Regardless, there's still plenty of work left to do as the truck Musk was driving wasn't equipped with side-view mirrors or a visible windshield wiper.


The Build Circuit button will construct a circuit whose gates correspond to the currently chosen expressions for each output. The circuit's inputs and outputs will be displayed in top-down order corresponding to how they appear under the Inputs and Outputs tabs. Generally speaking, the constructed circuit will be attractive; and, indeed, one application of Logisim's Combinational Analysis module is to beautify poorly drawn circuits. Still, as with any automatic formatting, it will not express the structural details that a human-drawn circuit would.
When you click the Build Circuit button, a dialog box will appear prompting you to choose which project where you want the circuit and the name you wish to give it.
If you type the name of an existing circuit, then that circuit will be replaced (after Logisim prompts you to confirm that you really want to do this).
The Build Circuit dialog includes two options. The Use Two-Input Gates Only option specifies that you want all gates constructed to have two inputs. (NOT gates, of course, constitute an exception to this rule.) The Use NAND Gates Only option specifies that you would like it to translate the circuit into one using only NAND gates. You can select both options if you want to use only two-input NAND gates.
Logisim cannot construct a NAND-only circuit for an expression containing any XOR operators. This option will therefore be disabled if any outputs' expressions contain XORs.
Next: User's Guide.


Stephen B. Carman
Republican
Small business owner, U.S. Lawns - Fort Collins.
PhD, Organization and Management, Capella University
80549
I have been a manager in Fortune 100 companies, prior to purchasing the franchise I now own with my wife. These positions require organizing, representing, advocating, and considering the interests of groups I have worked with. I have not previously been involved in any similar tasks as it relates to politics in the state of Colorado. I suspect the activities are similar.
I have only voted in local and national campaigns.
Fort Collins Rescue Mission Harvest Farm
I am interested in getting more involved in the political landscape and view this task of redistricting to be an import responsibility. I believe my background and experience outside of political (especially caustic) environment will contribute a reasoned view and voice to the redistricting process.
I am interested in and believe data and varied perspectives are important contributions to any decision making process. Therefore, discipline must allow for open conversations to ensure all viewpoints have been considered. As one trained in organizational dynamics, I am aware of how dominant personalities can overshadow those who may not be as charismatic in their communication style, and may be tempted (or intimidated) to shut down. I will encourage these individuals to share their perspective and opinions so that we have as much data as possible before any decision is made. This process also allows for unity (e.g., consensus) from a diverse group.
I like to start by having a clear understanding of the problem we are trying to solve. Unless, and until, there is clarity on this question, the potential solutions will be elusive. By having clarity on the problem we are trying to solve, one can rule out a number of potential options that will not help solve the problem. At this point, one can focus energy on the analytical skills, logic, and problem solving skills needed to identify the potential options available for solving the problem. Also important early on is clear understanding of the decision making criteria. I have used this approach with my personal pursuits, as well as in business. The challenge is not so much finding options to solving the problem, but the wisdom (discernment) to identify the solution that best fits the decision-making criteria and provides the best common good for the stakeholders involved.
Male


Projects
Driver Drowsiness Detection using Computer Vision
Athletics Meet Manager
CodeBuzz - Competitive Coding Dashboard
Automatic Text Summarization
Handwritten Digit Recognition
Self Driving Car using Udacity Car Simulator


class: center, middle, inverse, title-slide # ETC3250: Visualisation ## Semester 1, 2020 ###
Professor Di Cook
Econometrics and Business Statistics
Monash University ### Week 5 (a) --- class: split-two .column[.pad50px[ ## Why is visualisation important?
 Consider the following datasets, known as .green[Anscombe's quartet], which all have the same numerical statistical summaries. ]] .column[.content.vmiddle.center[

  set 	  mx 	  my 	  sx 	  sy 	  r

  1 	  9 	  7.5 	  3.32 	  2.03 	  0.82

  2 	  9 	  7.5 	  3.32 	  2.03 	  0.82

  3 	  9 	  7.5 	  3.32 	  2.03 	  0.82

  4 	  9 	  7.5 	  3.32 	  2.03 	  0.82

 ]] --- class: split-two .column[.pad50px[ ## Why is visualisation important?
 Consider the following datasets, known as .green[Anscombe's quartet], which all have the same numerical statistical summaries.
 .orange[Plots provide a more detailed statistical summary.] ]] .column[.content.vmiddle.center[  ]] --- class: split-two .column[.pad50px[ ## Why is visualisation important?
 .tip[Very .orange[different data] can have the .orange[same numerical summaries].] [Datasaurus dozen](https://www.autodeskresearch.com/publications/samestats): all have the same means, standard deviations and correlation, also. ]] .column[.content.vmiddle.center[  ]] --- ## Why is visualisation important?
 In machine learning visualisation is used for: - .orange[Initial data analysis]: to examine whether the data - satisfies assumptions required for the method - has unexpected complications like outliers or nonlinearity - .orange[Assess the model fit]: - predicted vs observed - residuals - boundaries between classes --- ## High dimensional visualisation Common methods for visualising high-dimensions - Tour - Parallel coordinate plot - Scatterplot matrix - Mosaic plot Most of what you find when you google "visualising high-dimensions" is awful, e.g. use colour and symbol after 3D to show 5D; PCA, MDS, tSNE, are visualisation methods; "you can't see beyond 3D".... Rubbish! --- ## Dimensionality
    - When you add another variable, you implicitly add another orthogonal axis. - The space is effectively a `\(p\)`-dimensional cube - The data might not fill the cube, and then dimension reduction might make it a `\(k(<p)\)`-dimensional cube --- class: split-two .column[.pad50px[ ## Grand tours
 A .orange[grand tour] is by definition a movie of low-dimensional projections constructed in such a way that it comes arbitrarily close to showing all possible low-dimensional projections; in other words, a grand tour is a space-filling curve in the manifold of low-dimensional projections of high-dimensional data spaces. ]] .column[.content.vmiddle.center[  ]] --- class: split-two .column[.pad50px[ ## Notation - `\({\mathbf x}_i \in \mathcal{R}^p\)`, `\(i^{th}\)` data vector - `\(d\)` projection dimension - `\(F\)` is a `\(p\times d\)` orthonormal basis, `\(F'F=I_d\)` - The projection of `\({\mathbf x}\)` onto `\(F\)` is `\({\mathbf y}_i=F'{\mathbf x}_i\)`. - Its a movie, so the tour is indexed by time, `\(F(t)\)`, where `\(t\in [a, z]\)`. Starting and target frame denoted as `\(F_a = F(a), F_z=F(t)\)`. - The animation of the projected data is given by a path `\({\mathbf y}_i(t)=F'(t){\mathbf x}_i\)`. ]] .column[.content.vmiddle.center[  ]] --- ## Examples `\(p=3, d=2\)`   --- ## Examples `\(p=6, d=2\)`   --- ## Examples `\(p=7, d=2\)`   --- ## Examples
 With the grand tour, you can get a good overall sense of the distribution (shape) of the data in its `\(p\)`-dimensional space: - In the first data set, the primary shape are .orange[three well separated clusters] - In the track data, the primary shape is that it lives in essentially a .orange[1-D] subspace, with a small amount of variation in other directions. It is also possible to see several .orange[outliers]. --- ## Guided tours .tip[.font_small[.content[ Remember: projection pursuit `$$\mathop{\text{maximize}}_{\phi_{11},\dots,\phi_{p1}} f\left(\sum_{j=1}^p \phi_{j1}x_{ij}\right) \text{ subject to } \sum_{j=1}^p \phi^2_{j1} = 1$$` ]]] The guided tour chooses new target projections by optimising a function of interest: .font_small[ - `holes`: This is an inverse Gaussian filter, which is optimised wheren there is not much data in the center of the projection, i.e. a "hole" or donut shape in 2D. - `central mass`: The opposite of holes, high density in the centre of the projection, and often "outliers" on the edges. - `LDA`: An index based on the linear discrimination dimension reduction, optimised by projections where the named classes are most separated. ] --- ## Guided tours `\(p=6, d=2,\)` guidance using the LDA index   --- ## Usage - in R To run a tour live: ```r library(tourr) # On a Mac use this graphics device # quartz() animate_xy(flea[, 1:6]) animate(flea[, 1:6], tour_path=grand_tour(), display=display_xy(axes = "bottomleft")) library(RColorBrewer) pal <- brewer.pal(3, "Dark2") col <- pal[as.numeric(flea$species)] animate_xy(flea[,-7], col=col) ``` --- ## Others
 - .orange[Little]: Interpolates between all possible pairs of variables. Like the scatterplot matrix, but animated between them. - .orange[Local]: Rocks back and forth from a given projection, so shows all possible projections within a radius. - .orange[Frozen]: Fixes some of the values of the orthonormal projection matrix and allows the others to vary freely according to any of the other tour methods. - .orange[Manual]: Control the contribution of a single variable, and move along this axis. This is really useful to examine the sensitivity of structure (e.g. clustering) to the contribution of a variable. Maybe the variable can be "zero'd out" and the structure would not be affected, thus simplifying the "model". This is available in the .orange[spinifex] package. --- ## Rendering
 .tip[The projection dimension `\\(d\\)` can be 1, 2, 3, ... It is just a projection of the data, and then you need to decide how to *render* the data.]
 - *d=1* : The projected data can be displayed as a dotplot, density, histogram, boxplot, ... - *d>2* : Use stereo (for *d=3* ) or a scatterplot matrix (or parallel coordinate plot) --- layout: false # 👩💻 Made by a human with a computer ### Slides at [https://monba.dicook.org](https://monba.dicook.org). ### Code and data at [https://github.com/dicook/Business_Analytics](https://github.com/dicook/Business_Analytics).
 ### Created using [R Markdown](https://rmarkdown.rstudio.com) with flair by [**xaringan**](https://github.com/yihui/xaringan), and [**kunoichi** (female ninja) style](https://github.com/emitanaka/ninja-theme).

This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.


grpc_wait_all
- Waits until all sessions have ended.
grpc_error_t grpc_wait_all()
None
The grpc_wait_all() function waits for all of the executing sessions to end. When no executing sessions exist, the grpc_wait_all() returns GRPC_NOERROR.
This function is MT-unsafe.
If successful, GRPC_NO_ERROR is returned. In the case of an error, Error code is returned.
GRPC_NOT_INITIALIZED
GRPC_SESSION_FAILED
GRPC_TIMEOUT_NP
GRPC_OTHER_ERROR_CODE


This project includes a sample component using LitElement with TypeScript.
Install dependencies:
npm i
This sample uses the TypeScript compiler to produce JavaScript that runs in modern browsers.
To build the JavaScript version of your component:
npm run build
To watch files and rebuild when the files are modified, run the following command in a separate shell:
npm run build:watch
Both the TypeScript compiler and lit-analyzer are configured to be very strict. You may want to change tsconfig.json
to make them less strict.
This sample uses modern-web.dev's @web/test-runner along with Mocha, Chai, and some related helpers for testing. See the modern-web.dev testing documentation for more information.
Tests can be run with the test
script:
npm test
This sample uses modern-web.dev's @web/dev-server for previewing the project without additional build steps. Web Dev Server handles resolving Node-style "bare" import specifiers, which aren't supported in browsers. It also automatically transpiles JavaScript and adds polyfills to support older browsers. See modern-web.dev's Web Dev Server documentation for more information.
To run the dev server and open the project in a new browser tab:
npm run serve
There is a development HTML file located at /dev/index.html
that you can view at http://localhost:8000/dev/index.html.
If you use VS Code, we highly recommend the lit-plugin extension, which enables some extremely useful features for lit-html templates:
The project is setup to recommend lit-plugin to VS Code users if they don't already have it installed.
Linting of TypeScript files is provided by ESLint and TypeScript ESLint. In addition, lit-analyzer is used to type-check and lint lit-html templates with the same engine and rules as lit-plugin.
The rules are mostly the recommended rules from each project, but some have been turned off to make LitElement usage easier. The recommended rules are pretty strict, so you may want to relax them by editing .eslintrc.json
and tsconfig.json
.
To lint the project run:
npm run lint
Prettier is used for code formatting. It has been pre-configured according to the Polymer Project's style. You can change this in .prettierrc.json
.
Prettier has not been configured to run when committing files, but this can be added with Husky and and pretty-quick
. See the prettier.io site for instructions.
This project includes a simple website generated with the eleventy static site generator and the templates and pages in /docs-src
. The site is generated to /docs
and intended to be checked in so that GitHub pages can serve the site from /docs
on the master branch.
To enable the site go to the GitHub settings and change the GitHub Pages "Source" setting to "master branch /docs folder".
To build the site, run:
npm run docs
To serve the site locally, run:
npm run docs:serve
To watch the site files, and re-build automatically, run:
npm run docs:watch
The site will usually be served at http://localhost:8000.
This starter project doesn't include any build-time optimizations like bundling or minification. We recommend publishing components as unoptimized JavaScript modules, and performing build-time optimizations at the application level. This gives build tools the best chance to deduplicate code, remove dead code, and so on.
For information on building application projects that include LitElement components, see Build for production on the Lit site.
See Get started on the Lit site for more information.
Generated using TypeDoc


Input the URL of the
.json
file that contains
the list of the search engine with the needed data (if none, the default database will be used).


A warm welcome to you, please feel free and be my guest!
Hello & Welcome! My name is Jon, I’m a web developer with a degree in supply chain and a background in search results and landing pages evaluations.
My interest for web building dates back long ago when I learned HTML & CSS on my own. After management changes in my supply chain job, I asked myself what I would like to do most disregard my formal training. So I started my career change as a consultant working to improve the relevancy of search results generated by the search engine Bing and to evaluate landing pages. After a couple of years, thousands of landing pages later. I decided to take a deep dive into coding school for the Web Development Immersive Program. And really find out how sites are put together, what powers the web, & how it all works!
Ultimately, it’s about learning new skills, it’s about finding innovative & better ways of doing things, it’s about building things, and last but not least, it’s about creativity & ingenuity. I’m open-minded, organized, & dedicated to my work. Once I had a last minute bug that I stayed up until I found a solution at 4:30AM and met the deadline the next day. My goal is to build creative apps & websites that benefit the organization & the user, making the web a better place.
Check out my projectsNetworking
Repositories
Write something
Absolutely essential!
Thanks for dropping by! I love developing websites and apps. And if I'm not busy on the computer, I like to play ukulele and make food from scratch. There's just something about enjoying the food you make and sharing it with family and friends. Comments and questions are always welcomed. Happy Coding!