Add cheatsheets section (Proxmox CLI, zsh config reference)
Lower-bar reference material, distinct from docs/'s engineering write-ups: recovered Proxmox cheat sheets (live-verified against PVE 9.2.21, new remote-migrate/importovf/pvesm subcommands added, acmedomain0 flag typo fixed) plus the real zsh aliases/functions/keybindings from the actual ZDOTDIR-based config.
This commit is contained in:
6 files changed
+956
No files matched your search
@@ -135,6 +135,12 @@ A self-hosted WireGuard mesh gives every fleet host and personal device its own
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Cheatsheets
|
||||||
|
|
||||||
|
Quick-reference material for tools I use day-to-day — command references and config notes, not full write-ups. See [`cheatsheets/`](cheatsheets/).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Scripts & Tooling
|
## Scripts & Tooling
|
||||||
|
|
||||||
A few standalone scripts live in [`projects/`](projects/) alongside the Docker stacks — real tooling, not demo code:
|
A few standalone scripts live in [`projects/`](projects/) alongside the Docker stacks — real tooling, not demo code:
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Cheatsheets
|
||||||
|
|
||||||
|
Quick-reference material, not deep dives. The [`docs/`](../docs/) directory is
|
||||||
|
where the real engineering write-ups live — verified claims, real evidence,
|
||||||
|
the actual design decisions behind each system. This directory is lower-key:
|
||||||
|
command references and config notes for tools I use day-to-day, kept here so
|
||||||
|
they're easy to find and easy to add to.
|
||||||
|
|
||||||
|
- **[proxmox/](proxmox/)** — CLI cheat sheet for the hypervisor cluster this
|
||||||
|
fleet runs on (`qm`/`pct`/`pvesm`/`pveam`), plus API token auth and
|
||||||
|
certificate management notes.
|
||||||
|
- **[zsh/](zsh/)** — the aliases, functions, and keybindings from my actual
|
||||||
|
zsh config, not a generic zsh tutorial.
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
## Create an API Token on Proxmox
|
||||||
|
|
||||||
|
To create a new API Token for your `user` in Proxmox, follow these steps:
|
||||||
|
|
||||||
|
1. Open the Proxmox Web UI and navigate to the **'Datacenter'** in the **'Server View'** menu.
|
||||||
|
2. Select **'API Token'** in the **'Permissions'** menu.
|
||||||
|
3. Click on **'Add'**.
|
||||||
|
4. Select the `user`, and add a **'Token ID'**.
|
||||||
|
5. (Optional) Disable `Privilege Separation`, and set an `Expire` date.
|
||||||
|
6. Click on **'Add'**.
|
||||||
|
|
||||||
|
## Check the API Token
|
||||||
|
|
||||||
|
To test the API Token, you can use the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -H "Authorization: PVEAPIToken=root@pam!monitoring=aaaaaaaaa-bbb-cccc-dddd-ef0123456789" https://your-proxmox-url:8006/api2/json/
|
||||||
|
```
|
||||||
@@ -0,0 +1,324 @@
|
|||||||
|
## Certificates for Intra-Cluster Communication
|
||||||
|
|
||||||
|
Each Proxmox VE cluster creates by default its own (self-signed) Certificate
|
||||||
|
Authority (CA) and generates a certificate for each node which gets signed by
|
||||||
|
the aforementioned CA. These certificates are used for encrypted communication
|
||||||
|
with the cluster's pveproxy service and the Shell/Console feature if SPICE is used.
|
||||||
|
|
||||||
|
The CA certificate and key are stored in the Proxmox Cluster File System (pmxcfs).
|
||||||
|
|
||||||
|
## Certificates for API and Web GUI
|
||||||
|
|
||||||
|
The REST API and web GUI are provided by the pveproxy service, which runs on each node.
|
||||||
|
You have the following options for the certificate used by pveproxy:
|
||||||
|
|
||||||
|
* By default the node-specific certificate in `/etc/pve/nodes/NODENAME/pve-ssl.pem` is used. This certificate is signed by the cluster CA and therefore not automatically trusted by browsers and operating systems.
|
||||||
|
* Use an externally provided certificate (e.g. signed by a commercial CA).
|
||||||
|
* Use ACME (Let's Encrypt) to get a trusted certificate with automatic renewal, this is also integrated in the Proxmox VE API and web interface.
|
||||||
|
|
||||||
|
For options 2 and 3 the file `/etc/pve/local/pveproxy-ssl.pem` (and
|
||||||
|
`/etc/pve/local/pveproxy-ssl.key`, which needs to be without password) is used.
|
||||||
|
Keep in mind that `/etc/pve/local` is a node specific symlink to
|
||||||
|
`/etc/pve/nodes/NODENAME`.
|
||||||
|
|
||||||
|
Certificates are managed with the Proxmox VE Node management command
|
||||||
|
(see the `pvenode(1)` manpage). The current node certificate's details can
|
||||||
|
be checked directly from the CLI too:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
pvenode cert info [FORMAT_OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not replace or manually modify the automatically generated node
|
||||||
|
certificate files in `/etc/pve/local/pve-ssl.pem` and
|
||||||
|
`/etc/pve/local/pve-ssl.key` or the cluster CA files in
|
||||||
|
`/etc/pve/pve-root-ca.pem` and `/etc/pve/priv/pve-root-ca.key`.
|
||||||
|
|
||||||
|
## Upload Custom Certificate
|
||||||
|
|
||||||
|
If you already have a certificate which you want to use for a Proxmox VE node
|
||||||
|
you can upload that certificate simply over the web interface. Note that the
|
||||||
|
certificates key file, if provided, mustn't be password protected.
|
||||||
|
|
||||||
|
## Trusted certificates via Let's Encrypt (ACME)
|
||||||
|
|
||||||
|
Proxmox VE includes an implementation of the Automatic Certificate
|
||||||
|
Management Environment ACME protocol, allowing Proxmox VE admins to
|
||||||
|
use an ACME provider like Let's Encrypt for easy setup of TLS certificates
|
||||||
|
which are accepted and trusted on modern operating systems and web browsers
|
||||||
|
out of the box.
|
||||||
|
|
||||||
|
Currently, the two ACME endpoints implemented are the
|
||||||
|
Let's Encrypt (LE) production and its staging
|
||||||
|
environment. Our ACME client supports validation of http-01 challenges using
|
||||||
|
a built-in web server and validation of dns-01 challenges using a DNS plugin
|
||||||
|
supporting all the DNS API endpoints `acme.sh` does.
|
||||||
|
|
||||||
|
### ACME Account
|
||||||
|
|
||||||
|
You need to register an ACME account per cluster with the endpoint you want to
|
||||||
|
use. The email address used for that account will serve as contact point for
|
||||||
|
renewal-due or similar notifications from the ACME endpoint.
|
||||||
|
You can register and deactivate ACME accounts over the web interface
|
||||||
|
`Datacenter -> ACME` or using the `pvenode` command line tool.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
pvenode acme account register account-name [email protected]
|
||||||
|
```
|
||||||
|
|
||||||
|
Because of rate-limits you should use LE staging for experiments or if you use
|
||||||
|
ACME for the first time.
|
||||||
|
|
||||||
|
### ACME Plugins
|
||||||
|
|
||||||
|
The ACME plugins task is to provide automatic verification that you, and thus
|
||||||
|
the Proxmox VE cluster under your operation, are the real owner of a domain. This is
|
||||||
|
the basis building block for automatic certificate management.
|
||||||
|
|
||||||
|
The ACME protocol specifies different types of challenges, for example the
|
||||||
|
http-01 where a web server provides a file with a certain content to prove
|
||||||
|
that it controls a domain. Sometimes this isn't possible, either because of
|
||||||
|
technical limitations or if the address of a record to is not reachable from
|
||||||
|
the public internet. The dns-01 challenge can be used in these cases. This
|
||||||
|
challenge is fulfilled by creating a certain DNS record in the domain's zone.
|
||||||
|
|
||||||
|
Proxmox VE supports both of those challenge types out of the box, you can configure
|
||||||
|
plugins either over the web interface under `Datacenter -> ACME`, or using the
|
||||||
|
`pvenode acme plugin add` command.
|
||||||
|
|
||||||
|
ACME Plugin configurations are stored in `/etc/pve/priv/acme/plugins.cfg`.
|
||||||
|
A plugin is available for all nodes in the cluster.
|
||||||
|
|
||||||
|
### Node Domains
|
||||||
|
|
||||||
|
Each domain is node specific. You can add new or manage existing domain entries
|
||||||
|
under Node -> Certificates, or using the `pvenode config` command.
|
||||||
|
|
||||||
|
After configuring the desired domain(s) for a node and ensuring that the
|
||||||
|
desired ACME account is selected, you can order your new certificate over the
|
||||||
|
web-interface. On success the interface will reload after 10 seconds.
|
||||||
|
|
||||||
|
Renewal will happen automatically.
|
||||||
|
|
||||||
|
## ACME HTTP Challenge Plugin
|
||||||
|
|
||||||
|
There is always an implicitly configured standalone plugin for validating
|
||||||
|
http-01 challenges via the built-in webserver spawned on port 80.
|
||||||
|
|
||||||
|
The name `standalone` means that it can provide the validation on it's
|
||||||
|
own, without any third party service. So, this plugin works also for cluster
|
||||||
|
nodes.
|
||||||
|
|
||||||
|
There are a few prerequisites to use it for certificate management with Let's
|
||||||
|
Encrypts ACME.
|
||||||
|
|
||||||
|
* You have to accept the ToS of Let's Encrypt to register an account.
|
||||||
|
* Port 80 of the node needs to be reachable from the internet.
|
||||||
|
* There must be no other listener on port 80.
|
||||||
|
* The requested (sub)domain needs to resolve to a public IP of the Node.
|
||||||
|
|
||||||
|
## ACME DNS API Challenge Plugin
|
||||||
|
|
||||||
|
On systems where external access for validation via the http-01 method is
|
||||||
|
not possible or desired, it is possible to use the dns-01 validation method.
|
||||||
|
This validation method requires a DNS server that allows provisioning of TXT
|
||||||
|
records via an API.
|
||||||
|
|
||||||
|
### Configuring ACME DNS APIs for validation
|
||||||
|
|
||||||
|
Proxmox VE re-uses the DNS plugins developed for the
|
||||||
|
[acme.sh project](https://github.com/acmesh-official/acme.sh). Please
|
||||||
|
refer to its documentation for details on configuration of specific APIs.
|
||||||
|
|
||||||
|
The easiest way to configure a new plugin with the DNS API is using the web
|
||||||
|
interface (`Datacenter -> ACME`).
|
||||||
|
|
||||||
|
Choose DNS as challenge type. Then you can select your API provider, enter
|
||||||
|
the credential data to access your account over their API.
|
||||||
|
|
||||||
|
See the `acme.sh`
|
||||||
|
[How to use DNS API](https://github.com/acmesh-official/acme.sh/wiki/dnsapi#how-to-use-dns-api)
|
||||||
|
wiki for more detailed information about getting API credentials for your
|
||||||
|
provider.
|
||||||
|
|
||||||
|
As there are many DNS providers and API endpoints Proxmox VE automatically generates
|
||||||
|
the form for the credentials for some providers. For the others you will see a
|
||||||
|
bigger text area, simply copy all the credentials KEY=VALUE pairs in there.
|
||||||
|
|
||||||
|
## DNS Validation through CNAME Alias
|
||||||
|
|
||||||
|
A special alias mode can be used to handle the validation on a different
|
||||||
|
domain/DNS server, in case your primary/real DNS does not support provisioning
|
||||||
|
via an API. Manually set up a permanent CNAME record for
|
||||||
|
`_acme-challenge.domain1.example` pointing to `_acme-challenge.domain2.example`
|
||||||
|
and set the alias property in the Proxmox VE node configuration file to
|
||||||
|
`domain2.example` to allow the DNS server of `domain2.example` to validate all
|
||||||
|
challenges for `domain1.example`.
|
||||||
|
|
||||||
|
### Combination of Plugins
|
||||||
|
|
||||||
|
Combining http-01 and dns-01 validation is possible in case your node is
|
||||||
|
reachable via multiple domains with different requirements / DNS provisioning
|
||||||
|
capabilities. Mixing DNS APIs from multiple providers or instances is also
|
||||||
|
possible by specifying different plugin instances per domain.
|
||||||
|
Accessing the same service over multiple domains increases complexity and
|
||||||
|
should be avoided if possible.
|
||||||
|
|
||||||
|
## Automatic renewal of ACME certificates
|
||||||
|
|
||||||
|
If a node has been successfully configured with an ACME-provided certificate
|
||||||
|
(either via `pvenode` or via the GUI), the certificate will be automatically
|
||||||
|
renewed by the `pve-daily-update.service`. Currently, renewal will be attempted
|
||||||
|
if the certificate has expired already, or will expire in the next 30 days.
|
||||||
|
A certificate can also be renewed directly, on demand:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
pvenode acme cert renew [OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
## ACME Examples with pvenode
|
||||||
|
|
||||||
|
*Example*: Sample `pvenode` invocation for using Let's Encrypt certificates
|
||||||
|
|
||||||
|
```sh
|
||||||
|
root@proxmox:~# pvenode acme account register default [email protected]
|
||||||
|
Directory endpoints:
|
||||||
|
0) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory)
|
||||||
|
1) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory)
|
||||||
|
2) Custom
|
||||||
|
Enter selection: 1
|
||||||
|
Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
|
||||||
|
Do you agree to the above terms? [y|N]y
|
||||||
|
...
|
||||||
|
Task OK
|
||||||
|
root@proxmox:~# pvenode config set --acme domains=example.invalid
|
||||||
|
root@proxmox:~# pvenode acme cert order
|
||||||
|
Loading ACME account details
|
||||||
|
Placing ACME order
|
||||||
|
...
|
||||||
|
Status is 'valid'!
|
||||||
|
All domains validated!
|
||||||
|
...
|
||||||
|
Downloading certificate
|
||||||
|
Setting pveproxy certificate and key
|
||||||
|
Restarting pveproxy
|
||||||
|
Task OK
|
||||||
|
```
|
||||||
|
|
||||||
|
*Example*: Setting up the OVH API for validating a domain
|
||||||
|
|
||||||
|
The account registration steps are the same no matter which plugins are
|
||||||
|
used, and are not repeated here.
|
||||||
|
|
||||||
|
OVH_AK and OVH_AS need to be obtained from OVH according to the OVH
|
||||||
|
API documentation
|
||||||
|
|
||||||
|
First you need to get all information so you and Proxmox VE can access the API.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
root@proxmox:~# cat /path/to/api-token
|
||||||
|
OVH_AK=XXXXXXXXXXXXXXXX
|
||||||
|
OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
|
||||||
|
root@proxmox:~# source /path/to/api-token
|
||||||
|
root@proxmox:~# curl -XPOST -H"X-Ovh-Application: $OVH_AK" -H "Content-type: application/json" \
|
||||||
|
https://eu.api.ovh.com/1.0/auth/credential -d '{
|
||||||
|
"accessRules": [
|
||||||
|
{"method": "GET","path": "/auth/time"},
|
||||||
|
{"method": "GET","path": "/domain"},
|
||||||
|
{"method": "GET","path": "/domain/zone/*"},
|
||||||
|
{"method": "GET","path": "/domain/zone/*/record"},
|
||||||
|
{"method": "POST","path": "/domain/zone/*/record"},
|
||||||
|
{"method": "POST","path": "/domain/zone/*/refresh"},
|
||||||
|
{"method": "PUT","path": "/domain/zone/*/record/"},
|
||||||
|
{"method": "DELETE","path": "/domain/zone/*/record/*"}
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
{"consumerKey":"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ","state":"pendingValidation","validationUrl":"https://eu.api.ovh.com/auth/?credentialToken=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}
|
||||||
|
(open validation URL and follow instructions to link Application Key with account/Consumer Key)
|
||||||
|
root@proxmox:~# echo "OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" >> /path/to/api-token
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can setup the ACME plugin:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
root@proxmox:~# pvenode acme plugin add dns example_plugin --api ovh --data /path/to/api_token
|
||||||
|
root@proxmox:~# pvenode acme plugin config example_plugin
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────────┬──────────────────────────────────────────┐
|
||||||
|
│ key │ value │
|
||||||
|
╞════════╪══════════════════════════════════════════╡
|
||||||
|
│ api │ ovh │
|
||||||
|
├────────┼──────────────────────────────────────────┤
|
||||||
|
│ data │ OVH_AK=XXXXXXXXXXXXXXXX │
|
||||||
|
│ │ OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY │
|
||||||
|
│ │ OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ │
|
||||||
|
├────────┼──────────────────────────────────────────┤
|
||||||
|
│ digest │ 867fcf556363ca1bea866863093fcab83edf47a1 │
|
||||||
|
├────────┼──────────────────────────────────────────┤
|
||||||
|
│ plugin │ example_plugin │
|
||||||
|
├────────┼──────────────────────────────────────────┤
|
||||||
|
│ type │ dns │
|
||||||
|
└────────┴──────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
At last you can configure the domain you want to get certificates for and
|
||||||
|
place the certificate order for it:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
root@proxmox:~# pvenode config set --acmedomain0 example.proxmox.com,plugin=example_plugin
|
||||||
|
root@proxmox:~# pvenode acme cert order
|
||||||
|
Loading ACME account details
|
||||||
|
Placing ACME order
|
||||||
|
Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/11111111/22222222
|
||||||
|
Getting authorization details from 'https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/33333333'
|
||||||
|
The validation for example.proxmox.com is pending!
|
||||||
|
[Wed Apr 22 09:25:30 CEST 2020] Using OVH endpoint: ovh-eu
|
||||||
|
[Wed Apr 22 09:25:30 CEST 2020] Checking authentication
|
||||||
|
[Wed Apr 22 09:25:30 CEST 2020] Consumer key is ok.
|
||||||
|
[Wed Apr 22 09:25:31 CEST 2020] Adding record
|
||||||
|
[Wed Apr 22 09:25:32 CEST 2020] Added, sleep 10 seconds.
|
||||||
|
Add TXT record: _acme-challenge.example.proxmox.com
|
||||||
|
Triggering validation
|
||||||
|
Sleeping for 5 seconds
|
||||||
|
Status is 'valid'!
|
||||||
|
[Wed Apr 22 09:25:48 CEST 2020] Using OVH endpoint: ovh-eu
|
||||||
|
[Wed Apr 22 09:25:48 CEST 2020] Checking authentication
|
||||||
|
[Wed Apr 22 09:25:48 CEST 2020] Consumer key is ok.
|
||||||
|
Remove TXT record: _acme-challenge.example.proxmox.com
|
||||||
|
All domains validated!
|
||||||
|
Creating CSR
|
||||||
|
Checking order status
|
||||||
|
Order is ready, finalizing order
|
||||||
|
valid!
|
||||||
|
Downloading certificate
|
||||||
|
Setting pveproxy certificate and key
|
||||||
|
Restarting pveproxy
|
||||||
|
Task OK
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example: Switching from the staging to the regular ACME directory
|
||||||
|
|
||||||
|
Changing the ACME directory for an account is unsupported, but as Proxmox VE
|
||||||
|
supports more than one account you can just create a new one with the
|
||||||
|
production (trusted) ACME directory as endpoint. You can also deactivate the
|
||||||
|
staging account and recreate it.
|
||||||
|
|
||||||
|
*Example*: Changing the default ACME account from staging to directory using `pvenode`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
root@proxmox:~# pvenode acme account deactivate default
|
||||||
|
Renaming account file from '/etc/pve/priv/acme/default' to '/etc/pve/priv/acme/_deactivated_default_4'
|
||||||
|
Task OK
|
||||||
|
root@proxmox:~# pvenode acme account register default [email protected]
|
||||||
|
Directory endpoints:
|
||||||
|
0) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory)
|
||||||
|
1) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory)
|
||||||
|
2) Custom
|
||||||
|
Enter selection: 0
|
||||||
|
Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
|
||||||
|
Do you agree to the above terms? [y|N]y
|
||||||
|
...
|
||||||
|
Task OK
|
||||||
|
```
|
||||||
@@ -0,0 +1,426 @@
|
|||||||
|
Proxmox Virtual Environment (Proxmox VE or PVE) is a hyper-converged infrastructure open-source software. It is a hosted hypervisor that can run operating systems including Linux and Windows on x64 hardware. It is a Debian-based Linux distribution with a modified Ubuntu LTS kernel and allows deployment and management of virtual machines and containers. Proxmox VE includes a web console and command-line tools, and provides a REST API for third-party tools. Two types of virtualization are supported: container-based with LXC (starting from version 4.0 replacing OpenVZ used in version up to 3.4, included), and full virtualization with KVM. It includes a web-based management interface.
|
||||||
|
|
||||||
|
Proxmox VE is licensed under the GNU Affero General Public License, version 3.
|
||||||
|
|
||||||
|
Repository: [https://git.proxmox.com](https://git.proxmox.com)
|
||||||
|
Website: [https://pve.proxmox.com](https://pve.proxmox.com)
|
||||||
|
|
||||||
|
## VM Management
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# list VMs
|
||||||
|
qm list
|
||||||
|
|
||||||
|
# Create or restore a virtual machine.
|
||||||
|
qm create your-vm-id
|
||||||
|
|
||||||
|
# start a VM
|
||||||
|
qm start your-vm-id
|
||||||
|
|
||||||
|
# Suspend virtual machine.
|
||||||
|
qm suspend your-vm-id
|
||||||
|
|
||||||
|
# shutdown a VM
|
||||||
|
qm shutdown your-vm-id
|
||||||
|
|
||||||
|
# reboot a VM
|
||||||
|
qm reboot your-vm-id
|
||||||
|
|
||||||
|
# reset a VM
|
||||||
|
qm reset your-vm-id
|
||||||
|
|
||||||
|
# stop a VM
|
||||||
|
qm stop your-vm-id
|
||||||
|
|
||||||
|
# Destroy the VM and all used/owned volumes.
|
||||||
|
# Removes any VM specific permissions and firewall rules
|
||||||
|
qm destroy your-vm-id
|
||||||
|
|
||||||
|
# Enter Qemu Monitor interface.
|
||||||
|
qm monitor your-vm-id
|
||||||
|
|
||||||
|
# Get the virtual machine configuration with both current and pending values.
|
||||||
|
qm pending your-vm-id
|
||||||
|
|
||||||
|
# Get the virtual machine configuration with pending changes applied.
|
||||||
|
qm config your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Send key event to virtual machine.
|
||||||
|
qm sendkey your-vm-id your-key-event [OPTIONS]
|
||||||
|
|
||||||
|
# Show command line which is used to start the VM (debug info).
|
||||||
|
qm showcmd your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Unlock the VM.
|
||||||
|
qm unlock your-vm-id
|
||||||
|
|
||||||
|
# Clone a VM
|
||||||
|
qm clone your-vm-id new-vm-id
|
||||||
|
|
||||||
|
# Migrate a VM
|
||||||
|
qm migrate your-vm-id target-node
|
||||||
|
|
||||||
|
# Migrate a VM to a remote cluster. EXPERIMENTAL.
|
||||||
|
qm remote-migrate your-vm-id target-endpoint --target-bridge <string> --target-storage <string> [OPTIONS]
|
||||||
|
|
||||||
|
# Create a new VM from an OVF manifest.
|
||||||
|
qm importovf your-vm-id <manifest> <storage> [OPTIONS]
|
||||||
|
|
||||||
|
# Enroll updated UEFI certificates to the EFI disk.
|
||||||
|
qm enroll-efi-keys your-vm-id
|
||||||
|
|
||||||
|
# Show VM status
|
||||||
|
qm status your-vm-id
|
||||||
|
|
||||||
|
# Wait until the VM is stopped.
|
||||||
|
qm wait your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Clean up resources for a VM
|
||||||
|
qm cleanup your-vm-id your-clean-shutdown your-guest-requested
|
||||||
|
|
||||||
|
# Create a Template.
|
||||||
|
qm template your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Set virtual machine options (synchrounous API)
|
||||||
|
qm set your-vm-id [OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cloudinit
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Get automatically generated cloudinit config.
|
||||||
|
qm cloudinit dump your-vm-id your-vm-type
|
||||||
|
|
||||||
|
# Get the cloudinit configuration with both current and pending values.
|
||||||
|
qm cloudinit pending your-vm-id
|
||||||
|
|
||||||
|
# Regenerate and change cloudinit config drive.
|
||||||
|
qm cloudinit update your-vm-id
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disk
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Import an external disk image as an unused disk in a VM.
|
||||||
|
# The image format has to be supported by qemu-img(1).
|
||||||
|
qm disk import your-vm-id your-target-source your-target-storage
|
||||||
|
|
||||||
|
# Move volume to different storage or to a different VM.
|
||||||
|
qm disk move your-vm-id your-vm-disk [<storage>] [OPTIONS]
|
||||||
|
|
||||||
|
# Rescan all storages and update disk sizes and unused disk images.
|
||||||
|
qm disk rescan [OPTIONS]
|
||||||
|
|
||||||
|
# Extend volume size.
|
||||||
|
qm disk resize your-vm-id your-vm-disk <size> [OPTIONS]
|
||||||
|
|
||||||
|
# Unlink/delete disk images.
|
||||||
|
qm disk unlink your-vm-id --idlist <string> [OPTIONS]
|
||||||
|
|
||||||
|
# rescan volumes
|
||||||
|
qm rescan
|
||||||
|
```
|
||||||
|
|
||||||
|
### Snapshot
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# List all snapshots.
|
||||||
|
qm listsnapshot your-vm-id
|
||||||
|
|
||||||
|
# Snapshot a VM
|
||||||
|
qm snapshot your-vm-id <snapname>
|
||||||
|
|
||||||
|
# Delete a snapshot.
|
||||||
|
qm delsnapshot your-vm-id <snapname>
|
||||||
|
|
||||||
|
# Rollback a snapshot
|
||||||
|
qm rollback your-vm-id <snapname>
|
||||||
|
|
||||||
|
# Open a terminal using a serial device
|
||||||
|
# (The VM need to have a serial device configured, for example serial0: socket)
|
||||||
|
qm terminal your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Proxy VM VNC traffic to stdin/stdout
|
||||||
|
qm vncproxy your-vm-id
|
||||||
|
```
|
||||||
|
|
||||||
|
### Misc
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Execute Qemu Guest Agent commands.
|
||||||
|
qm guest cmd your-vm-id <command>
|
||||||
|
|
||||||
|
# Executes the given command via the guest agent
|
||||||
|
qm guest exec your-vm-id [<extra-args>] [OPTIONS]
|
||||||
|
|
||||||
|
# Gets the status of the given pid started by the guest-agent
|
||||||
|
qm guest exec-status your-vm-id <pid>
|
||||||
|
|
||||||
|
# Sets the password for the given user to the given password
|
||||||
|
qm guest passwd your-vm-id <username> [OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
### PV, VG, LV Management
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Create a PV
|
||||||
|
pvcreate <disk-device-name>
|
||||||
|
|
||||||
|
# Remove a PV
|
||||||
|
pvremove <disk-device-name>
|
||||||
|
|
||||||
|
# List all PVs
|
||||||
|
pvs
|
||||||
|
|
||||||
|
# Create a VG
|
||||||
|
vgcreate <vg-name> <disk-device-name>
|
||||||
|
|
||||||
|
# Remove a VG
|
||||||
|
vgremove <vg-name>
|
||||||
|
|
||||||
|
# List all VGs
|
||||||
|
vgs
|
||||||
|
|
||||||
|
# Create a LV
|
||||||
|
lvcreate -L <lv-size> -n <lv-name> <vg-name>
|
||||||
|
|
||||||
|
# Remove a LV
|
||||||
|
lvremove <vg-name>/<lv-name>
|
||||||
|
|
||||||
|
# List all LVs
|
||||||
|
lvs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Storage Management
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Create a new storage.
|
||||||
|
pvesm add <type> <storage> [OPTIONS]
|
||||||
|
|
||||||
|
# Allocate disk images.
|
||||||
|
pvesm alloc <storage> your-vm-id <filename> <size> [OPTIONS]
|
||||||
|
|
||||||
|
# Delete volume
|
||||||
|
pvesm free <volume> [OPTIONS]
|
||||||
|
|
||||||
|
# Delete storage configuration.
|
||||||
|
pvesm remove <storage>
|
||||||
|
|
||||||
|
# Update storage configuration.
|
||||||
|
pvesm set <storage> [OPTIONS]
|
||||||
|
|
||||||
|
# List storage content.
|
||||||
|
pvesm list <storage> [OPTIONS]
|
||||||
|
|
||||||
|
# Get the filesystem path for a specified volume.
|
||||||
|
pvesm path <volume>
|
||||||
|
|
||||||
|
# Prune backups on a storage (standard naming scheme only).
|
||||||
|
pvesm prune-backups <storage> [OPTIONS]
|
||||||
|
|
||||||
|
# Extract configuration from a vzdump backup archive.
|
||||||
|
pvesm extractconfig <volume>
|
||||||
|
|
||||||
|
# Returns the storage API version and age.
|
||||||
|
pvesm apiinfo
|
||||||
|
|
||||||
|
# An alias for pvesm scan lvm.
|
||||||
|
pvesm lvmscan
|
||||||
|
|
||||||
|
# An alias for pvesm scan lvmthin.
|
||||||
|
pvesm lvmthinscan
|
||||||
|
|
||||||
|
# List local LVM volume groups.
|
||||||
|
pvesm scan lvm
|
||||||
|
|
||||||
|
# List local LVM Thin Pools.
|
||||||
|
pvesm scan lvmthin <vg>
|
||||||
|
|
||||||
|
# Get status for all datastores.
|
||||||
|
pvesm status [OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Template Management
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# list all templates
|
||||||
|
pveam available
|
||||||
|
|
||||||
|
# list all templates
|
||||||
|
pveam list <storage>
|
||||||
|
|
||||||
|
# Download appliance templates
|
||||||
|
pveam download <storage> <template>
|
||||||
|
|
||||||
|
# Remove a template.
|
||||||
|
pveam remove <template-path>
|
||||||
|
|
||||||
|
# Update Container Template Database.
|
||||||
|
pveam update
|
||||||
|
```
|
||||||
|
|
||||||
|
## Certificate Management
|
||||||
|
|
||||||
|
See the [Proxmox Certificate Management](proxmox-certificate-management.md) cheat sheet.
|
||||||
|
|
||||||
|
## Container Management
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# List containers
|
||||||
|
pct list
|
||||||
|
|
||||||
|
# Create or restore a container.
|
||||||
|
pct create your-vm-id <ostemplate> [OPTIONS]
|
||||||
|
|
||||||
|
# Start the container.
|
||||||
|
pct start your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Create a container clone/copy
|
||||||
|
pct clone your-vm-id new-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Suspend the container. This is experimental.
|
||||||
|
pct suspend your-vm-id
|
||||||
|
|
||||||
|
# Resume the container.
|
||||||
|
pct resume your-vm-id
|
||||||
|
|
||||||
|
# Stop the container.
|
||||||
|
# This will abruptly stop all processes running in the container.
|
||||||
|
pct stop your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Shutdown the container.
|
||||||
|
# This will trigger a clean shutdown of the container, see lxc-stop(1) for details.
|
||||||
|
pct shutdown your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Destroy the container (also delete all uses files).
|
||||||
|
pct destroy your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Show CT status.
|
||||||
|
pct status your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Migrate the container to another node. Creates a new migration task.
|
||||||
|
pct migrate your-vm-id <target> [OPTIONS]
|
||||||
|
|
||||||
|
# Migrate the container to a remote cluster. Creates a new migration task. EXPERIMENTAL.
|
||||||
|
pct remote-migrate your-vm-id target-endpoint --target-bridge <string> --target-storage <string> [OPTIONS]
|
||||||
|
|
||||||
|
# Get container configuration.
|
||||||
|
pct config your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Print the list of assigned CPU sets.
|
||||||
|
pct cpusets
|
||||||
|
|
||||||
|
# Get container configuration, including pending changes.
|
||||||
|
pct pending your-vm-id
|
||||||
|
|
||||||
|
# Reboot the container by shutting it down, and starting it again. Applies pending changes.
|
||||||
|
pct reboot your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Create or restore a container.
|
||||||
|
pct restore your-vm-id <ostemplate> [OPTIONS]
|
||||||
|
|
||||||
|
# Set container options.
|
||||||
|
pct set your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Create a Template.
|
||||||
|
pct template your-vm-id
|
||||||
|
|
||||||
|
# Unlock the VM.
|
||||||
|
pct unlock your-vm-id
|
||||||
|
```
|
||||||
|
|
||||||
|
### Container Disks
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Get the container's current disk usage.
|
||||||
|
pct df your-vm-id
|
||||||
|
|
||||||
|
# Run a filesystem check (fsck) on a container volume.
|
||||||
|
pct fsck your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Run fstrim on a chosen CT and its mountpoints.
|
||||||
|
pct fstrim your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Mount the container's filesystem on the host.
|
||||||
|
# This will hold a lock on the container and is meant for emergency maintenance only
|
||||||
|
# as it will prevent further operations on the container other than start and stop.
|
||||||
|
pct mount your-vm-id
|
||||||
|
|
||||||
|
# Move a rootfs-/mp-volume to a different storage or to a different container.
|
||||||
|
pct move-volume your-vm-id <volume> [<storage>] [<target-vmid>] [<target-volume>] [OPTIONS]
|
||||||
|
|
||||||
|
# Unmount the container's filesystem.
|
||||||
|
pct unmount your-vm-id
|
||||||
|
|
||||||
|
# Resize a container mount point.
|
||||||
|
pct resize your-vm-id your-vm-disk <size> [OPTIONS]
|
||||||
|
|
||||||
|
# Rescan all storages and update disk sizes and unused disk images.
|
||||||
|
pct rescan [OPTIONS]
|
||||||
|
|
||||||
|
# Connect to container
|
||||||
|
pct enter your-vm-id
|
||||||
|
|
||||||
|
# Launch a console for the specified container.
|
||||||
|
pct console your-vm-id [OPTIONS]
|
||||||
|
|
||||||
|
# Launch a shell for the specified container.
|
||||||
|
pct enter your-vm-id
|
||||||
|
|
||||||
|
# Launch a command inside the specified container.
|
||||||
|
pct exec your-vm-id [<extra-args>]
|
||||||
|
|
||||||
|
# Copy a file from the container to the local system.
|
||||||
|
pct pull your-vm-id <path> <destination> [OPTIONS]
|
||||||
|
|
||||||
|
# Copy a local file to the container.
|
||||||
|
pct push your-vm-id <file> <destination> [OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Container Snapshot
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Snapshot a container.
|
||||||
|
pct snapshot your-vm-id <snapname> [OPTIONS]
|
||||||
|
|
||||||
|
# List all snapshots.
|
||||||
|
pct listsnapshot your-vm-id
|
||||||
|
|
||||||
|
# Rollback LXC state to specified snapshot.
|
||||||
|
pct rollback your-vm-id <snapname> [OPTIONS]
|
||||||
|
|
||||||
|
# Delete a LXC snapshot.
|
||||||
|
pct delsnapshot your-vm-id <snapname> [OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Web GUI
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Restart web GUI
|
||||||
|
service pveproxy restart
|
||||||
|
```
|
||||||
|
|
||||||
|
## Resize Disk
|
||||||
|
|
||||||
|
### Increase disk size
|
||||||
|
|
||||||
|
Increase disk size in the GUI or with the following command
|
||||||
|
|
||||||
|
```shell
|
||||||
|
qm resize 100 virtio0 +5G
|
||||||
|
```
|
||||||
|
|
||||||
|
### Decrease disk size
|
||||||
|
|
||||||
|
> Before decreasing disk sizes in Proxmox, you should take a backup!
|
||||||
|
|
||||||
|
1. Convert qcow2 to raw: `qemu-img convert vm-100.qcow2 vm-100.raw`
|
||||||
|
2. Shrink the disk `qemu-img resize -f raw vm-100.raw 10G`
|
||||||
|
3. Convert back to qcow2 `qemu-img convert -p -O qcow2 vm-100.raw vm-100.qcow2`
|
||||||
|
|
||||||
|
## Further information
|
||||||
|
|
||||||
|
More examples and tutorials regarding Proxmox can be found in the link list below:
|
||||||
|
|
||||||
|
- Ansible playbook that automates Linux VM updates running on Proxmox (including snapshots): [TheDatabaseMe - update_proxmox_vm](https://github.com/thedatabaseme/update_proxmox_vm)
|
||||||
|
- Manage Proxmox VM templates with Packer: [Use Packer to build Proxmox images](https://thedatabaseme.de/2022/10/16/what-a-golden-boy-use-packer-to-build-proxmox-images/)
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
# Zsh Cheatsheet
|
||||||
|
|
||||||
|
Reference for the new ZDOTDIR-based zsh setup (oh-my-zsh removed,
|
||||||
|
config lives in `~/.config/zsh/`).
|
||||||
|
|
||||||
|
## Aliases
|
||||||
|
|
||||||
|
### Docker Compose
|
||||||
|
| Alias | Expands to | What it does |
|
||||||
|
|---|---|---|
|
||||||
|
| `dcu` | `docker compose up -d` | Start containers in detached mode |
|
||||||
|
| `dcd` | `docker compose down` | Stop and remove containers |
|
||||||
|
| `dcr` | `docker compose restart` | Restart containers |
|
||||||
|
| `dcp` | `docker compose pull` | Pull latest images |
|
||||||
|
|
||||||
|
### Navigation
|
||||||
|
| Alias | Expands to | What it does |
|
||||||
|
|---|---|---|
|
||||||
|
| `..` | `cd ..` | Up one directory |
|
||||||
|
| `...` | `cd ../..` | Up two directories |
|
||||||
|
| `....` | `cd ../../..` | Up three directories |
|
||||||
|
|
||||||
|
### File listing
|
||||||
|
| Alias | Expands to | What it does |
|
||||||
|
|---|---|---|
|
||||||
|
| `ls` | `eza -lahF --group-directories-first --time-style="+%d/%m/%Y %H:%M" --git` (falls back to plain `ls -lahF ...` if eza isn't installed) | Long listing, all files, classify symbols (`/`, `*`, `@`), directories first, custom date format, git status column |
|
||||||
|
| `tree` | `eza --tree` (only if eza is installed) | Tree view of directory structure |
|
||||||
|
| `cat` | `bat` (only if bat is installed) | Syntax-highlighted file viewer |
|
||||||
|
|
||||||
|
### System
|
||||||
|
| Alias | Expands to | What it does |
|
||||||
|
|---|---|---|
|
||||||
|
| `df` | `df -h` | Disk usage, human-readable sizes |
|
||||||
|
| `free` | `free -h` | Memory usage, human-readable sizes |
|
||||||
|
| `c` | `clear` | Clear the terminal |
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
| Function | Usage | What it does |
|
||||||
|
|---|---|---|
|
||||||
|
| `cd` (overridden) | `cd <dir>` | Changes directory, then automatically runs `ls` (so you always see the contents of where you land). `cd` with no argument goes to `$HOME`. |
|
||||||
|
| `mkcd` | `mkcd <dir>` | Creates a directory and `cd`s into it in one step |
|
||||||
|
| `extract` | `extract <file>` | Extracts an archive based on its extension. Supports `.tar.gz`/`.tgz`, `.tar.bz2`, `.tar.xz`, `.zip`, `.gz` |
|
||||||
|
| `ports` | `ports` | Shows listening ports and the processes using them (`sudo ss -tulpen`) |
|
||||||
|
| `psg` | `psg <name>` | Searches running processes by name (case-insensitive `ps aux | grep`) |
|
||||||
|
| `killport` | `killport <port>` | Kills whatever process is listening on the given port |
|
||||||
|
| `logtail` | `logtail <file> [lines]` | Tails a log file (`-f`), default 50 lines, or specify a custom number |
|
||||||
|
| `reload` | `reload` | Reloads the zsh config (`source $ZDOTDIR/.zshrc`) without restarting the shell |
|
||||||
|
|
||||||
|
## Keybindings
|
||||||
|
|
||||||
|
| Key | Action | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| `Ctrl + →` | Move cursor forward one word | |
|
||||||
|
| `Ctrl + ←` | Move cursor backward one word | |
|
||||||
|
| `Ctrl + \` | Toggle autosuggestions on/off | Echoes "Autosuggestions: on/off" so you know the current state |
|
||||||
|
| `↑` (Up arrow) | Search history backward by prefix | Type a few characters first, then press Up to find matching previous commands |
|
||||||
|
| `↓` (Down arrow) | Search history forward by prefix | Same as above, opposite direction |
|
||||||
|
|
||||||
|
## Line editing (built-in zsh defaults)
|
||||||
|
|
||||||
|
These come from zsh's default "emacs" editing mode (the standard unless
|
||||||
|
something switches it to vi mode — this setup doesn't). Most of these
|
||||||
|
work in any emacs-style shell (bash, zsh) and are worth building into
|
||||||
|
muscle memory since they work everywhere.
|
||||||
|
|
||||||
|
### Cursor movement
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `←` / `→` | Move cursor one character left/right |
|
||||||
|
| `Ctrl + ←` / `Ctrl + →` | Move cursor one **word** left/right (custom binding in this setup) |
|
||||||
|
| `Ctrl + A` | Jump to the **start** of the line |
|
||||||
|
| `Ctrl + E` | Jump to the **end** of the line |
|
||||||
|
| `Alt + B` | Move backward one word (alternative to Ctrl+←) |
|
||||||
|
| `Alt + F` | Move forward one word (alternative to Ctrl+→) |
|
||||||
|
|
||||||
|
### Deleting / cutting text
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `Backspace` | Delete the character **before** the cursor |
|
||||||
|
| `Ctrl + D` / `Delete` | Delete the character **under/after** the cursor (Ctrl+D on an empty line exits the shell — careful) |
|
||||||
|
| `Ctrl + W` | Delete the **word before** the cursor (cuts to kill-ring) |
|
||||||
|
| `Alt + D` | Delete the **word after** the cursor (cuts to kill-ring) |
|
||||||
|
| `Alt + Backspace` | Same as Ctrl+W — delete word before cursor |
|
||||||
|
| `Ctrl + U` | Delete **everything before** the cursor (whole line back to start) |
|
||||||
|
| `Ctrl + K` | Delete **everything after** the cursor (to end of line) |
|
||||||
|
|
||||||
|
### Pasting (yanking) deleted text
|
||||||
|
|
||||||
|
zsh doesn't have "select text" like a GUI — instead, anything you cut
|
||||||
|
with `Ctrl+W`, `Alt+D`, `Ctrl+U`, or `Ctrl+K` goes into a clipboard-like
|
||||||
|
buffer (the "kill ring"), which you can paste back with:
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `Ctrl + Y` | Paste ("yank") the last cut text at the cursor |
|
||||||
|
|
||||||
|
**Practical example:** to move a word from the end of a command to the
|
||||||
|
start — put cursor at end of word, `Alt + Backspace` to cut it, `Ctrl + A`
|
||||||
|
to jump to the start of the line, `Ctrl + Y` to paste it there.
|
||||||
|
|
||||||
|
### Undo / retype
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `Ctrl + _` (Ctrl + Shift + -) | Undo the last edit |
|
||||||
|
| `Ctrl + L` | Clear the screen (same as the `c` alias, but doesn't lose scrollback the same way) |
|
||||||
|
|
||||||
|
### Transposing / fixing typos
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `Ctrl + T` | Swap the two characters around the cursor (fixes a typo like `hte` → `the`) — **note:** this is overridden by fzf's Ctrl+T in this setup if fzf is installed |
|
||||||
|
| `Alt + T` | Swap the two **words** around the cursor |
|
||||||
|
|
||||||
|
### Case changes
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `Alt + U` | Uppercase the word from the cursor onward |
|
||||||
|
| `Alt + L` | Lowercase the word from the cursor onward |
|
||||||
|
| `Alt + C` | Capitalize the word from the cursor onward |
|
||||||
|
|
||||||
|
### Re-running / editing previous commands
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `!!` | Re-run the last command (e.g. `sudo !!` re-runs the last command with sudo) |
|
||||||
|
| `!$` | The last **argument** of the previous command (e.g. `cat !$` opens whatever file you last referenced) |
|
||||||
|
| `Ctrl + R` (no fzf) | Reverse incremental search through history (built-in, before fzf takes over — see fzf section below for the upgraded version) |
|
||||||
|
| `fc` | Opens the last command in `$EDITOR` (nano) for editing, then runs it |
|
||||||
|
|
||||||
|
## Fuzzy search (fzf)
|
||||||
|
|
||||||
|
Only active if `fzf` is installed.
|
||||||
|
|
||||||
|
| Key | Action | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| `Ctrl + R` | Fuzzy search command history | Type to filter, select a command, it's inserted at the cursor. This overrides the built-in reverse search mentioned above |
|
||||||
|
| `Ctrl + F` | Fuzzy file search (includes hidden files, excludes `.git`) | Selected file path is inserted at the cursor. Uses `fd` if installed, otherwise falls back to `find` |
|
||||||
|
| `Ctrl + T` | Fuzzy file search (fzf's built-in, non-hidden files) | Only active if fzf's own shell integration is found on the system; uses `fd` for speed if installed. This overrides the built-in character-transpose shortcut mentioned above |
|
||||||
|
|
||||||
|
## Plugins (auto-loaded on shell startup)
|
||||||
|
|
||||||
|
These are cloned automatically into `$ZDOTDIR/plugins/` the first time
|
||||||
|
you start a shell after the role runs — no manual setup needed.
|
||||||
|
|
||||||
|
| Plugin | What it does |
|
||||||
|
|---|---|
|
||||||
|
| `zsh-autosuggestions` | Shows a greyed-out suggestion as you type, based on history. Press `→` (right arrow) or `End` to accept it |
|
||||||
|
| `fast-syntax-highlighting` | Colors commands as you type — valid commands, paths, strings, etc. get different colors so you can spot typos before pressing Enter |
|
||||||
|
|
||||||
|
## Environment / history
|
||||||
|
|
||||||
|
- History file: `~/.local/state/zsh/history`
|
||||||
|
- History size: 10,000 commands
|
||||||
|
- History behavior: shared across sessions, duplicates ignored, commands
|
||||||
|
starting with a space aren't recorded (`HIST_IGNORE_SPACE`)
|
||||||
|
- Default editor: `nano` (`$EDITOR` / `$VISUAL`)
|
||||||
|
- Config location: `$ZDOTDIR` = `~/.config/zsh/`
|
||||||
|
- Per-host extra env vars (e.g. `VAULT_ADDR`) are set via `zsh_extra_env`
|
||||||
|
in Ansible host_vars, appended to `env.zsh`
|
||||||
|
|
||||||
|
## Startup
|
||||||
|
|
||||||
|
`fastfetch` runs automatically every time a new shell opens, showing
|
||||||
|
system info (OS, kernel, uptime, packages, etc.) above the prompt.
|
||||||
Reference in new issue
Block a user