User-facing desktop application for server.garden
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

737 lines
40 KiB

// for browser
// let language;
// if (window.navigator.languages) {
// language = window.navigator.languages[0];
// } else {
// language = window.navigator.userLanguage || window.navigator.language;
// }
// language = language.split('-')[0];
const code = (x) => `<span class="code">${x}</span>`;
const boldRedUnderlined = (x) => `<span class="red-bold-underline">${x}</span>`;
const bold = (x) => `<span class="bold">${x}</span>`;
const makeLink = (url, text) => `<a rel="noopener noreferrer nofollow" target="_blank" href="${url}" >${text}</a>`
const url_bugReport = 'https://git.sequentialread.com/forest/seedpacket/issues'
const url_greenhouse = 'https://greenhouse.server.garden/'
const url_backblaze = 'https://www.backblaze.com/'
const url_digitalocean = 'https://www.digitalocean.com/'
const url_gandi = 'https://www.gandi.net/'
const url_recommendedPeripherals = "https://server.garden/recommended-peripherals";
const url_howServerGardenWorksOnAnyNetwork = "https://server.garden/how-server-garden-works-on-any-network";
const macros = {
"en-US" : {
"pleaseIssueABugReport": `
<p>If you believe that you have recieved this message in error, please issue a
${makeLink(url_bugReport, "bug report")}.</p>`
}
}
const translations = {
"en-US": {
"button_NewFile": "Create New Seed File",
"button_OpenFile": "Open an Existing Seed File",
"title_OpenASeedFile": "Open a server.garden seed (.sgseed) File",
"description_FileTypeSGSeed": "server.garden seed file (*.sgseed)",
"description_FileTypeAllFiles": "All Files (*)",
"title_WhereToSaveYourFile": "Where to Save Your File?",
"defaultFileName": "MyDatacenter.sgseed",
"errorMessage_BlockDeviceScanner": "unable to list block devices",
"errorMessage_UnsupportedRequestFilepathMode": (mode) => `
unsupported request filepath mode "${mode}", expected "new" or "open"
`,
"errorMessage_UnhandledError": "Unhandled Error",
"errorMessage_XReturnedY": (x, y) => `${x} returned ${y}.`,
"errorMessage_CantXBecauseYReturnedZ": (x, y, z) => `can't ${x} because ${y} returned ${z}.`,
"title_CantOpenFile": "Could Not Open File",
"title_RecentlyOpened": "recently opened: ",
"title_NewSeedPassphrase": "Create an Encryption Passphrase",
"description_NewSeedPassphrase": `
This passphrase will be used to encrypt sensitive information.
Use the Generate button to create a suitably secure passphrase.
"Traditional" passwords like ${code("Ro$3bud")} are
${makeLink("https://xkcd.com/936/", `not recommended because they are hard for humans to remember, but easy for computers to guess.`)}
<br/><br/>
${boldRedUnderlined("Write it down on paper")} and save it somewhere secure so you don't lose it.<br/>
${boldRedUnderlined("No one can recover it for you")}.
`,
"title_EnterPassphraseToOpenX": x => `Enter Passphrase to Open ${code(x)}`,
"description_EnterSeedPassphrase": `This file is encrypted. In order to open it,
you have to enter the encryption passphrase specified when it was created.
`,
"label_IHaveWrittenDownOnPaper": "I have written this passphrase down on paper and I will not lose it.",
"title_ReEnterPassphrase": "Re-enter Passphrase",
"description_ReEnterPassphrase": "Prove that you wrote down the passphrase by entering it here.",
"description_MoveToGenerateEntropy": `Move your mouse around to generate entropy (touch and drag on mobile)`,
"errorMessage_WrongPassphraseError": "WrongPassphraseError: MessageAuthenticationCode does not match",
"errorMessage_PassphraseDoesntMatch": "Passphrase doesn't match",
"errorMessage_FormatErrorX": x => `FormatError: File format was different from expected: ${x}`,
"title_Setup": "Setup Wizard",
"title_Plan": "Plan Datacenter Configuration",
"title_Compile": "Compile Credentials",
"title_Write": "Write Boot Disk(s)",
"title_Launch": "Launch Datacenter",
"label_Plan": "Plan",
"label_Compile": "Compile",
"label_Write": "Write",
"label_Launch": "Launch",
"title_License": "GNU General Public License",
"content_License": `
Copyleft &#127279; 2020 Forest Johnson
<br/><br/>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
<br/><br/>
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
`,
"errorMessage_YouMustAcknowlegeSoftwareLicense": "You must acknowledge reciept of software license",
"description_License": `
You should have received a copy of the GNU General Public License
along with this program. If not, see ${makeLink("https://www.gnu.org/licenses/", "https://www.gnu.org/licenses/")}.
`,
"label_AgreeLicenseTerms": "I agree to these license terms",
"title_ISPInformation": "Running Servers at Home",
"content_ISPInformation": `
Many residential Internet Service <span class="strikethrough">Providers</span> Monopolists
like Comcast, AT&T, and Charter/Spectrum have
${makeLink(
"https://www.xfinity.com/Corporate/Customers/Policies/HighSpeedInternetAUP",
"acceptable use policies that prohibit customers from running servers"
)}.
That doesn't mean that they ${bold("will")} suspend your service if you operate a server,
but they have ${bold("reserved the right to do so")} if they decide they don't like you.
<br/><br/>
ISPs have probably added these terms to help deal with thier most troublesome customers:
folks who wreak legal or technical havoc on their network either intentionally or by accident.
<br/><br/>
Monopolistic ISPs make ${bold("big money")} off of subscriptions like yours,
and they will do almost anything to retain a customer.
Most likely you would have to make ${bold("trouble for them")} before
they consider taking any action against your account.
`,
"description_ISPInformation": `
This information is provided to users of this program as ${bold("information only, not as advice or recommendation")}.
The user must make up their own mind and bear responsibility for their use of this software solely upon themself.
For technical information, see: ${makeLink(
url_howServerGardenWorksOnAnyNetwork,
"how server.garden works on any network"
)}.
`,
"title_AboutThisWizard": "About This Application",
"content_AboutThisWizard": `
This application will help you set up your personal datacenter. <br/>
It is split into four sections:
<br/>
<ol class="no-indent">
<li>
${bold("Plan")}
<ul><li>You will make important decisions about how your personal datacenter will work.</li></ul>
</li>
<li>
${bold("Compile")}
<ul><li>You will go over a checklist and enter required credentials.</li></ul>
</li>
<li>
${bold("Write")}
<ul><li>You will insert writeable media (like MicroSD Cards) and they will be converted into boot disks.
During this step, you will be prompted to grant seedpacket Administrator privileges on this computer.</li></ul>
</li>
<li>
${bold("Launch")}
<ul><li>After inserting your boot disks and turning on your servers, your personal datacenter will be online!</li></ul>
</li>
</ol>
`,
"description_AboutThisWizard": `
The choices you make and information you enter will be saved inside your seed file at each step.<br/>
You can ${bold("close this application at any point and resume your progress later")} by reopening your seed file.
`,
"title_Encryption": "Seed Encryption Passphrase",
"description_EncryptionIsImportantBecause": `
While we don't force you do it, passphrase-protecting your seed file should generally be considered a requirement.<br/>
If you don't, any program running on your computer or any person accessing your computer
could concievably ${bold("steal \"the keys to the kingdom\" and take over")} your datacenter without you knowing.
`,
"label_EncryptionOn": "Provide a Passphrase Now",
"label_EncryptionKeep": "Keep Existing Passphrase",
"label_EncryptionOff": "Later / Never",
"description_EncryptionIntermediate": `
This Encryption Passphrase is important to protect against malware & unauthorized access to your systems.
If you chose not to provide an Encryption Passphrase,
you also won't be able to easily restore from backup in the event that you lose your seed file.
`,
"description_EncryptionAdvanced": `
This passphrase will go into the scrypt Key Derivation Function and the resulting key will be used to encrypt your seed file
as well as anything we upload to object storage.
If no passphrase is given, a random passphrase will be stored in the seed file and used for object storage.
`,
"title_TechnicalExpertise": "Choose your Technical Expertise Level",
"label_TechnicalExpertiseBeginner": "Beginner",
"label_TechnicalExpertiseIntermediate": "Intermediate",
"label_TechnicalExpertiseAdvanced": "Advanced",
"description_TechnicalExpertiseBeginnerUser": `
The beginner user knows how to send email, browse the web, and install software.
When their computer isn't doing what they want, the beginner will ask others for help.
`,
"description_TechnicalExpertiseIntermediateUser": `
The intermediate user searches the internet to find solutions to computer problems.
Known to be tech savvy by friends or family, they re-intall windows and
configure home routers with ease. They've even used a command-line interface once or twice!
`,
"description_TechnicalExpertiseAdvancedUser": `
The advanced user is fluent in programming or scripting languages, uses command line interfaces every day,
and has experience in IT fields like
networking, system administration, and information security.
`,
"description_TechnicalExpertise": `
Your answer determines the options you will be presented with.
If you answer Beginner, some options will not be avaliable.
If you choose Advanced options, setup may take longer and when things go wrong, it will be up to you to fix it!
`,
"errorMessage_YouMustSelectTechnicalExpertise": "You must choose a technical expertise level",
"title_Servers": "Servers",
"description_ServersBeginner": `
How many servers are you going to have?
We recommend using two Single Board Computers (like Raspberry Pi 4).
`,
"description_ServersIntermediate": `
How many servers are you going to have? What kind of server hardware will you use?
Servers have to stay on all the time.
You can't use a desktop or laptop computer as both a server and a personal computer with this tool.
We recommend using two Single Board Computers (like Raspberry Pi 4).
`,
"description_ServersAdvanced": `
How many servers are you going to have? What kind of server hardware will you use?
`,
"button_Add": "Add...",
"title_AddServer": "Add Server",
"title_EditServer": "Edit Server",
"label_Hardware": "Hardware: ",
"label_Icon": "Icon: ",
"label_IHaveExternalStorageBeginner": "I have a USB storage disk dedicated for this server. (SSD/HDD, not a flash drive)",
"label_IHaveExternalStorageIntermediate": "I have an external SSD/HDD dedicated for this server.",
"label_IHaveExternalStorageAdvanced": "I have an external SSD/HDD dedicated for this server.",
"label_IUnderstandFlashRisk": `
Server will be painfully slow and liable to destroy the SD Card.
`,
"description_WeDoNotRecommendFlashStorage": `
${boldRedUnderlined("We do not recommend using the SD card as the only disk.")}<br/>
While they are required in order to boot most Single Board Computers (SBCs), <br/>
<b>SD cards wear out over time</b> when they are used in a live system which writes files frequently.
For the type of work servers do, most flash drives and SD cards
are also around 1000x slower compared to a Solid State Disk (SSD).<br/>
For more information, see ${makeLink(url_recommendedPeripherals, "recommended peripherals")}.
`,
"description_DiskPowerAdmonition": (hardware) => `
The ${hardware} is known to crash when a USB device like a disk draws a lot of electric current. </br>
Make sure you choose a hard drive enclosure which comes with its own power supply that plugs into the wall.
`,
"label_Name": "Name: ",
"errorMessage_SelectHardware": "Select server hardware",
"errorMessage_SelectDiskOption": "Select a disk option",
"errorMessage_NameRequired": "Name is required",
"errorMessage_NameTaken": "That name is already taken",
"errorMessage_NameMustBeAValidSubdomain": `
Name can only contain letters, numbers, dashes and underscores. Name cannot begin or end with a dash or underscore
`,
"description_ServerName": `
Examples: "raspberry01" or "goober". These names will be publically visible, so you may want to
avoid putting people's names or street addresses on them. The name cannot be changed later.
`,
"tooltip_HardwareBeginner": `
The "Generic" hardware option is not included because you didn't select Advanced Technical Expertise.
We recommend the listed Single Board Computer hardware models for the easiest setup experience.
`,
"errorMessage_AtLeastOneServerRequired": "At least one server is required.",
"title_DownloadHeadsUp": "Download Heads Up",
"description_DownloadHeadsUpPart1": `
Now that you have specified the server hardware you intend to use, seedpacket will start downloading
linux operating system image(s) for your servers.
`,
"description_DownloadHeadsUpPart2": ` These files will be written to `,
"description_DownloadHeadsUpChecking": ` Checking avaliable disk space, please wait...`,
"description_DownloadHeadsUpConsume": (required) => ` This will use ${required} of disk space.`,
"description_DownloadHeadsUpLowDiskSpace": (free, required) => `
${boldRedUnderlined(`
This will require about ${required} of disk space.
But your disk only has ${free} free! <br/>Please free up some disk space before continuing.
`)}
`,
"description_CheckDiskSpaceFailed": `
${boldRedUnderlined(`Checking avaliable disk space failed.`)}
If you have a few GB free on your disk you should be fine,
otherwise you may want to free up some space before continuing.
`,
"description_DownloadHeadsUp": `
This download will continue in the background while you complete the rest of the Setup Wizard.
`,
"label_Bytes": "bytes",
"label_KB": "kb",
"label_MB": "MB",
"label_GB": "GB",
"label_TB": "TB",
"title_Locations": "Locations",
"title_EditLocation": "Edit Location",
"title_AddLocation": "Add Location",
"description_LocationName": `Examples: "example-street" or "moms-house"`,
"description_Locations": `
Where will your servers reside?
The ideal setup has at least two geographically separated locations,
this way the datacenter will continue to operate during a power or internet outage in either location.
If you want to set up a server in a location outside your home, ask the people in that location first.
`,
"errorMessage_IconRequired": "Icon is required",
"label_RouterAdministration": "Router Administration",
"description_RouterAdministration": `
Can you log in to the router for the local network in this location and make changes to its configuration?
If you don't know or don't want to bother with this, leave the box un-checked.
`,
"label_Ethernet": "Always Connect via Ethernet Cable",
"description_Ethernet": `
Wired connections are preferred when possible, because they are faster and more reliable.
Only check this box if you are certain that there will always be an avaliable ethernet port in this location.
You can still use Ethernet if this box is not checked.
`,
"errorMessage_AtLeastOneLocationRequired": "At least one location is required",
"title_IncomingConnectionsFromTheInternet": "Incoming Connections From The Internet",
"description_IncomingConnectionsFromTheInternetIntermediate": `
When users try to connect to your datacenter, how will that connection reach your servers?
`,
"description_IncomingConnectionsFromTheInternetAdvanced": `
How will you handle public ingress into your datacenter?
`,
"label_IngressCloud": "Cloud-Based Internet Gateway",
"label_IngressDirect": "Direct To Location",
"description_IngressCloudIntermediate": `
This is the easiest and most reliable option, but you will have to sign up for an account
with a cloud compute provider & pay them a monthly bill.
This option always works, even in locations where you would otherwise not be able to run a server at all.
`,
"description_IngressDirectIntermediate": `
Will not work "out of the box". You will have to manually configure the internet router in each location.
This mode of operation won't work at all if you plan on operating an email server.
`,
"description_IngressCloudAdvanced": `
This mode will create a Virtual Private Server instance with a cloud provider of your choice,
to act as a public-facing gateway for incoming traffic.
`,
"description_IngressDirectAdvanced": `
This mode will point domain names at the public IP address of the router in a location where your server is running.
You won't be able to run an email server in this mode
unless you can get your Internet Service Provider to create a reverse DNS entry for you.
`,
"title_CloudServiceType": "Choose Cloud Service Type",
"description_CloudServiceType": `
Do you want to set up your own cloud service accounts?
`,
"label_Greenhouse": "Greenhouse",
"label_DIY": "DIY",
"description_ServiceTypeGreenhouseIntermediate": `
${makeLink(url_greenhouse, "Greenhouse")} is the companion cloud service designed
to make server.garden easier to use.
It handles everything for you with service options ranging from $10/year to $15/month.
`,
"description_ServiceTypeGreenhouseAdvanced": `
${makeLink(url_greenhouse, "Greenhouse")} is the companion cloud service designed
to make server.garden easier to use.
With greenhouse, you can get started quicker and cheaper but it may be harder to do your own customizations.
`,
"description_ServiceTypeDIYIntermediate": `
You will sign up for your own cloud service accounts to use with server.garden.
You will need an account with a Domain Name Registrar, Cloud Storage Provider, and Cloud Compute Provider.
`,
"description_ServiceTypeDIYAdvanced": `
You will sign up for your own cloud service accounts to use with server.garden.
You will need an account with a Domain Name Registrar, Cloud Storage Provider, and Cloud Compute Provider.
`,
"title_ChooseServiceProviders": "Choose Service Providers",
"description_ChooseServiceProviders": `
You will have to sign up for an account with each of your selected providers and pay them for thier services.
We currently only support one or two providers of each kind, but plan on adding more in the future.
We try to recommend smaller, more independent companies that offer better prices
and give back to the community.
`,
"description_ChooseServiceProvidersAdvanced": `
We currently only support one or two providers of each kind, but plan on supporting more in the future.
We proudly support smaller, more independent companies that offer better prices
and give back to the community.
If you want to use Amazon, Google, Microsoft, etc, feel free to build support for those providers yourself!
`,
"label_ComputeProviders": "Cloud Compute",
"label_DomainNameRegistrars": "Domain Name",
"label_ObjectStorageProviders": "Object Storage",
"label_S3Compatible": "S3-Compatible",
"description_ComputeProviders": `
A cloud compute instance, also called a Virtual Private Server (VPS),
dramatically simplifies networking setup for your datacenter.
`,
"description_DomainNameRegistrars": `
Your datacenter needs a domain name to be accessible online.
`,
"description_ObjectStorageProviders": `
Your datacenter requires cloud storage to organize itself.
`,
"errorMessage_ChooseDomainNameRegistrar": `
You must choose a domain name registrar
`,
"errorMessage_ChooseObjectStorageProvider": `
You must choose an object storage provider
`,
"errorMessage_ChooseCloudComputeProvider": `
You must choose a cloud compute provider
`,
"title_Checklist": "Checklist",
"description_Checklist": `
Your datacenter plan is complete!
Here's an overview of required Compile steps based on your plan.
You will be walked through each step, one at a time.
`,
"title_Networks": (arr) => {
if(arr.length > 1) {
return `For the network in each location: ${arr.map(x => `"${x}"`).join(", ")}`;
} else {
return `For the network at "${arr[0]}":`;
}
},
"title_ForTheServerX": x => `For the server '${x}':`,
"description_3Amp": "3 Amp",
"description_XSBCWithYPowerSupply": (x, y) => `${x} single board computer with ${y} power supply`,
"description_ExternalDisk": `USB External SSD (Solid State Disk) or Hard Drive`,
"description_SDCard": `Micro-SD card`,
"description_HighEnduranceSDCard": `High-endurance Micro-SD card`,
"description_EthernetOrUSBWifiDongle": `
Ethernet cable & avaliable ethernet port on a switch or router, OR a USB Wifi dongle
`,
"description_EthernetCable": `
Ethernet cable & avaliable ethernet port on a switch or router
`,
"description_ExternalDiskWithPowerSupply": `
Powered USB SSD (Solid State Disk) or Hard Drive <br/>
(drive enclosure must have its own AC power supply)
`,
"description_FreeWallSocket": `
One free AC power socket with space to plug in a "wall wart" power supply
`,
"description_TwoFreeWallSockets": `
Two free AC power sockets, both with space to plug in a "wall wart" power supply
`,
"description_PracticePortForwarding": `
Log into the Router Administration Panel and make sure
you can forward public ports 80 and 443 to a machine on the network.
`,
"description_PromptToEnterSSHKeys": `
Generate a new key-pair or select a public key to use for Secure Shell (SSH) access to your servers.
`,
"errorMessage_AtLeastOneSSHKeyRequired": "At least one SSH public key is required",
"title_FileIsNotOpenSSHPublicKey": "File Is Not OpenSSH Public Key",
"description_FileIsNotOpenSSHPublicKey": (file) => `
The file ${code(file)} doesn't look right.<br/>
The content of the file should look something like:<br/>
${code("ssh-ed25519 AAAAC3NzaC1l...Yqv== me@my-computer")}
`,
"description_PromptToEnterRootPassword": `
Specify a password for the root user on your servers.
`,
"title_ChecklistCloudProvider": (cloudprovider) => {
const providers = {
greenhouse: {
name: "Greenhouse",
url: url_greenhouse,
},
backblaze: {
name: "Backblaze",
url: url_backblaze,
},
digitalocean: {
name: "DigitalOcean",
url: url_digitalocean,
},
gandi: {
name: "Gandi.net",
url: url_gandi,
},
};
const link = makeLink(providers[cloudprovider].url, providers[cloudprovider].name);
return `Sign up for a ${link} account, then create your ${providers[cloudprovider].name} API Token.`;
},
"description_EnterWirelessNetwork": "Enter the exact name of the wireless network (the SSID) and the wifi password.",
"title_WifiCredentials": "Wifi Credentials",
"label_WirelessNetworkName": "Wifi Network Name",
"label_WirelessNetworkPassword": "Wifi Network Password",
"description_WirelessNetwork": `
Since servers in this location may rely on Wifi to connect to the internet, the Wifi credentials must be entered perfectly.
<b>Every lower or upper case letter, every space,
and every bit of punctuation must match exactly for both the wireless network name (SSID) and the password.</b>
`,
"description_WifiCredentials": `
If you can't be physically present at this location, we recommend asking someone to send you a
screenshot of the Wifi network name (SSID) and a photo of the password.
`,
"errorMessage_SSIDIsRequired": "please enter your wireless network name (SSID)",
"errorMessage_PasswordIsRequired": "please enter your wireless network password",
"title_SSHKeys": "Secure Shell (SSH) Keys",
"description_SSHKeysIntermediate": `
Secure Shell (SSH) allows a user like you to log in to a server across the internet securely.
SSH only works with the text-based Shell interface, not the Graphical User Interface (GUI).
If everything goes well, server.garden won't require you to use this interface,
but it's a good idea to have it avaliable just in case something goes wrong.
`,
"description_SSHKeysAdvanced": `
The SSH public key(s) you select will be added to the ${code("authorized_keys")}
file on the SD card.
It will also be added to ${code("authorized_keys")} on any cloud-based servers we spawn.
`,
"label_IHaveMyOwnSSHKey": "I already have my own SSH key pair(s)",
"label_GenerateSSHKey": "Generate an SSH key pair for me",
"label_SSHPublicKeyFile": "Public Key(s)",
"button_ChooseFile": "Choose File(s)...",
"title_ChooseSSHPublicKey": "Choose SSH Public Key(s)",
"description_FileTypeOpenSSHPublicKey": "openssh public key files (*.pub)",
"description_CreateSSHKey": (keyName) => `
Seedpacket will create a new ssh key pair for you, named ${code(keyName)}<sup>1</sup>.
This key pair will be saved in the default location,
in a hidden folder<sup>2</sup> called ${code(".ssh")} inside your user's home directory on this computer.
<br/>
The private key file will be encrypted with the same passphrase you chose to encrypt your seed file,
meaning you will be prompted to enter the same passphrase if you ever try to use the key yourself.
`,
"label_SaveABackupCopyOfSSHPrivateKey": "Save a backup copy of the SSH private key inside my seed file",
"description_SaveABackupCopyOfSSHPrivateKey": `
Having a backup is a good idea, but you have to be careful with it!
Anyone who can open your seed file would be able to log into your servers.
<br/><br/>
<sup>1</sup> "ed25519" here refers to the
${makeLink("https://en.wikipedia.org/wiki/EdDSA#Ed25519", "cryptographic scheme")} used by the key.<br/>
<sup>2</sup> To see the ${code(".ssh")} folder, you will have to enable "show hidden files" in
the file explorer.
`,
"title_RootPassword": "Servers Root Password",
"description_RootPassword": `
The password for the ${code("root")} user on your servers.
This password is required just in case you need it, for example, for data recovery later on. but you probably wont.
You won't have to type it unless something goes wrong, so we recommend using a password which is quite long.
`,
"label_RootPassword": "Root Password",
"title_BackblazeAccount": "Backblaze Account",
"description_BackblazeAccount": `
After you sign up for a Backblaze account, you will have to create an Application Key.
Finally, copy and paste the Key Id and Secret Key here.
`,
"label_BucketName": "Bucket Name",
"label_KeyId": "Key Id",
"label_SecretKey": "Secret Key",
"errorMessage_BucketNameIsRequired": "please enter a bucket name",
"errorMessage_KeyIdIsRequired": "please enter your key id",
"errorMessage_SecretKeyIsRequired": "please enter your secret key",
"title_CreateBucket": "Create Bucket?",
"description_CreateBucket": (x) => `Create the bucket ${code(x)} ?`,
"title_CantCreateBucket": "Error Creating Bucket",
"title_CantHitBackblaze": "Error connecting to Backblaze",
"title_GandiAccount": "Gandi.net Account",
"description_GandiAccount": `
After you sign up for a Gandi.net account, you will have to register/transfer a domain and create an API Key.
Once you have done that, enter the domain name & copy and paste the API Key here.
`,
"label_DomainName": "Domain Name",
"label_APIKey": "API Key",
"errorMessage_DomainNameIsRequired": "please enter a domain name",
"errorMessage_APIKeyIsRequired": "please enter your API key",
"title_CantHitGandi": "Error connecting to Gandi.net",
"errorMessage_TheDomainXIsNotOwnedByThisAccount": x => `The domain name '${x}' is not owned by this account`,
"errorMessage_GandiIncorrectAPIKey": `
Gandi.net returned HTTP 401 (Unauthorized). This probably means your API key is incorrect.
`,
"title_DigitalOceanAccount": "DigitalOcean Account",
"description_DigitalOceanAccount": `
After you sign up for a DigitalOcean account, you will have to create a "Personal access token" (API token).
Once you have done that, copy and paste the API token here.
`,
"title_CantHitDigitalOcean": "Error connecting to DigitalOcean",
"errorMessage_DigitalOceanIncorrectAPIKey": `
DigitalOcean returned HTTP 401 (Unauthorized). This probably means your API token is incorrect.
`,
"title_SelectDigitalOceanRegion": "Select DigitalOcean Region",
"description_SelectDigitalOceanRegion": "Choose a region near you:",
"description_ChooseGeneric": "Choose...",
"title_DownloadProgress": "Download Progress",
"description_Downloading": "Downloading ",
"description_MethodTorrent": "torrent",
"description_ObtainingMetadata": "obtaining metadata",
"description_Connecting": "connecting",
"description_Downloading": "downloading",
"description_Verifying": "verifying",
"error_TimedOutWatingForTorrent": "timed out waiting for torrent to start downloading",
"description_MethodHTTPS": "https",
"label_Method": "method",
"label_DownloadPhase": "phase",
"label_DownloadSpeed": "speed",
"label_TorrentPeers": "peers",
"description_AllDownloadsComplete": "All downloads have completed!",
"description_ExtractLowDiskSpace": (free, required) => `
${boldRedUnderlined(`
Extracting the downloaded image files will require about ${required} of disk space.
But your disk only has ${free} free! <br/>Please free up some disk space before continuing.
`)}
`,
"description_DownloadProgress": "Status of Linux operating system image downloads",
"title_WriteDisks": "Write Disks",
"description_WriteDisks": `
`,
"label_WriteImageToSD": "Write Image To SD Card: ",
"description_NoBlockDevices": "<no writable external disks detected>",
"description_ChooseDisk": "Choose Disk...",
"label_WriteSpeed": "speed",
"label_WritePhase": "phase",
"description_Extracting1of3": "extracting (1/3)",
"description_Flashing2of3": "flashing (2/3)",
"description_Verifying3of3": "verifying (3/3)",
"description_Configuring": "configuring...",
"button_WriteDisk": "Write Disk...",
"title_OverwriteDisk": "Overwrite Disk",
"description_OverwriteDisk1": "Are you sure you want to overwrite the ",
"description_OverwriteDisk2": " external disk ",
"description_OverwriteDisk3": `
${boldRedUnderlined("All existing data on this disk will be lost.")} <br/>
During the next step, you will be prompted to grant seedpacket Administrator privileges on this computer. <br/>
This is required in order to flash the image to the disk.
`,
"button_AcknowledgementOverwriteDisk": "Overwrite Disk",
"title_DiskFlashError": "Error While Flashing Disk",
"description_DiskFlashError": "An error occurred while attempting to flash the SD card: ",
"title_DiskFlashSuccess": "Success",
"description_DiskFlashSuccess": `
The SD card has been flashed successfully! <br/><br/>
${boldRedUnderlined("In order to prevent accidental data loss")}, please read the instructions in the next
section of the wizard before installing this SD card.
`,
"errorMessage_FlashAtLeastOneSDCard": "Flash at least one SD card to continue",
"errorMessage_WaitForFlashingOperation": "Please wait while flashing operation completes",
"errorMessage_FlashingDiskWasCancelled": "Flashing disk was cancelled",
"title_LaunchServer": "Launch Server Instructions",
"label_Launch": "Launch",
"description_OnlyServersForWhichYouHaveFlashedAnSDCardWillBeShown": `
Only servers for which you have already flashed an SD card will be shown here.
`,
"description_LaunchPowerOff": "Make sure the server is off; make sure it's not plugged into the power supply.",
"description_LaunchInsertSD": "Carefully insert the SD card into the server.",
"description_LaunchEnsureWifi": `
If you can't connect via ethernet, ensure that the ${bold("required")} USB Wifi dongle is plugged into the server.
`,
"description_LaunchEnsureEthernet": "Make sure that the ethernet cable is plugged into the server.",
"description_LaunchEnsureDisk": "Make sure that the external disk is plugged into the server via USB cable.",
"description_LaunchExactlyOneDisk": "Make sure that only one external disk is plugged into the server.",
"description_LaunchEnsureDiskPSU": `
Make sure that the external disk power supply is plugged in and the external disk is switched on.
${bold("NOTE:")} this server won't work with an external disk unless the disk has its own power supply.
`,
"description_LaunchDiskWillBeWiped": `
${boldRedUnderlined("IMPORTANT:")} Once you power on the server, it will completely take over the external disk. <br/>
${boldRedUnderlined("Any existing data on the disk will be lost!")}`,
"description_LaunchPlugInBoot": `
Finally, plug the server's power supply into the server to turn it on.
Once you have done this, proceed to the next screen.
`,
"description_LaunchServer": "description_LaunchServer",
"errorMessage_SelectServer": "Select a server to display launch instructions",
"title_ServerStatus": "Server Status",
"title_StatusOfServerX": x => `${code(x)} Status`,
"description_ServerStatus": `
Once your server is launched and running, it should show an ${code("IN PROGRESS")} or ${code("OK")} status here.
If the status doesn't change from ${code("UNKNOWN")} within 5 minutes of turning on the server,
something went wrong; either it wasn't able to boot or it wasn't able to connect to the internet.
Click on a server to see additional details.
`,
"description_IndicatorUnknown": "UNKNOWN",
"description_IndicatorNotStarted": "NOT STARTED",
"description_IndicatorInProgress": "IN PROGRESS",
"description_IndicatorWarning": "WARNING",
"description_IndicatorNA": "N/A",
"description_IndicatorError": "ERROR",
"description_IndicatorOk": "OK",
"description_IndicatorHistory": "PREVIOUS",
"errorMessage_CantDownloadServerStatus": "Can't Get Server Logs From Object Storage",
"label_PreviousLogs": "Previous Logs: ",
"description_WaitingForXStatusYSeconds": (x, y) => `Waiting for ${x}... ${y}s`,
"title_InfrastructureProvisioning": "Infrastructure Provisioning",
"description_InfrastructureProvisioningLoading": `
Polling object storage for latest build status. <br/>
<br/>
Wait a minute or two for the build to start...
`,
"description_InfrastructureProvisioningBeginner": `
Please wait while the infrastructure for your datacenter is set up...
`,
"description_InfrastructureProvisioningIntermediate": `
Please wait while the infrastructure for your datacenter is set up...
`,
"description_InfrastructureProvisioningAdvanced": `
Rootsystem is running Terraform and Ansible to build cloud infrastructure...
`,
"label_PreviousBuilds": "History: ",
"label_GlobalTerraformProject": "cloud infrastructure",
"label_NodeTerraformProject": x => `${x} infrastructure`,
"label_NodeDockerCompose": x => `${x} applications`,
"label_Diagram": "🎨 Diagram",
"label_Log": "📃 Log",
"button_GeneratePassphrase": "Generate new Passphrase",
"button_AcknowledgementOK": "Ok",
"button_AcknowledgementAdd": "Add",
"button_AcknowledgementSave": "Save",
"button_AcknowledgementContinue": "Continue",
"button_AcknowledgementCreate": "Create",
"button_BackCancel": "Cancel",
"button_Back": "Back"
}
}
translations['en'] = translations['en-US'];
module.exports = { translations }