#31 Enable running multiple instances #33

Merged
kai.boesefeldt merged 3 commits from hector into main 8 months ago
  1. 6
      Documents/Contributing.md
  2. 14
      Documents/GettingStarted.md
  3. 2
      README.md
  4. 3
      ipfs.sh
  5. 1
      issues/0031 DONE Run multiple instances.txt
  6. 26
      odo.cloud.ipfs/ipfs/patchConfig.sh
  7. 11
      odo.cloud.ipfs/src/main/kotlin/straightway/odo/cloud/ipfs/DefaultIpfsSettings.kt
  8. 9
      odo.cloud.ipfs/src/test/kotlin/straightway/odo/cloud/ipfs/DefaultIpfsSettingsTest.kt
  9. 14
      odo.ui.desktop.model/src/main/kotlin/straightway/odo/ui/desktop/model/RootModel.kt
  10. 14
      odo.ui.desktop.model/src/main/kotlin/straightway/odo/ui/desktop/model/SystemPaths.kt
  11. 15
      odo.ui.desktop.model/src/test/kotlin/straightway/odo/ui/desktop/model/RootModelTest.kt
  12. 30
      run.sh

6
Documents/Contributing.md

@ -18,6 +18,8 @@ We appreciate any help we can get with ODO, so feel very welcome! Please check i
We need help in the areas listed below (don't worry if you don't have competences in every point). If you cannot find the proper thing for you, but would like to contribute anyway, don't hesitate! Together we'll find out where you can help us!
We have a modest [quality management system](QualityManagement/README.md) defining some aspects of the development process. Please have a look at this document to check if you find this appropriate for you. If not, don't hesitate do suggest improvements!
## Coding
The general software design of ODO is outlined in the [architecture document](../Design/odoArchitecture.md). Open issues can be found [here](https://codeberg.org/straightway/ODO/issues).
@ -60,7 +62,7 @@ Straightway aims to be a loose group of volunteer software enthousiasts providin
Keeping such a project running efficiently requires a good organization of the team and a team culture, that makes every member feel comfortable, taking into accout, that the team members spend their limited spare time on the project, next to their regular jobs.
Especially (but not only) in the beginning, agility will be a important factor, in order to quickly react on problems or inefficiencies arising from the project organization.
Especially (but not only) in the beginning, agility will be a important factor, in order to quickly react on problems or inefficiencies arising from the project organization. The development process is defined in our [quality management system](QualityManagement/README.md), which needs frequent update and improvement.
## Fund raising
@ -68,6 +70,8 @@ Currently, money is no issue at all for ODO or straightway, and there is no conc
However, first of all a concept for all this is required, which then must be executed. And this is closely related to organizationonal issues.
On other aspect, which may be a bit cross-cutting, is [monetarization](Monetarization.md). Without denying our dedication to freedom and open source, we want to enable small firms to save or earn money with ODO.
## Public relations
For attracting more contriutors and as preparation for announcing releases in the future, we need a concept for public relations.

14
Documents/GettingStarted.md

@ -14,18 +14,18 @@
# Getting Started with ODO
Currently, ODO only supports desktop Linux.
Currently, ODO only supports 64 bit desktop Linux.
## Run
1. Clone the git repository:
```bash
git clone https://codeberg.org/straightway/ODO.git
git clone https://codeberg.org/straightway/odo.git
```
2. Change to the directory named 'ODO' and start the ```run.sh``` bash script.
2. Change to the directory named 'odo' and start the ```run.sh``` bash script.
```bash
cd ODO
cd odo
./run.sh
```
@ -41,6 +41,12 @@ and then locally add it (plus button in the bottom right corner) from the subfol
![Screenshot of the running Hello app](ScreenshotLauncherWithHelloPrototype.png)
Executing ```run.sh``` without parameters executes ODO in its default location ```~/.odo```. For test purposes, you can run multiple instances by passing a numeric argument:
```./run.sh 1```
This starts an odo instance which is hosted under ```build/odoInstances/1``` in your project directory. It uses a different configuration, so that it can run in parallel with the other instances. You can download an app by copy & paste the app's URI from one instance to another.
## Development
To start with development, simply open the 'ODO' folder with [IntellijIDEA](https://www.jetbrains.com/idea/download) (works well with the free community edition).

2
README.md

@ -49,4 +49,4 @@ Please be patient ;-) We have the following milestones until the 1.0 release (ch
I want to contribute!
---------------------
If you would like to contribute, start with [this document](Documents/Contributing.md), and the go on with [onboarding](Documents/Onboarding.md).
If you would like to contribute, start with [this document](Documents/Contributing.md), and the go on with [onboarding](Documents/Onboarding.md). Also have a look at your [quality management system](Documents/QualityManagement/README.md).

3
ipfs.sh

@ -27,4 +27,5 @@ then
./gradlew odo.cloud.ipfs:installIPFS
fi
IPFS_PATH=$ODO_ROOT/ipfs/repo build/install/go-ipfs/ipfs $@
IPFS_PATH=$ODO_ROOT/ipfs/repo build/install/go-ipfs/ipfs "$@"
trap "" EXIT

1
issues/0031 DONE Run multiple instances.txt

@ -0,0 +1 @@
DONE #31 Run multiple instances

26
odo.cloud.ipfs/ipfs/patchConfig.sh

@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Copyright 2016 straightway
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
INSTANCE_NO=$1
SWARM_PORT=$((4001 + "$INSTANCE_NO"))
API_PORT=$((5001 + "$INSTANCE_NO"))
GATEWAY_PORT=$((8080 + "$INSTANCE_NO"))
sed -e "s/\/tcp\/4001/\/tcp\/$SWARM_PORT/g" | \
sed -e "s/\/udp\/4001/\/udp\/$SWARM_PORT/g" | \
sed -e "s/\/tcp\/5001/\/tcp\/$API_PORT/g" | \
sed -e "s/\/tcp\/8080/\/tcp\/$GATEWAY_PORT/g"

11
odo.cloud.ipfs/src/main/kotlin/straightway/odo/cloud/ipfs/DefaultIpfsSettings.kt

@ -22,16 +22,19 @@ import java.nio.file.Path
*/
class DefaultIpfsSettings(settings: Map<String, Any>) : IpfsSettings {
companion object {
val DEFAULT_IPFS_PATH =
Path.of(System.getProperty("user.home"), ".odo", "ipfs").toString()
val DEFAULT_IPFS_REPO_PATH: Path =
Path.of(System.getProperty("user.home"), ".odo", "ipfs", "repo")
}
val ipfsRepoPath = settings["ipfs.repoPath"] as Path?
?: Path.of(DEFAULT_IPFS_PATH, "repo")
val ipfsRepoPath: Path = settings["ipfs.repoPath"]?.toPath() ?: DEFAULT_IPFS_REPO_PATH
val apiAccessString by lazy { ipfsRepoPath.toFile().resolve("api").readText() }
override val apiBaseUri by lazy {
val components = apiAccessString.split('/')
val (_, _, host, _, tcpPort) = components
"http://$host:$tcpPort/api/v0"
}
private fun Any.toPath(): Path = Path.of(toString())
}

9
odo.cloud.ipfs/src/test/kotlin/straightway/odo/cloud/ipfs/DefaultIpfsSettingsTest.kt

@ -20,7 +20,6 @@ import straightway.testing.bdd.Given
import straightway.testing.flow.*
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
class DefaultIpfsSettingsTest {
@ -48,12 +47,12 @@ class DefaultIpfsSettingsTest {
@Test
fun `default path`() {
assertThat(
DefaultIpfsSettings.DEFAULT_IPFS_PATH
DefaultIpfsSettings.DEFAULT_IPFS_REPO_PATH
.startsWith(System.getProperty("user.home")) is_ true
)
assertThat(
DefaultIpfsSettings.DEFAULT_IPFS_PATH is_ equal to_
Regex(".*\\.odo.ipfs")
DefaultIpfsSettings.DEFAULT_IPFS_REPO_PATH.toString() is_ equal to_
Regex(".*\\.odo.ipfs.repo$")
)
}
@ -66,7 +65,7 @@ class DefaultIpfsSettingsTest {
} then {
assertThat(
it.toString() is_ equal to_
Path.of(DefaultIpfsSettings.DEFAULT_IPFS_PATH, "repo").toString()
DefaultIpfsSettings.DEFAULT_IPFS_REPO_PATH.toString()
)
}

14
odo.ui.desktop.model/src/main/kotlin/straightway/odo/ui/desktop/model/RootModel.kt

@ -24,6 +24,7 @@ import straightway.odo.ui.model.*
import tornadofx.Component
import tornadofx.EventBus
import tornadofx.ScopedInstance
import java.nio.file.Path
import java.nio.file.Paths
/**
@ -39,6 +40,10 @@ class RootModel(
val identities: IdentitiesModel
val settings: PropertySet
// region Private
private val ipfsRepoDir = Path.of(baseDir.toString(), "ipfs", "repo").toString()
init {
baseDir.toFile().mkdirs()
@ -46,7 +51,12 @@ class RootModel(
settings =
if (settingsFile.exists())
PropertySet.fromJson(settingsFile.readText(Charsets.UTF_8))
else PropertySet()
else PropertySet(
mapOf(
"ipfs.repoPath" to
ipfsRepoDir
)
)
val services = passedServices ?: ServicesImpl(settings.properties) {
fire(ActionEvent(EventBus.RunOn.ApplicationThread, it))
@ -66,4 +76,6 @@ class RootModel(
subscribe<ActionEvent> { it.action() }
}
// endregion
}

14
odo.ui.desktop.model/src/main/kotlin/straightway/odo/ui/desktop/model/SystemPaths.kt

@ -15,12 +15,22 @@
*/
package straightway.odo.ui.desktop.model
import straightway.compiler.Generated
import java.nio.file.Path
import java.nio.file.Paths
/**
* Definition of system wide paths.
*/
@Generated("Definitions of static paths")
object SystemPaths {
val baseDir get() = Paths.get(System.getProperty("user.home"), ".odo")
val appsRepoPath get() = Paths.get(baseDir.toString(), "apps")
val baseDir: Path
get() = System.getenv("ODO_ROOT").let {
if (it === null)
Paths.get(System.getProperty("user.home"), ".odo")
else Paths.get(it)
}
val appsRepoPath: Path get() = Paths.get(baseDir.toString(), "apps")
}

15
odo.ui.desktop.model/src/test/kotlin/straightway/odo/ui/desktop/model/RootModelTest.kt

@ -93,7 +93,7 @@ class RootModelTest {
// Do nothing
} when_ {
sut.identities
} then { it ->
} then {
if (it !is IdentitiesModelImpl)
fail("$it has wrong type")
@ -102,13 +102,22 @@ class RootModelTest {
}
@Test
fun `missing config_json creates empty SettingsModel`() =
fun `missing config_json creates default SettingsModel`() =
test {
// Do nothing
} when_ {
sut.settings
} then {
assertThat(it.properties is_ empty)
assertThat(
it.properties is_ equal to mapOf(
"ipfs.repoPath" to
Path.of(
SystemPaths.baseDir.toString(),
"ipfs",
"repo"
).toString()
)
)
}
@Test

30
run.sh

@ -17,11 +17,37 @@
trap "exit" INT TERM ERR
trap "kill 0" EXIT
export ODO_ROOT=~/.odo
SCRIPT_DIR=`dirname $0`
SCRIPT_DIR=`realpath $SCRIPT_DIR`
INSTANCE_NO=""
if [ ! "$1" == "" ]
then
INSTANCE_NO=$1
ODO_ROOT="$SCRIPT_DIR/build/odoInstances/$INSTANCE_NO"
fi
./gradlew odo.cloud.ipfs:installIPFS
mkdir -p ~/.odo/ipfs/repo
IPFS_CONFIG_PATH=$ODO_ROOT/ipfs/repo
mkdir -p $IPFS_CONFIG_PATH
if [ ! -e "$IPFS_CONFIG_PATH/config" ]
then
./ipfs.sh init &
wait $!
fi
if [ "$INSTANCE_NO" != "" ]
then
if [ ! -e "$IPFS_CONFIG_PATH/config.orig" ]
then
cp "$IPFS_CONFIG_PATH/config" "$IPFS_CONFIG_PATH/config.orig"
odo.cloud.ipfs/ipfs/patchConfig.sh "$INSTANCE_NO" < "$IPFS_CONFIG_PATH/config.orig" > "$IPFS_CONFIG_PATH/config"
fi
fi
./ipfs.sh daemon --init &
./ipfs.sh daemon &
IPFS_PID=$!
echo "Started IPFS, PID: $IPFS_PID"

Loading…
Cancel
Save