Skip to content

Commit

Permalink
Try using easier to type machine names. Fixes: #78
Browse files Browse the repository at this point in the history
  • Loading branch information
spanezz committed Nov 13, 2022
1 parent a3e133f commit 2e08e3e
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 2 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
instead of manually invoking the package manager in the maintscript
* Propagate options to subcommands, so they can be used anywhere in the command
line
* Try out easier to type machine names (#78)

# Version 0.7

Expand Down
21 changes: 19 additions & 2 deletions moncic/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
import subprocess
import tempfile
import time
import uuid
from collections import Counter
from typing import (TYPE_CHECKING, Any, Callable, ContextManager, Dict, Iterator, List,
NoReturn, Optional, Protocol, Tuple)

from .nspawn import escape_bind_ro
from .runner import RunConfig, SetnsCallableRunner, UserConfig
from .deb import apt_get_cmd
from . import libbanana

if TYPE_CHECKING:
from .system import System
Expand All @@ -28,6 +29,16 @@

re_split_bind = re.compile(r"(?<!\\):")

# Per-pid sequence numbers used for machine names
machine_name_sequences: Dict[int, int] = Counter()

# Convert PIDs to machine names
machine_name_generator = libbanana.Codec(
alphabets=(
"bcdfgjklmnprstvwxz",
"aeiouy",
)).encode


@dataclasses.dataclass
class BindConfig:
Expand Down Expand Up @@ -381,7 +392,12 @@ def __init__(self, system: System, config: ContainerConfig, instance_name: Optio
self.system = system

if instance_name is None:
self.instance_name = str(uuid.uuid4())
current_pid = os.getpid()
seq = machine_name_sequences[current_pid]
machine_name_sequences[current_pid] += 1
self.instance_name = "mc" + machine_name_generator(current_pid)
if seq > 0:
self.instance_name += str(seq)
else:
self.instance_name = instance_name

Expand Down Expand Up @@ -513,6 +529,7 @@ def get_start_command(self):
cmd.append("--ephemeral")
if self.system.images.session.moncic.systemd_version >= 250:
cmd.append("--suppress-sync=yes")
cmd.append(f"systemd.hostname={self.instance_name}")
return cmd

def forward_user(self, user: UserConfig, allow_maint=False):
Expand Down
115 changes: 115 additions & 0 deletions moncic/libbanana.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Convert numbers to/from base banana. See https://basebanana.org/
#
# Code from https://git.lattuga.net/itec/banana
#
# MIT License
#
# Copyright (c) 2020, itec
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""Main module."""
import logging
import random

log = logging.getLogger("libbanana")


class Codec:
def __init__(self, shiftalpha=0, alphaend=0, minlength=0, alphabets=None):
self.shiftalpha = shiftalpha
self.alphaend = alphaend
if alphabets is None:
self.alphabets = [list("bcdfglmnprstvz"), list("aeiou")]
else:
self.alphabets = alphabets

def encode(self, num, minlength=1):
alphabets = self.alphabets
numalpha = len(alphabets)
v = num
st = ""
length = 0

idx = (numalpha - 1 + self.shiftalpha + self.alphaend) % numalpha
while not (
v == 0
and idx == (numalpha - 1 + self.shiftalpha) % numalpha
and length >= minlength
):
r = v % len(alphabets[idx])
v = int(v / len(alphabets[idx]))
st = alphabets[idx][r] + st
idx = (idx + numalpha - 1) % numalpha
length += 1

return st

def decode(self, word):
alphabets = self.alphabets

numalpha = len(alphabets)
if (len(word) - self.alphaend) % numalpha != 0:
raise ValueError("Invalid banana")
v = 0
for i in range(len(word)):
r = (numalpha + i + self.shiftalpha) % numalpha
try:
v = v * len(alphabets[r]) + alphabets[r].index(word[i])
except (ValueError, KeyError):
raise ValueError("Invalid character in position %d" % i + 1)

return v

def is_valid(self, word):
alphabets = self.alphabets

numalpha = len(alphabets)
if (len(word) - self.alphaend) % numalpha != 0:
return False
for i in range(len(word)):
r = (numalpha + i + self.shiftalpha) % numalpha
if word[i] not in alphabets[r]:
return False

return True

def random(self, minlength=6, prng=random.Random()):
numalpha = len(self.alphabets)
word = ""

if minlength < 1:
return ""

curr_alpha = (numalpha - 1 + self.shiftalpha + self.alphaend) % numalpha
final_alpha = (numalpha - 1 + self.shiftalpha) % numalpha
while curr_alpha != final_alpha or len(word) < minlength:
word = prng.choice(self.alphabets[curr_alpha]) + word
curr_alpha = (curr_alpha - 1) % numalpha

return word


class BananaCodec(Codec):
def __init__(self):
super().__init__()


if __name__ == "__main__":
print("Hi I'm the basebanana library")

0 comments on commit 2e08e3e

Please sign in to comment.