Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9cbfb0f25f | |||
| db3ed868e6 | |||
| 489ecbdeef |
12
README.md
12
README.md
@ -1,11 +1,12 @@
|
|||||||
# autopve
|
# autopve
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
[autopve_demo.webm](https://github.com/natankeddem/autopve/assets/44515217/1133abe2-97b4-421d-b33f-a833f8b6c904)
|
|
||||||
|
[autopve_demo.webm](https://github.com/natankeddem/autopve/assets/44515217/827bdd22-5311-43c1-9452-a56fa11998aa)
|
||||||
|
|
||||||
## Information
|
## Information
|
||||||
|
|
||||||
GUI configurable web server for Proxmox automated installation.
|
GUI configurable web server for Proxmox automated installation. More information about the automated installation feature built into the Proxmox installation media can be found [here](https://pve.proxmox.com/wiki/Automated_Installation).
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@ -44,3 +45,10 @@ GUI configurable web server for Proxmox automated installation.
|
|||||||
|
|
||||||
The configuration GUI can be accessed at `http://host:8080`. Answers are hosted at `http://host:8080/answer`.
|
The configuration GUI can be accessed at `http://host:8080`. Answers are hosted at `http://host:8080/answer`.
|
||||||
|
|
||||||
|
### OPNsense Setup
|
||||||
|
|
||||||
|
For Unbound you will need to enable TXT records and make an appropriate host override entry.
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -20,13 +20,13 @@ def build():
|
|||||||
@app.post("/answer")
|
@app.post("/answer")
|
||||||
async def post_answer(request: Request) -> PlainTextResponse:
|
async def post_answer(request: Request) -> PlainTextResponse:
|
||||||
def response(answer: str, system_info: Dict[str, Any], data: Dict[str, Any]):
|
def response(answer: str, system_info: Dict[str, Any], data: Dict[str, Any]):
|
||||||
toml = tomlkit.dumps(default_data)
|
toml = tomlkit.dumps(data)
|
||||||
toml_fixed = ""
|
toml_fixed = ""
|
||||||
for line in toml.splitlines():
|
for line in toml.splitlines():
|
||||||
if len(line) > 0 and line[0] == '"':
|
if len(line) > 0 and line[0] == '"':
|
||||||
line = line.replace('"', "", 2)
|
line = line.replace('"', "", 2)
|
||||||
toml_fixed = toml_fixed + line + "\n"
|
toml_fixed = toml_fixed + line + "\n"
|
||||||
r = history.Request(answer=answer, response=toml_fixed, system_info=dict(system_info))
|
r = history.Request(answer=answer, response=toml_fixed, system_info=copy.deepcopy(system_info))
|
||||||
history.History.add_history(r)
|
history.History.add_history(r)
|
||||||
for client in Client.instances.values():
|
for client in Client.instances.values():
|
||||||
if not client.has_socket_connection:
|
if not client.has_socket_connection:
|
||||||
@ -37,12 +37,12 @@ def build():
|
|||||||
|
|
||||||
system_info = await request.json()
|
system_info = await request.json()
|
||||||
system_info_raw = json.dumps(system_info)
|
system_info_raw = json.dumps(system_info)
|
||||||
default_data = dict(storage.answer("Default"))
|
default_data = copy.deepcopy(storage.answer("Default"))
|
||||||
answers = list(storage.answers.keys())
|
answers = list(storage.answers.keys())
|
||||||
if "Default" in answers:
|
if "Default" in answers:
|
||||||
answers.remove("Default")
|
answers.remove("Default")
|
||||||
for answer in answers:
|
for answer in answers:
|
||||||
answer_data = dict(storage.answer(answer))
|
answer_data = copy.deepcopy(storage.answer(answer))
|
||||||
if "match" in answer_data:
|
if "match" in answer_data:
|
||||||
if len(answer_data["match"]) > 0 and answer_data["match"] in system_info_raw:
|
if len(answer_data["match"]) > 0 and answer_data["match"] in system_info_raw:
|
||||||
if "global" in default_data and "global" in answer_data:
|
if "global" in default_data and "global" in answer_data:
|
||||||
|
|||||||
@ -60,7 +60,7 @@ class Tab:
|
|||||||
"control": el.FInput(
|
"control": el.FInput(
|
||||||
key,
|
key,
|
||||||
password=True if key == "root_password" else False,
|
password=True if key == "root_password" else False,
|
||||||
autocomplete=keys[key]["options"] if "options" in keys[key] else None,
|
autocomplete=keys[key]["options"] if key in keys and "options" in keys[key] else None,
|
||||||
on_change=lambda e, key=key: set_key(key, e.value),
|
on_change=lambda e, key=key: set_key(key, e.value),
|
||||||
),
|
),
|
||||||
"row": key_row,
|
"row": key_row,
|
||||||
@ -78,7 +78,7 @@ class Tab:
|
|||||||
|
|
||||||
def set_key(key, value: str):
|
def set_key(key, value: str):
|
||||||
if len(value) > 0:
|
if len(value) > 0:
|
||||||
if "type" in keys[key]:
|
if key in keys and "type" in keys[key]:
|
||||||
if keys[key]["type"] == "list":
|
if keys[key]["type"] == "list":
|
||||||
self.picked_keys[key] = value[1:-1].split(",")
|
self.picked_keys[key] = value[1:-1].split(",")
|
||||||
elif keys[key]["type"] == "int":
|
elif keys[key]["type"] == "int":
|
||||||
|
|||||||
Reference in New Issue
Block a user