1 Commits

Author SHA1 Message Date
3wc
3cf501a393 Disco updates for YOLOCOLO site 2021-07-21 01:13:52 +02:00
11 changed files with 68 additions and 156 deletions

View File

@ -31,6 +31,7 @@ load_dotenv(find_dotenv())
app = Flask(__name__) app = Flask(__name__)
app.config.from_mapping( app.config.from_mapping(
BASE_URL=os.environ.get("BASE_URL", default="http://localhost:5000"), BASE_URL=os.environ.get("BASE_URL", default="http://localhost:5000"),
SECRET_KEY=os.environ.get("SECRET_KEY", default="dev"), SECRET_KEY=os.environ.get("SECRET_KEY", default="dev"),
HUB_MODE_ENABLED=os.environ.get("HUB_MODE_ENABLED", default="True").lower() in ['true', '1', 't', 'y', 'yes'], HUB_MODE_ENABLED=os.environ.get("HUB_MODE_ENABLED", default="True").lower() in ['true', '1', 't', 'y', 'yes'],
@ -71,7 +72,7 @@ app.config.from_mapping(
#STRIPE_WEBHOOK_SECRET=os.environ.get("STRIPE_WEBHOOK_SECRET", default="") #STRIPE_WEBHOOK_SECRET=os.environ.get("STRIPE_WEBHOOK_SECRET", default="")
BTCPAY_PRIVATE_KEY=os.environ.get("BTCPAY_PRIVATE_KEY", default="").replace("\\n", "\n"), BTCPAY_PRIVATE_KEY=os.environ.get("BTCPAY_PRIVATE_KEY", default="").replace("\\n", "\n"),
BTCPAY_URL=os.environ.get("BTCPAY_URL", default="") BTCPAY_URL=os.environ.get("BTCPAY_URL", default="https://btcpay.cyberia.club")
) )
app.config['HUB_URL'] = os.environ.get("HUB_URL", default=app.config['BASE_URL']) app.config['HUB_URL'] = os.environ.get("HUB_URL", default=app.config['BASE_URL'])
@ -139,11 +140,8 @@ else:
app.config['HTTP_CLIENT'] = MyHTTPClient(timeout_seconds=int(app.config['INTERNAL_HTTP_TIMEOUT_SECONDS'])) app.config['HTTP_CLIENT'] = MyHTTPClient(timeout_seconds=int(app.config['INTERNAL_HTTP_TIMEOUT_SECONDS']))
app.config['BTCPAY_ENABLED'] = False
if app.config['BTCPAY_URL'] != "":
try: try:
app.config['BTCPAY_CLIENT'] = btcpay.Client(api_uri=app.config['BTCPAY_URL'], pem=app.config['BTCPAY_PRIVATE_KEY']) app.config['BTCPAY_CLIENT'] = btcpay.Client(api_uri=app.config['BTCPAY_URL'], pem=app.config['BTCPAY_PRIVATE_KEY'])
app.config['BTCPAY_ENABLED'] = True
except: except:
app.logger.warning("unable to create btcpay client. Capsul will work fine except cryptocurrency payments will not work. The error was: " + my_exec_info_message(sys.exc_info())) app.logger.warning("unable to create btcpay client. Capsul will work fine except cryptocurrency payments will not work. The error was: " + my_exec_info_message(sys.exc_info()))
@ -221,6 +219,7 @@ def override_url_for():
return dict(url_for=url_for_with_cache_bust) return dict(url_for=url_for_with_cache_bust)
def url_for_with_cache_bust(endpoint, **values): def url_for_with_cache_bust(endpoint, **values):
""" """
Add a query parameter based on the hash of the file, this acts as a cache bust Add a query parameter based on the hash of the file, this acts as a cache bust
@ -245,3 +244,7 @@ def url_for_with_cache_bust(endpoint, **values):
values['q'] = current_app.config['STATIC_FILE_HASH_CACHE'][filename] values['q'] = current_app.config['STATIC_FILE_HASH_CACHE'][filename]
return url_for(endpoint, **values) return url_for(endpoint, **values)

View File

@ -423,7 +423,6 @@ def account_balance():
has_vms=len(vms_billed)>0, has_vms=len(vms_billed)>0,
vms_billed=vms_billed, vms_billed=vms_billed,
warning_text=warning_text, warning_text=warning_text,
btcpay_enabled=current_app.config["BTCPAY_ENABLED"],
payments=list(map( payments=list(map(
lambda x: dict( lambda x: dict(
dollars=x["dollars"], dollars=x["dollars"],

View File

@ -17,10 +17,6 @@ from capsulflask.http_client import HTTPResult
from capsulflask.shared import VirtualizationInterface, VirtualMachine, OnlineHost, validate_capsul_id, my_exec_info_message from capsulflask.shared import VirtualizationInterface, VirtualMachine, OnlineHost, validate_capsul_id, my_exec_info_message
class MockHub(VirtualizationInterface): class MockHub(VirtualizationInterface):
def __init__(self):
self.default_network = "public1"
self.default_ipv4 = "1.1.1.1"
def capacity_avaliable(self, additional_ram_bytes): def capacity_avaliable(self, additional_ram_bytes):
return True return True
@ -33,9 +29,9 @@ class MockHub(VirtualizationInterface):
{"key_type":"RSA", "content":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvotgzgEP65JUQ8S8OoNKy1uEEPEAcFetSp7QpONe6hj4wPgyFNgVtdoWdNcU19dX3hpdse0G8OlaMUTnNVuRlbIZXuifXQ2jTtCFUA2mmJ5bF+XjGm3TXKMNGh9PN+wEPUeWd14vZL+QPUMev5LmA8cawPiU5+vVMLid93HRBj118aCJFQxLgrdP48VPfKHFRfCR6TIjg1ii3dH4acdJAvlmJ3GFB6ICT42EmBqskz2MPe0rIFxH8YohCBbAbrbWYcptHt4e48h4UdpZdYOhEdv89GrT8BF2C5cbQ5i9qVpI57bXKrj8hPZU5of48UHLSpXG8mbH0YDiOQOfKX/Mt", "sha256":"ghee6KzRnBJhND2kEUZSaouk7CD6o6z2aAc8GPkV+GQ"}, {"key_type":"RSA", "content":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvotgzgEP65JUQ8S8OoNKy1uEEPEAcFetSp7QpONe6hj4wPgyFNgVtdoWdNcU19dX3hpdse0G8OlaMUTnNVuRlbIZXuifXQ2jTtCFUA2mmJ5bF+XjGm3TXKMNGh9PN+wEPUeWd14vZL+QPUMev5LmA8cawPiU5+vVMLid93HRBj118aCJFQxLgrdP48VPfKHFRfCR6TIjg1ii3dH4acdJAvlmJ3GFB6ICT42EmBqskz2MPe0rIFxH8YohCBbAbrbWYcptHt4e48h4UdpZdYOhEdv89GrT8BF2C5cbQ5i9qVpI57bXKrj8hPZU5of48UHLSpXG8mbH0YDiOQOfKX/Mt", "sha256":"ghee6KzRnBJhND2kEUZSaouk7CD6o6z2aAc8GPkV+GQ"},
{"key_type":"ECDSA", "content":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLLgOoATz9R4aS2kk7vWoxX+lshK63t9+5BIHdzZeFE1o+shlcf0Wji8cN/L1+m3bi0uSETZDOAWMP3rHLJj9Hk=", "sha256":"aCYG1aD8cv/TjzJL0bi9jdabMGksdkfa7R8dCGm1yYs"} {"key_type":"ECDSA", "content":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLLgOoATz9R4aS2kk7vWoxX+lshK63t9+5BIHdzZeFE1o+shlcf0Wji8cN/L1+m3bi0uSETZDOAWMP3rHLJj9Hk=", "sha256":"aCYG1aD8cv/TjzJL0bi9jdabMGksdkfa7R8dCGm1yYs"}
]""") ]""")
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], ipv4=self.default_ipv4, ssh_host_keys=ssh_host_keys) return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], ipv4="1.1.1.1", ssh_host_keys=ssh_host_keys)
return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], ipv4=self.default_ipv4) return VirtualMachine(id, current_app.config["SPOKE_HOST_ID"], ipv4="1.1.1.1")
def list_ids(self) -> list: def list_ids(self) -> list:
return get_model().all_non_deleted_vm_ids() return get_model().all_non_deleted_vm_ids()
@ -44,16 +40,6 @@ class MockHub(VirtualizationInterface):
validate_capsul_id(id) validate_capsul_id(id)
current_app.logger.info(f"mock create: {id} for {email}") current_app.logger.info(f"mock create: {id} for {email}")
sleep(1) sleep(1)
get_model().create_vm(
email=email,
id=id,
size=size,
os=os,
host=current_app.config["SPOKE_HOST_ID"],
network_name=self.default_network,
public_ipv4=self.default_ipv4,
ssh_authorized_keys=list(map(lambda x: x["name"], ssh_authorized_keys)),
)
def destroy(self, email: str, id: str): def destroy(self, email: str, id: str):
current_app.logger.info(f"mock destroy: {id} for {email}") current_app.logger.info(f"mock destroy: {id} for {email}")
@ -63,6 +49,7 @@ class MockHub(VirtualizationInterface):
class CapsulFlaskHub(VirtualizationInterface): class CapsulFlaskHub(VirtualizationInterface):
def synchronous_operation(self, hosts: List[OnlineHost], email: str, payload: str) -> List[HTTPResult]: def synchronous_operation(self, hosts: List[OnlineHost], email: str, payload: str) -> List[HTTPResult]:
return self.generic_operation(hosts, email, payload, True)[1] return self.generic_operation(hosts, email, payload, True)[1]
@ -275,3 +262,4 @@ class CapsulFlaskHub(VirtualizationInterface):
if not result_status == "success": if not result_status == "success":
raise ValueError(f"""failed to {command} vm "{id}" on host "{host.id}" for {email}: {result_json_string}""") raise ValueError(f"""failed to {command} vm "{id}" on host "{host.id}" for {email}: {result_json_string}""")

View File

@ -12,11 +12,9 @@ def index():
@bp.route("/pricing") @bp.route("/pricing")
def pricing(): def pricing():
vm_sizes = get_model().vm_sizes_dict()
operating_systems = get_model().operating_systems_dict() operating_systems = get_model().operating_systems_dict()
return render_template( return render_template(
"pricing.html", "pricing.html",
vm_sizes=vm_sizes,
operating_systems=operating_systems operating_systems=operating_systems
) )

View File

@ -48,10 +48,6 @@ def validate_dollars():
def btcpay_payment(): def btcpay_payment():
errors = list() errors = list()
if not current_app.config['BTCPAY_ENABLED']:
flash("BTCPay is not enabled on this server")
return redirect(url_for("console.account_balance"))
if request.method == "POST": if request.method == "POST":
result = validate_dollars() result = validate_dollars()
errors = result[0] errors = result[0]

View File

@ -241,6 +241,7 @@ thead {
background: #bdc7b812; background: #bdc7b812;
} }
td, th { td, th {
padding: 0.1em 1em; padding: 0.1em 1em;
} }
table.small td, table.small th { table.small td, table.small th {

View File

@ -46,9 +46,7 @@
<a href="/payment/stripe">Add funds with Credit/Debit (stripe)</a> <a href="/payment/stripe">Add funds with Credit/Debit (stripe)</a>
<ul><li>notice: stripe will load nonfree javascript </li></ul> <ul><li>notice: stripe will load nonfree javascript </li></ul>
</li> </li>
{% if btcpay_enabled %}
<li><a href="/payment/btcpay">Add funds with Bitcoin/Litecoin/Monero (btcpay)</a></li> <li><a href="/payment/btcpay">Add funds with Bitcoin/Litecoin/Monero (btcpay)</a></li>
{% endif %}
<li>Cash: email <a href="mailto:treasurer@cyberia.club">treasurer@cyberia.club</a></li> <li>Cash: email <a href="mailto:treasurer@cyberia.club">treasurer@cyberia.club</a></li>
</ul> </ul>

View File

@ -13,7 +13,7 @@
<nav> <nav>
<div class="row justify-space-between half-margin"> <div class="row justify-space-between half-margin">
<div> <div>
<a href="/"><b>Capsul</b></a>💊 <a href="/"><b>YOLOCOLO</b></a>💊
</div> </div>
<div> <div>
&nbsp; &nbsp;
@ -27,7 +27,6 @@
<div class="row justify-center half-margin wrap nav-links"> <div class="row justify-center half-margin wrap nav-links">
<a href="/pricing">Pricing</a> <a href="/pricing">Pricing</a>
<a href="/faq">FAQ</a> <a href="/faq">FAQ</a>
<a href="/changelog">Changelog</a>
{% if session["account"] %} {% if session["account"] %}
<a href="/console">Capsuls</a> <a href="/console">Capsuls</a>
@ -47,11 +46,12 @@
</main> </main>
{% block subcontent %}{% endblock %} {% block subcontent %}{% endblock %}
<footer> <footer>
(c) Attribution-ShareAlike 4.0 International <br/> This server runs <a
&nbsp;&nbsp;&nbsp;&nbsp;A service by Cyberia Computer Club 2020-<span class="bigtext"></span> <br/> href="https://giit.cyberia.club/~forest/capsul-flask">capsul-flask</a> by
<br/> Cyberia Computer Club, available under the <a
<br/> href="https://creativecommons.org/licenses/by-sa/4.0/">Attribution-ShareAlike
<a href="https://giit.cyberia.club/~forest/capsul-flask/tree/master/capsulflask{% block pagesource %}{% endblock %}">View page source</a> 4.0 International</a> licence.<br/><br/>
<a href="https://git.autonomic.zone/3wordchant/capsul-flask/src/branch/yolocolo/capsulflask{% block pagesource %}{% endblock %}">View page source</a>
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -10,82 +10,32 @@
<p> <p>
<ul> <ul>
<li> <li>
Which instance type should I buy? What is this?
<p>There are no hard rules for this sort of thing, but here are some guidelines:</p> <p>
<p>f1-xs: blog, vpn, bot, cgit</p> This is a <strong>technical demo</strong> of <a
<p>f1-s: a bot, owncloud, gitea, popular blog</p> href="https://giit.cyberia.club/~forest/capsul-flask">Capsul</a>, for the
<p>f1-m: docker host, build system</p> as-yet-untitled <a href="https://coops.tech">Cotech</a> server hosting
<p>f1-l: large webservice, rotund java app</p> initiative, which you can <a
<p>f1-x: gitlab (wow such memory very devops</p> href="https://community.coops.tech/t/call-for-input-v2-co-op-vps-survey/2802/9">read
<p>f1-xx: something gargantuan</p> about on the Cotech forum</a>.
</li>
<li>
How do I log in?
<p>ssh to the ip provided to you using the cyberian user.</p>
<pre class='code'>$ ssh cyberian@1.2.3.4</pre>
<p>For more information, see <a href="/about-ssh">Understanding the Secure Shell Protocol (SSH)</a>.</p>
</li>
<li>
How do I change to the root user?
<p>The cyberian user has passwordless sudo access by default. This should work:</p>
<pre class='code'>
# Linux
$ sudo su -
# OpenBSD
$ doas su -</pre>
</li>
<li>
Do you offer reverse DNS?
<p>We do, but right now it's a manual process. Shoot us an email and we'll get it done.</p>
</li>
<li>
What if I don't pay / don't maintain my payments?
<p>Your VM will eventually be deleted.
Capsul will send you a few inoffensive reminders as that termination date approaches.
</p> </p>
</li> </li>
<li> <li>
Besides my virtual machines and payments, what information do you keep about me? What do you mean, "technical demo"?
<p>We associate an email address with every VM so that we can track payment and respond to support requests.</p> <p>No backups</p>
<p>If you pay with a credit card, Stripe stores some additional details about you that we literally cannot delete.</p> <p>No service level agreement</p>
<p>"Best effort" support</p>
</li> </li>
<li> <li>
What can I do with my VM? Where can I get this, but, more reliable?
<p>Make it into a mailserver, a tor relay, a VPN host, whatever you'd like - we do have one small request, though.</p> <p>Cyberia, the authors of this platform, run the canonical instance, <a
<p>Crypto mining on capsul is currently considered obnoxious behavior, because the hashrates on our CPUs is so low and because mining crypto consumes entire processor cores that could have otherwise been shared between many dozens of other users.</p> href="https://capsul.org">Capsul.org</a>, on hardware they own. Please
<p>In the future, if we have plentiful CPU resources, we may come out with a tier more suitable for mining - maybe a high cpu tier or similar, where each VM gets a full dedicated core and sharing them is not anticipated.</p> send them your money! (cash, crypto, or card accepted).</p>
<p>We will never snoop on your traffic or inspect what's going on inside of our customer virtual machines - we don't want to. We hope that you'll extend us a similar courtesy and try not to use too much of our shared CPU resources. Capsul is currently a shared (resource-wise) world, and we all must live in it together!</p>
<p>Also, mandatory: our systems exist within the USA, and as such those systems are bound by US law.</p>
</li> </li>
<li> <li>
Can you recover my passwords/insert new keys? How do I use this system?
<p>Can we? Technically yes. Will we? No, never. It would violate the trust that our users have in us. <p>Please see <a href="https://capsul.org/faq">the official Capsul FAQ
We have no interest in touching client VMs after they're running. page</a>.</p>
We promise to keep your machines running smoothly.
If you lose access to your VM, that's on you.</p>
</li>
<li>
Do you offer refunds?
<p>Not now, but email us and we can probably figure something out.</p>
</li>
<li>
Where do the VMs run? Is it on a machine that you guys own/control?
<p>Capsul runs on a server named Baikal which Cyberia built from scratch & mailed to a datacenter
in Georgia called CyberWurx. CyberWurx staff installed it for us in a rack space that
Cyberia pays for. </p>
</li>
<li>
Do you offer support?
<p>Yep, see <a href="/support">our support page</a>.</p>
</li>
<li>
Do you have an SLA?
<p>No, but we normally respond pretty quickly.</p>
</li>
<li>
Will you implement feature X?
<p>Maybe! Email <a href="mailto:ops@cyberia.club">ops@cyberia.club</a> and ask us about it.</p>
</li> </li>
</ul> </ul>
</p> </p>

View File

@ -1,31 +1,26 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block content %} {% block content %}
<h1>CAPSUL</h1> <h1>
<pre> <pre>
.-. _ _
/:::\ _ _ ___ | | ___ ___ ___ | | ___
/::::/ | | | |/ _ \| |/ _ \ / __/ _ \| |/ _ \
/ `-:/ | |_| | (_) | | (_) | (_| (_) | | (_) |
/ / \__, |\___/|_|\___/ \___\___/|_|\___/
\ / |___/
`"`
</pre> </pre>
<span>Simple, fast, private compute by <a href="https://cyberia.club">cyberia.club</a></span> <span>Co-operative hosting using <a href="https://cyberia.club">Cyberia</a>'s Capsul</span>
{% endblock %} {% endblock %}
{% block subcontent %} {% block subcontent %}
<p> <p>
<ul> <ul>
<li>Low friction: simply log in with your email address and fund your account with Credit/Debit or Cryptocurrency</li> <li>Sign up for an account!</li>
<li>All root disks are backed up at no charge</li> <li>Add some funds!</li>
<li>All storage is fast, local, and solid-state</li> <li>Create a VPS!</li>
<li>All network connections are low latency</li> <li>Give your feedback!</li>
<li>Supported by amazing volunteers from Cyberia</li>
<li>Upfront prices, no confusing billing</li>
<li>Operated by a Minnesota non-profit organization that will never exploit you</li>
<li>We donate a portion of our proceeds to likeminded hacker groups around the globe</li>
</ul> </ul>
</p> </p>
{% endblock %} {% endblock %}

View File

@ -6,38 +6,22 @@
<div class="row third-margin"> <div class="row third-margin">
<h1>CAPSUL TYPES & PRICING</h1> <h1>CAPSUL TYPES & PRICING</h1>
</div> </div>
<div class="row half-margin">
<table>
<thead>
<tr>
<th>type</th>
<th>monthly*</th>
<th>cpus</th>
<th>mem</th>
<th>ssd</th>
<th>net</th>
</tr>
</thead>
<tbody>
{% for vm_size_key, vm_size in vm_sizes.items() %}
<tr>
<td>{{ vm_size_key }}</td>
<td>${{ vm_size['dollars_per_month'] }}</td>
<td>{{ vm_size['vcpus'] }}</td>
<td>{{ vm_size['memory_mb'] }}</td>
<td>25G</td>
<td>{{ vm_size['bandwidth_gb_per_month'] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="row half-margin"> <div class="row half-margin">
<pre> <pre>
type monthly* cpus mem ssd net*
----- ------- ---- --- --- ---
f1-xs $5.00 1 512M 25G .5TB
f1-s $7.50 1 1024M 25G 1TB
f1-m $12.50 1 2048M 25G 2TB
f1-l $20.00 2 3072M 25G 3TB
f1-x $27.50 3 4096M 25G 4TB
f1-xx $50.00 4 8192M 25G 5TB
* net is calculated as a per-month average * net is calculated as a per-month average
* vms are billed for a minimum of 24 hours upon creation * vms are billed for a minimum of 24 hours upon creation
* all VMs come standard with one public IPv4 address * all VMs come standard with one public IPv4 address
SUPPORTED OPERATING SYSTEMS: SUPPORTED OPERATING SYSTEMS: