Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
7a3fdfb467 |
|
@ -1,8 +1,5 @@
|
||||||
## Version 0.14.0
|
## Version 0.13.1
|
||||||
- Cosmos is now fully dockerless
|
- Fix a security issue with token (thansk @vncloudsco)
|
||||||
- Improved network IP resolution for containers, including supporting any network mode
|
|
||||||
- Integrated MongoDB as container
|
|
||||||
- Removed all sort of container bootstrapping (much faster boot)
|
|
||||||
|
|
||||||
## Version 0.13.0
|
## Version 0.13.0
|
||||||
- Display container stacks as a group in the UI
|
- Display container stacks as a group in the UI
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import wrap from './wrap';
|
import wrap from './wrap';
|
||||||
import yaml from 'js-yaml';
|
|
||||||
|
|
||||||
function list() {
|
function list() {
|
||||||
return wrap(fetch('/cosmos/api/servapps', {
|
return wrap(fetch('/cosmos/api/servapps', {
|
||||||
|
@ -178,9 +177,9 @@ function createService(serviceData, onProgress) {
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/yaml'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
body: serviceData
|
body: JSON.stringify(serviceData)
|
||||||
};
|
};
|
||||||
|
|
||||||
return fetch('/cosmos/api/docker-service', requestOptions)
|
return fetch('/cosmos/api/docker-service', requestOptions)
|
||||||
|
|
|
@ -176,196 +176,196 @@ const DockerComposeImport = ({ refresh, dockerComposeInit, installerInit, defaul
|
||||||
try {
|
try {
|
||||||
doc = yaml.load(dockerCompose);
|
doc = yaml.load(dockerCompose);
|
||||||
|
|
||||||
// if (typeof doc === 'object' && doc !== null && Object.keys(doc).length > 0 &&
|
if (typeof doc === 'object' && doc !== null && Object.keys(doc).length > 0 &&
|
||||||
// !doc.services && !doc.networks && !doc.volumes) {
|
!doc.services && !doc.networks && !doc.volumes) {
|
||||||
// doc = {
|
doc = {
|
||||||
// services: Object.assign({}, doc)
|
services: Object.assign({}, doc)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // convert to the proper format
|
// convert to the proper format
|
||||||
// if (doc.services) {
|
if (doc.services) {
|
||||||
// Object.keys(doc.services).forEach((key) => {
|
Object.keys(doc.services).forEach((key) => {
|
||||||
// // convert volumes
|
// convert volumes
|
||||||
// if (doc.services[key].volumes) {
|
if (doc.services[key].volumes) {
|
||||||
// if (Array.isArray(doc.services[key].volumes)) {
|
if (Array.isArray(doc.services[key].volumes)) {
|
||||||
// let volumes = [];
|
let volumes = [];
|
||||||
// doc.services[key].volumes.forEach((volume) => {
|
doc.services[key].volumes.forEach((volume) => {
|
||||||
// if (typeof volume === 'object') {
|
if (typeof volume === 'object') {
|
||||||
// volumes.push(volume);
|
volumes.push(volume);
|
||||||
// } else {
|
} else {
|
||||||
// let volumeSplit = volume.split(':');
|
let volumeSplit = volume.split(':');
|
||||||
// let volumeObj = {
|
let volumeObj = {
|
||||||
// source: volumeSplit[0],
|
source: volumeSplit[0],
|
||||||
// target: volumeSplit[1],
|
target: volumeSplit[1],
|
||||||
// type: (volume[0] === '/' || volume[0] === '.') ? 'bind' : 'volume',
|
type: (volume[0] === '/' || volume[0] === '.') ? 'bind' : 'volume',
|
||||||
// };
|
};
|
||||||
// volumes.push(volumeObj);
|
volumes.push(volumeObj);
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// doc.services[key].volumes = volumes;
|
doc.services[key].volumes = volumes;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if(doc.services[key].volumes)
|
if(doc.services[key].volumes)
|
||||||
// Object.values(doc.services[key].volumes).forEach((volume) => {
|
Object.values(doc.services[key].volumes).forEach((volume) => {
|
||||||
// if (volume.source && volume.source[0] === '.') {
|
if (volume.source && volume.source[0] === '.') {
|
||||||
// let defaultPath = (config && config.DockerConfig && config.DockerConfig.DefaultDataPath) || "/usr"
|
let defaultPath = (config && config.DockerConfig && config.DockerConfig.DefaultDataPath) || "/usr"
|
||||||
// volume.source = defaultPath + volume.source.replace('.', '');
|
volume.source = defaultPath + volume.source.replace('.', '');
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
|
|
||||||
// // convert expose
|
// convert expose
|
||||||
// if (doc.services[key].expose) {
|
if (doc.services[key].expose) {
|
||||||
// doc.services[key].expose = doc.services[key].expose.map((port) => {
|
doc.services[key].expose = doc.services[key].expose.map((port) => {
|
||||||
// return '' + port;
|
return '' + port;
|
||||||
// })
|
})
|
||||||
// }
|
}
|
||||||
|
|
||||||
// //convert user
|
//convert user
|
||||||
// if (doc.services[key].user) {
|
if (doc.services[key].user) {
|
||||||
// doc.services[key].user = '' + doc.services[key].user;
|
doc.services[key].user = '' + doc.services[key].user;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // convert labels:
|
// convert labels:
|
||||||
// if (doc.services[key].labels) {
|
if (doc.services[key].labels) {
|
||||||
// if (Array.isArray(doc.services[key].labels)) {
|
if (Array.isArray(doc.services[key].labels)) {
|
||||||
// let labels = {};
|
let labels = {};
|
||||||
// doc.services[key].labels.forEach((label) => {
|
doc.services[key].labels.forEach((label) => {
|
||||||
// const [key, value] = label.split(/=(.*)/s);
|
const [key, value] = label.split(/=(.*)/s);
|
||||||
// labels['' + key] = '' + value;
|
labels['' + key] = '' + value;
|
||||||
// });
|
});
|
||||||
// doc.services[key].labels = labels;
|
doc.services[key].labels = labels;
|
||||||
// }
|
}
|
||||||
// if (typeof doc.services[key].labels == 'object') {
|
if (typeof doc.services[key].labels == 'object') {
|
||||||
// let labels = {};
|
let labels = {};
|
||||||
// Object.keys(doc.services[key].labels).forEach((keylabel) => {
|
Object.keys(doc.services[key].labels).forEach((keylabel) => {
|
||||||
// labels['' + keylabel] = '' + doc.services[key].labels[keylabel];
|
labels['' + keylabel] = '' + doc.services[key].labels[keylabel];
|
||||||
// });
|
});
|
||||||
// doc.services[key].labels = labels;
|
doc.services[key].labels = labels;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // convert environment
|
// convert environment
|
||||||
// if (doc.services[key].environment) {
|
if (doc.services[key].environment) {
|
||||||
// if (!Array.isArray(doc.services[key].environment)) {
|
if (!Array.isArray(doc.services[key].environment)) {
|
||||||
// let environment = [];
|
let environment = [];
|
||||||
// Object.keys(doc.services[key].environment).forEach((keyenv) => {
|
Object.keys(doc.services[key].environment).forEach((keyenv) => {
|
||||||
// environment.push(keyenv + '=' + doc.services[key].environment[keyenv]);
|
environment.push(keyenv + '=' + doc.services[key].environment[keyenv]);
|
||||||
// });
|
});
|
||||||
// doc.services[key].environment = environment;
|
doc.services[key].environment = environment;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // convert network
|
// convert network
|
||||||
// if (doc.services[key].networks) {
|
if (doc.services[key].networks) {
|
||||||
// if (Array.isArray(doc.services[key].networks)) {
|
if (Array.isArray(doc.services[key].networks)) {
|
||||||
// let networks = {};
|
let networks = {};
|
||||||
// doc.services[key].networks.forEach((network) => {
|
doc.services[key].networks.forEach((network) => {
|
||||||
// if (typeof network === 'object') {
|
if (typeof network === 'object') {
|
||||||
// networks['' + network.name] = network;
|
networks['' + network.name] = network;
|
||||||
// }
|
}
|
||||||
// else
|
else
|
||||||
// networks['' + network] = {};
|
networks['' + network] = {};
|
||||||
// });
|
});
|
||||||
// doc.services[key].networks = networks;
|
doc.services[key].networks = networks;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // convert devices
|
// convert devices
|
||||||
// if (doc.services[key].devices) {
|
if (doc.services[key].devices) {
|
||||||
// console.log(1)
|
console.log(1)
|
||||||
// if (Array.isArray(doc.services[key].devices)) {
|
if (Array.isArray(doc.services[key].devices)) {
|
||||||
// console.log(2)
|
console.log(2)
|
||||||
// let devices = [];
|
let devices = [];
|
||||||
// doc.services[key].devices.forEach((device) => {
|
doc.services[key].devices.forEach((device) => {
|
||||||
// if(device.indexOf(':') === -1) {
|
if(device.indexOf(':') === -1) {
|
||||||
// devices.push(device + ':' + device);
|
devices.push(device + ':' + device);
|
||||||
// } else {
|
} else {
|
||||||
// devices.push(device);
|
devices.push(device);
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// doc.services[key].devices = devices;
|
doc.services[key].devices = devices;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // convert command
|
// convert command
|
||||||
// if (doc.services[key].command) {
|
if (doc.services[key].command) {
|
||||||
// if (typeof doc.services[key].command !== 'string') {
|
if (typeof doc.services[key].command !== 'string') {
|
||||||
// doc.services[key].command = doc.services[key].command.join(' ');
|
doc.services[key].command = doc.services[key].command.join(' ');
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // ensure container_name
|
// ensure container_name
|
||||||
// if (!doc.services[key].container_name) {
|
if (!doc.services[key].container_name) {
|
||||||
// doc.services[key].container_name = key;
|
doc.services[key].container_name = key;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // convert healthcheck
|
// convert healthcheck
|
||||||
// if (doc.services[key].healthcheck) {
|
if (doc.services[key].healthcheck) {
|
||||||
// const toConvert = ["timeout", "interval", "start_period"];
|
const toConvert = ["timeout", "interval", "start_period"];
|
||||||
// toConvert.forEach((valT) => {
|
toConvert.forEach((valT) => {
|
||||||
// if(typeof doc.services[key].healthcheck[valT] === 'string') {
|
if(typeof doc.services[key].healthcheck[valT] === 'string') {
|
||||||
// let original = doc.services[key].healthcheck[valT];
|
let original = doc.services[key].healthcheck[valT];
|
||||||
// let value = parseInt(original);
|
let value = parseInt(original);
|
||||||
// if (original.endsWith('m')) {
|
if (original.endsWith('m')) {
|
||||||
// value = value * 60;
|
value = value * 60;
|
||||||
// } else if (original.endsWith('h')) {
|
} else if (original.endsWith('h')) {
|
||||||
// value = value * 60 * 60;
|
value = value * 60 * 60;
|
||||||
// } else if (original.endsWith('d')) {
|
} else if (original.endsWith('d')) {
|
||||||
// value = value * 60 * 60 * 24;
|
value = value * 60 * 60 * 24;
|
||||||
// }
|
}
|
||||||
// doc.services[key].healthcheck[valT] = value;
|
doc.services[key].healthcheck[valT] = value;
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // convert networks
|
// convert networks
|
||||||
// if (doc.networks) {
|
if (doc.networks) {
|
||||||
// if (Array.isArray(doc.networks)) {
|
if (Array.isArray(doc.networks)) {
|
||||||
// let networks = {};
|
let networks = {};
|
||||||
// doc.networks.forEach((network) => {
|
doc.networks.forEach((network) => {
|
||||||
// if (typeof network === 'object') {
|
if (typeof network === 'object') {
|
||||||
// networks['' + network.name] = network;
|
networks['' + network.name] = network;
|
||||||
// }
|
}
|
||||||
// else
|
else
|
||||||
// networks['' + network] = {};
|
networks['' + network] = {};
|
||||||
// });
|
});
|
||||||
// doc.networks = networks;
|
doc.networks = networks;
|
||||||
// } else {
|
} else {
|
||||||
// let networks = {};
|
let networks = {};
|
||||||
// Object.keys(doc.networks).forEach((key) => {
|
Object.keys(doc.networks).forEach((key) => {
|
||||||
// networks['' + key] = doc.networks[key] || {};
|
networks['' + key] = doc.networks[key] || {};
|
||||||
// });
|
});
|
||||||
// doc.networks = networks;
|
doc.networks = networks;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // convert volumes
|
// convert volumes
|
||||||
// if (doc.volumes) {
|
if (doc.volumes) {
|
||||||
// if (Array.isArray(doc.volumes)) {
|
if (Array.isArray(doc.volumes)) {
|
||||||
// let volumes = {};
|
let volumes = {};
|
||||||
// doc.volumes.forEach((volume) => {
|
doc.volumes.forEach((volume) => {
|
||||||
// if (!volume) {
|
if (!volume) {
|
||||||
// volume = {};
|
volume = {};
|
||||||
// }
|
}
|
||||||
// if (typeof volume === 'object') {
|
if (typeof volume === 'object') {
|
||||||
// volumes['' + volume.name] = volume;
|
volumes['' + volume.name] = volume;
|
||||||
// }
|
}
|
||||||
// else
|
else
|
||||||
// volumes['' + volume] = {};
|
volumes['' + volume] = {};
|
||||||
// });
|
});
|
||||||
// doc.volumes = volumes;
|
doc.volumes = volumes;
|
||||||
// } else {
|
} else {
|
||||||
// let volumes = {};
|
let volumes = {};
|
||||||
// Object.keys(doc.volumes).forEach((key) => {
|
Object.keys(doc.volumes).forEach((key) => {
|
||||||
// volumes['' + key] = doc.volumes[key] || {};
|
volumes['' + key] = doc.volumes[key] || {};
|
||||||
// });
|
});
|
||||||
// doc.volumes = volumes;
|
doc.volumes = volumes;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setYmlError(e.message);
|
setYmlError(e.message);
|
||||||
|
|
|
@ -21,7 +21,6 @@ import { Link } from 'react-router-dom';
|
||||||
import { smartDockerLogConcat, tryParseProgressLog } from '../../../utils/docker';
|
import { smartDockerLogConcat, tryParseProgressLog } from '../../../utils/docker';
|
||||||
import { LoadingButton } from '@mui/lab';
|
import { LoadingButton } from '@mui/lab';
|
||||||
import LogLine from '../../../components/logLine';
|
import LogLine from '../../../components/logLine';
|
||||||
import yaml from 'js-yaml';
|
|
||||||
|
|
||||||
const preStyle = {
|
const preStyle = {
|
||||||
backgroundColor: '#000',
|
backgroundColor: '#000',
|
||||||
|
@ -85,7 +84,7 @@ const NewDockerService = ({service, refresh}) => {
|
||||||
setLog([
|
setLog([
|
||||||
'Creating Service... ',
|
'Creating Service... ',
|
||||||
])
|
])
|
||||||
API.docker.createService(yaml.dump(service), (newlog) => {
|
API.docker.createService(service, (newlog) => {
|
||||||
setLog((old) => smartDockerLogConcat(old, newlog));
|
setLog((old) => smartDockerLogConcat(old, newlog));
|
||||||
preRef.current.scrollTop = preRef.current.scrollHeight;
|
preRef.current.scrollTop = preRef.current.scrollHeight;
|
||||||
if (newlog.includes('[OPERATION SUCCEEDED]')) {
|
if (newlog.includes('[OPERATION SUCCEEDED]')) {
|
||||||
|
@ -119,7 +118,8 @@ const NewDockerService = ({service, refresh}) => {
|
||||||
<pre style={preStyle} ref={preRef}>
|
<pre style={preStyle} ref={preRef}>
|
||||||
{!log.length && `
|
{!log.length && `
|
||||||
# You are about to create the following service(s):
|
# You are about to create the following service(s):
|
||||||
${yaml.dump(service)}`
|
|
||||||
|
${JSON.stringify(service, false ,2)}`
|
||||||
}
|
}
|
||||||
{log.map((l) => {
|
{log.map((l) => {
|
||||||
return <LogLine message={tryParseProgressLog(l)} docker isMobile={!screenMin} />
|
return <LogLine message={tryParseProgressLog(l)} docker isMobile={!screenMin} />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "cosmos-server",
|
"name": "cosmos-server",
|
||||||
"version": "0.13.0",
|
"version": "0.13.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "test-server.js",
|
"main": "test-server.js",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
|
|
@ -115,8 +115,7 @@ func ConfigApiPatch(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
utils.Log("RouteSettingsUpdate: Service needs update: "+name)
|
utils.Log("RouteSettingsUpdate: Service needs update: "+name)
|
||||||
|
|
||||||
// TODO CACHE BURST IN IP RESOLUTION
|
utils.ReBootstrapContainer(name)
|
||||||
// utils.ReBootstrapContainer(name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package docker
|
package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// "encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -12,7 +12,6 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os/user"
|
"os/user"
|
||||||
"errors"
|
"errors"
|
||||||
// "gopkg.in/yaml.v2"
|
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/docker/docker/api/types/mount"
|
"github.com/docker/docker/api/types/mount"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
|
@ -230,76 +229,23 @@ func CreateServiceRoute(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// decoder := yaml.NewDecoder(req.Body)
|
decoder := json.NewDecoder(req.Body)
|
||||||
// var serviceRequest DockerServiceCreateRequest
|
var serviceRequest DockerServiceCreateRequest
|
||||||
// err := decoder.Decode(&serviceRequest)
|
err := decoder.Decode(&serviceRequest)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// utils.Error("CreateService - decode - ", err)
|
utils.Error("CreateService - decode - ", err)
|
||||||
// fmt.Fprintf(w, "[OPERATION FAILED] Bad request: "+err.Error(), http.StatusBadRequest, "DS003")
|
fmt.Fprintf(w, "[OPERATION FAILED] Bad request: "+err.Error(), http.StatusBadRequest, "DS003")
|
||||||
// flusher.Flush()
|
flusher.Flush()
|
||||||
// utils.HTTPError(w, "Bad request: " + err.Error(), http.StatusBadRequest, "DS003")
|
utils.HTTPError(w, "Bad request: " + err.Error(), http.StatusBadRequest, "DS003")
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
|
|
||||||
/*CreateService(serviceRequest,
|
CreateService(serviceRequest,
|
||||||
func (msg string) {
|
func (msg string) {
|
||||||
fmt.Fprintf(w, msg)
|
fmt.Fprintf(w, msg)
|
||||||
flusher.Flush()
|
flusher.Flush()
|
||||||
},
|
},
|
||||||
)*/
|
)
|
||||||
|
|
||||||
ServiceName := "test-wesh"
|
|
||||||
|
|
||||||
filePath := utils.CONFIGFOLDER + "compose/" + ServiceName
|
|
||||||
|
|
||||||
// Create the folder if does not exist, and output docker-compose.yml
|
|
||||||
if _, err := os.Stat(utils.CONFIGFOLDER + "compose/"); os.IsNotExist(err) {
|
|
||||||
os.MkdirAll(utils.CONFIGFOLDER + "compose/", 0750)
|
|
||||||
}
|
|
||||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
|
||||||
os.MkdirAll(filePath, 0750)
|
|
||||||
}
|
|
||||||
|
|
||||||
// create or truncate the file
|
|
||||||
file, err := os.Create(filePath + "/docker-compose.yml")
|
|
||||||
if err != nil {
|
|
||||||
utils.Error("CreateService - create - ", err)
|
|
||||||
fmt.Fprintf(w, "[OPERATION FAILED] Internal server error: "+err.Error(), http.StatusInternalServerError, "DS004")
|
|
||||||
flusher.Flush()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
// write to file
|
|
||||||
ymlBody := req.Body
|
|
||||||
writer := bufio.NewWriter(file)
|
|
||||||
_, err = writer.ReadFrom(ymlBody)
|
|
||||||
if err != nil {
|
|
||||||
utils.Error("CreateService - write - ", err)
|
|
||||||
fmt.Fprintf(w, "[OPERATION FAILED] Internal server error: "+err.Error(), http.StatusInternalServerError, "DS005")
|
|
||||||
flusher.Flush()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.Flush()
|
|
||||||
|
|
||||||
// Compose up
|
|
||||||
err = ComposeUp(filePath, func(message string, outputType int) {
|
|
||||||
fmt.Fprintf(w, "%s\n", message)
|
|
||||||
flusher.Flush()
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
utils.Error("CreateService - composeup - ", err)
|
|
||||||
fmt.Fprintf(w, "[OPERATION FAILED] Internal server error: "+err.Error(), http.StatusInternalServerError, "DS006")
|
|
||||||
flusher.Flush()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Write a response to the client
|
|
||||||
fmt.Fprintf(w, "[OPERATION SUCCESSFUL] Service created successfully", http.StatusOK, "DS007")
|
|
||||||
flusher.Flush()
|
|
||||||
} else {
|
} else {
|
||||||
utils.Error("CreateService: Method not allowed" + req.Method, nil)
|
utils.Error("CreateService: Method not allowed" + req.Method, nil)
|
||||||
utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001")
|
utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001")
|
||||||
|
@ -340,21 +286,6 @@ func CreateService(serviceRequest DockerServiceCreateRequest, OnLog func(string)
|
||||||
var rollbackActions []DockerServiceCreateRollback
|
var rollbackActions []DockerServiceCreateRollback
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
serviceName := ""
|
|
||||||
for serviceName = range serviceRequest.Services {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if serviceRequest.Networks contains service-default, if not, create it
|
|
||||||
if _, ok := serviceRequest.Networks[serviceName + "-default"]; !ok {
|
|
||||||
serviceRequest.Networks[serviceName + "-default"] = ContainerCreateRequestNetwork{
|
|
||||||
Name: serviceName + "-default",
|
|
||||||
Driver: "bridge",
|
|
||||||
Attachable: true,
|
|
||||||
Internal: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create networks
|
// Create networks
|
||||||
for networkToCreateName, networkToCreate := range serviceRequest.Networks {
|
for networkToCreateName, networkToCreate := range serviceRequest.Networks {
|
||||||
utils.Log(fmt.Sprintf("Creating network %s...", networkToCreateName))
|
utils.Log(fmt.Sprintf("Creating network %s...", networkToCreateName))
|
||||||
|
@ -365,7 +296,7 @@ func CreateService(serviceRequest DockerServiceCreateRequest, OnLog func(string)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if networkToCreate.Driver == "" {
|
if networkToCreate.Driver == "" {
|
||||||
networkToCreate.Driver = serviceName + "-default"
|
networkToCreate.Driver = "bridge"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exNetworkDef.Driver != networkToCreate.Driver) {
|
if (exNetworkDef.Driver != networkToCreate.Driver) {
|
||||||
|
@ -491,8 +422,7 @@ func CreateService(serviceRequest DockerServiceCreateRequest, OnLog func(string)
|
||||||
OnLog(fmt.Sprintf("Checking service %s...\n", serviceName))
|
OnLog(fmt.Sprintf("Checking service %s...\n", serviceName))
|
||||||
|
|
||||||
// If container request a Cosmos network, create and attach it
|
// If container request a Cosmos network, create and attach it
|
||||||
|
if (container.Labels["cosmos-force-network-secured"] == "true" || strings.ToLower(container.Labels["cosmos-network-name"]) == "auto") &&
|
||||||
/*if (container.Labels["cosmos-force-network-secured"] == "true" || strings.ToLower(container.Labels["cosmos-network-name"]) == "auto") &&
|
|
||||||
container.Labels["cosmos-network-name"] == "" {
|
container.Labels["cosmos-network-name"] == "" {
|
||||||
utils.Log(fmt.Sprintf("Forcing secure %s...", serviceName))
|
utils.Log(fmt.Sprintf("Forcing secure %s...", serviceName))
|
||||||
OnLog(fmt.Sprintf("Forcing secure %s...\n", serviceName))
|
OnLog(fmt.Sprintf("Forcing secure %s...\n", serviceName))
|
||||||
|
@ -535,7 +465,7 @@ func CreateService(serviceRequest DockerServiceCreateRequest, OnLog func(string)
|
||||||
|
|
||||||
AttachNetworkToCosmos(container.Labels["cosmos-network-name"])
|
AttachNetworkToCosmos(container.Labels["cosmos-network-name"])
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
|
||||||
utils.Log(fmt.Sprintf("Creating container %s...", container.Name))
|
utils.Log(fmt.Sprintf("Creating container %s...", container.Name))
|
||||||
OnLog(fmt.Sprintf("Creating container %s...\n", container.Name))
|
OnLog(fmt.Sprintf("Creating container %s...\n", container.Name))
|
||||||
|
@ -889,8 +819,6 @@ func CreateService(serviceRequest DockerServiceCreateRequest, OnLog func(string)
|
||||||
// connect to networks
|
// connect to networks
|
||||||
for netName, netConfig := range container.Networks {
|
for netName, netConfig := range container.Networks {
|
||||||
utils.Log("CreateService: Connecting to network: " + netName)
|
utils.Log("CreateService: Connecting to network: " + netName)
|
||||||
|
|
||||||
//TODO: THIS IS WRONG https://pkg.go.dev/github.com/docker/docker@v24.0.7+incompatible/api/types/network#EndpointSettings
|
|
||||||
err = DockerClient.NetworkConnect(DockerContext, netName, container.Name, &network.EndpointSettings{
|
err = DockerClient.NetworkConnect(DockerContext, netName, container.Name, &network.EndpointSettings{
|
||||||
Aliases: netConfig.Aliases,
|
Aliases: netConfig.Aliases,
|
||||||
IPAddress: netConfig.IPV4Address,
|
IPAddress: netConfig.IPV4Address,
|
||||||
|
|
|
@ -1,150 +1,150 @@
|
||||||
package docker
|
package docker
|
||||||
|
|
||||||
// import (
|
import (
|
||||||
// "github.com/azukaar/cosmos-server/src/utils"
|
"github.com/azukaar/cosmos-server/src/utils"
|
||||||
// "github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
// "os"
|
"os"
|
||||||
// "fmt"
|
"fmt"
|
||||||
// "regexp"
|
"regexp"
|
||||||
// )
|
)
|
||||||
|
|
||||||
// func BootstrapAllContainersFromTags() []error {
|
func BootstrapAllContainersFromTags() []error {
|
||||||
// errD := Connect()
|
errD := Connect()
|
||||||
// if errD != nil {
|
if errD != nil {
|
||||||
// return []error{errD}
|
return []error{errD}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// errors := []error{}
|
errors := []error{}
|
||||||
|
|
||||||
// containers, err := DockerClient.ContainerList(DockerContext, types.ContainerListOptions{})
|
containers, err := DockerClient.ContainerList(DockerContext, types.ContainerListOptions{})
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// utils.Error("Docker Container List", err)
|
utils.Error("Docker Container List", err)
|
||||||
// return []error{err}
|
return []error{err}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// for _, container := range containers {
|
for _, container := range containers {
|
||||||
// errB := BootstrapContainerFromTags(container.ID)
|
errB := BootstrapContainerFromTags(container.ID)
|
||||||
// if errB != nil {
|
if errB != nil {
|
||||||
// utils.Error("Bootstrap Container From Tags", errB)
|
utils.Error("Bootstrap Container From Tags", errB)
|
||||||
// errors = append(errors, errB)
|
errors = append(errors, errB)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return errors
|
return errors
|
||||||
// }
|
}
|
||||||
|
|
||||||
// func UnsecureContainer(container types.ContainerJSON) (string, error) {
|
func UnsecureContainer(container types.ContainerJSON) (string, error) {
|
||||||
// RemoveLabels(container, []string{
|
RemoveLabels(container, []string{
|
||||||
// "cosmos-force-network-secured",
|
"cosmos-force-network-secured",
|
||||||
// });
|
});
|
||||||
// return EditContainer(container.ID, container, false)
|
return EditContainer(container.ID, container, false)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// func BootstrapContainerFromTags(containerID string) error {
|
func BootstrapContainerFromTags(containerID string) error {
|
||||||
// errD := Connect()
|
errD := Connect()
|
||||||
// if errD != nil {
|
if errD != nil {
|
||||||
// return errD
|
return errD
|
||||||
// }
|
}
|
||||||
|
|
||||||
// selfContainer := types.ContainerJSON{}
|
selfContainer := types.ContainerJSON{}
|
||||||
// if os.Getenv("HOSTNAME") != "" {
|
if os.Getenv("HOSTNAME") != "" {
|
||||||
// var errS error
|
var errS error
|
||||||
// selfContainer, errS = DockerClient.ContainerInspect(DockerContext, os.Getenv("HOSTNAME"))
|
selfContainer, errS = DockerClient.ContainerInspect(DockerContext, os.Getenv("HOSTNAME"))
|
||||||
// if errS != nil {
|
if errS != nil {
|
||||||
// utils.Error("DockerContainerBootstrapSelfInspect", errS)
|
utils.Error("DockerContainerBootstrapSelfInspect", errS)
|
||||||
// return errS
|
return errS
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// utils.Log("Bootstrap Container From Tags: " + containerID)
|
utils.Log("Bootstrap Container From Tags: " + containerID)
|
||||||
|
|
||||||
// container, err := DockerClient.ContainerInspect(DockerContext, containerID)
|
container, err := DockerClient.ContainerInspect(DockerContext, containerID)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// utils.Error("DockerContainerBootstrapInspect", err)
|
utils.Error("DockerContainerBootstrapInspect", err)
|
||||||
// return err
|
return err
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // check if any route has been added to the container
|
// check if any route has been added to the container
|
||||||
// config := utils.GetMainConfig()
|
config := utils.GetMainConfig()
|
||||||
// if(!HasLabel(container, "cosmos-network-name")) {
|
if(!HasLabel(container, "cosmos-network-name")) {
|
||||||
// for _, route := range config.HTTPConfig.ProxyConfig.Routes {
|
for _, route := range config.HTTPConfig.ProxyConfig.Routes {
|
||||||
// utils.Debug("No cosmos-network-name label on container "+container.Name)
|
utils.Debug("No cosmos-network-name label on container "+container.Name)
|
||||||
// pattern := fmt.Sprintf(`(?i)^(([a-z]+):\/\/)?%s(:?[0-9]+)?$`, container.Name[1:])
|
pattern := fmt.Sprintf(`(?i)^(([a-z]+):\/\/)?%s(:?[0-9]+)?$`, container.Name[1:])
|
||||||
// match, _ := regexp.MatchString(pattern, route.Target)
|
match, _ := regexp.MatchString(pattern, route.Target)
|
||||||
// if route.Mode == "SERVAPP" && match {
|
if route.Mode == "SERVAPP" && match {
|
||||||
// utils.Log("Adding cosmos-network-name label to container "+container.Name)
|
utils.Log("Adding cosmos-network-name label to container "+container.Name)
|
||||||
// AddLabels(container, map[string]string{
|
AddLabels(container, map[string]string{
|
||||||
// "cosmos-network-name": "auto",
|
"cosmos-network-name": "auto",
|
||||||
// })
|
})
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // Check cosmos-network-name tag
|
// Check cosmos-network-name tag
|
||||||
// isCosmosCon, _, needsUpdate := IsConnectedToASecureCosmosNetwork(selfContainer, container)
|
isCosmosCon, _, needsUpdate := IsConnectedToASecureCosmosNetwork(selfContainer, container)
|
||||||
|
|
||||||
// if(IsLabel(container, "cosmos-force-network-secured")) {
|
if(IsLabel(container, "cosmos-force-network-secured")) {
|
||||||
// utils.Log(container.Name+": Checking Force network secured")
|
utils.Log(container.Name+": Checking Force network secured")
|
||||||
|
|
||||||
// // check if connected to bridge and to a cosmos network
|
// check if connected to bridge and to a cosmos network
|
||||||
// isCon := IsConnectedToNetwork(container, "bridge")
|
isCon := IsConnectedToNetwork(container, "bridge")
|
||||||
|
|
||||||
// if isCon || !isCosmosCon {
|
if isCon || !isCosmosCon {
|
||||||
// utils.Log(container.Name+": Needs isolating on a secured network")
|
utils.Log(container.Name+": Needs isolating on a secured network")
|
||||||
// needsRestart := false
|
needsRestart := false
|
||||||
// var errCT error
|
var errCT error
|
||||||
// if !isCosmosCon {
|
if !isCosmosCon {
|
||||||
// utils.Debug(container.Name+": Not connected to a cosmos network")
|
utils.Debug(container.Name+": Not connected to a cosmos network")
|
||||||
// needsRestart, errCT = ConnectToSecureNetwork(container)
|
needsRestart, errCT = ConnectToSecureNetwork(container)
|
||||||
// if errCT != nil {
|
if errCT != nil {
|
||||||
// utils.Warn("DockerContainerBootstrapConnectToSecureNetwork -- Cannot connect to network, removing force secure")
|
utils.Warn("DockerContainerBootstrapConnectToSecureNetwork -- Cannot connect to network, removing force secure")
|
||||||
// _, errUn := UnsecureContainer(container)
|
_, errUn := UnsecureContainer(container)
|
||||||
// if errUn != nil {
|
if errUn != nil {
|
||||||
// utils.Fatal("DockerContainerBootstrapUnsecureContainer -- A broken container state is preventing Cosmos from functionning. Please remove the cosmos-force-secure label from the container "+container.Name+" manually", errUn)
|
utils.Fatal("DockerContainerBootstrapUnsecureContainer -- A broken container state is preventing Cosmos from functionning. Please remove the cosmos-force-secure label from the container "+container.Name+" manually", errUn)
|
||||||
// return errCT
|
return errCT
|
||||||
// }
|
}
|
||||||
// return errCT
|
return errCT
|
||||||
// }
|
}
|
||||||
// if needsRestart {
|
if needsRestart {
|
||||||
// utils.Log(container.Name+": Will restart to apply changes")
|
utils.Log(container.Name+": Will restart to apply changes")
|
||||||
// needsUpdate = true
|
needsUpdate = true
|
||||||
// } else {
|
} else {
|
||||||
// utils.Log(container.Name+": Connected to new network")
|
utils.Log(container.Name+": Connected to new network")
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// if !needsRestart && isCon {
|
if !needsRestart && isCon {
|
||||||
// utils.Log(container.Name+": Disconnecting from bridge network")
|
utils.Log(container.Name+": Disconnecting from bridge network")
|
||||||
// errDisc := DockerClient.NetworkDisconnect(DockerContext, "bridge", containerID, true)
|
errDisc := DockerClient.NetworkDisconnect(DockerContext, "bridge", containerID, true)
|
||||||
// if errDisc != nil {
|
if errDisc != nil {
|
||||||
// utils.Warn("DockerContainerBootstrapDisconnectFromBridge -- Cannot disconnect from Bridge, removing force secure")
|
utils.Warn("DockerContainerBootstrapDisconnectFromBridge -- Cannot disconnect from Bridge, removing force secure")
|
||||||
// _, errUn := UnsecureContainer(container)
|
_, errUn := UnsecureContainer(container)
|
||||||
// if errUn != nil {
|
if errUn != nil {
|
||||||
// utils.Fatal("DockerContainerBootstrapUnsecureContainer -- A broken container state is preventing Cosmos from functionning. Please remove the cosmos-force-secure label from the container "+container.Name+" manually", errUn)
|
utils.Fatal("DockerContainerBootstrapUnsecureContainer -- A broken container state is preventing Cosmos from functionning. Please remove the cosmos-force-secure label from the container "+container.Name+" manually", errUn)
|
||||||
// return errDisc
|
return errDisc
|
||||||
// }
|
}
|
||||||
// return errDisc
|
return errDisc
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if(len(GetAllPorts(container)) > 0) {
|
if(len(GetAllPorts(container)) > 0) {
|
||||||
// utils.Log("Removing unsecure ports bindings from "+container.Name)
|
utils.Log("Removing unsecure ports bindings from "+container.Name)
|
||||||
// // remove all ports
|
// remove all ports
|
||||||
// UnexposeAllPorts(&container)
|
UnexposeAllPorts(&container)
|
||||||
// needsUpdate = true
|
needsUpdate = true
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if(needsUpdate) {
|
if(needsUpdate) {
|
||||||
// _, errEdit := EditContainer(containerID, container, false)
|
_, errEdit := EditContainer(containerID, container, false)
|
||||||
// if errEdit != nil {
|
if errEdit != nil {
|
||||||
// utils.Error("Docker Boostrap, couldn't update container: ", errEdit)
|
utils.Error("Docker Boostrap, couldn't update container: ", errEdit)
|
||||||
// return errEdit
|
return errEdit
|
||||||
// }
|
}
|
||||||
// utils.Debug("Done updating Container From Tags after Bootstrapping: " + container.Name)
|
utils.Debug("Done updating Container From Tags after Bootstrapping: " + container.Name)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// utils.Log("Done bootstrapping Container From Tags: " + container.Name)
|
utils.Log("Done bootstrapping Container From Tags: " + container.Name)
|
||||||
|
|
||||||
// return nil
|
return nil
|
||||||
// }
|
}
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
package docker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
"os/exec"
|
|
||||||
|
|
||||||
"github.com/azukaar/cosmos-server/src/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
Stdout = iota
|
|
||||||
Stderr
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
// readOutput reads from the given reader and uses the callback function to handle the output.
|
|
||||||
func readOutput(r io.Reader, callback func(message string, outputType int), outputType int) {
|
|
||||||
scanner := bufio.NewScanner(r)
|
|
||||||
for scanner.Scan() {
|
|
||||||
callback(scanner.Text(), outputType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExecCommand runs the specified command and uses a callback function to handle the output.
|
|
||||||
func ExecCommand(callback func(message string, outputType int), args ...string) error {
|
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
|
||||||
utils.Debug("Running command: " + cmd.String())
|
|
||||||
|
|
||||||
callback("Running command: " + cmd.String(), Stdout)
|
|
||||||
|
|
||||||
// Create pipes for stdout and stderr
|
|
||||||
stdoutPipe, err := cmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
stderrPipe, err := cmd.StderrPipe()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the command
|
|
||||||
if err := cmd.Start(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read from stdout and stderr in separate goroutines
|
|
||||||
go readOutput(stdoutPipe, callback, Stdout)
|
|
||||||
go readOutput(stderrPipe, callback, Stderr)
|
|
||||||
|
|
||||||
// Wait for the command to finish
|
|
||||||
return cmd.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ComposeUp(filePath string, callback func(message string, outputType int)) error {
|
|
||||||
return ExecCommand(callback, "docker", "compose", "--project-directory", filePath, "up", "--remove-orphans", "-d")
|
|
||||||
}
|
|
|
@ -140,7 +140,7 @@ func DebouncedExportDocker() {
|
||||||
|
|
||||||
func onDockerStarted(containerID string) {
|
func onDockerStarted(containerID string) {
|
||||||
utils.Debug("onDockerStarted: " + containerID)
|
utils.Debug("onDockerStarted: " + containerID)
|
||||||
// BootstrapContainerFromTags(containerID)
|
BootstrapContainerFromTags(containerID)
|
||||||
DebouncedExportDocker()
|
DebouncedExportDocker()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/azukaar/cosmos-server/src/utils"
|
"github.com/azukaar/cosmos-server/src/utils"
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
|
@ -51,68 +49,22 @@ func (c *Cache) Set(key string, value string, duration time.Duration) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func _getContainerIPByName(containerName string) (string, error) {
|
func _getContainerIPByName(containerName string) (string, error) {
|
||||||
errD := Connect()
|
|
||||||
if errD != nil {
|
|
||||||
return "", errD
|
|
||||||
}
|
|
||||||
|
|
||||||
container, err := DockerClient.ContainerInspect(DockerContext, containerName)
|
container, err := DockerClient.ContainerInspect(DockerContext, containerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prioritize "host"
|
// Prioritize "host"
|
||||||
// if net, ok := container.NetworkSettings.Networks["host"]; ok && net.IPAddress != "" {
|
if net, ok := container.NetworkSettings.Networks["host"]; ok && net.IPAddress != "" {
|
||||||
// return "localhost", nil
|
return net.IPAddress, nil
|
||||||
// }
|
|
||||||
|
|
||||||
// Next, prioritize "bridge"
|
|
||||||
// if net, ok := container.NetworkSettings.Networks["bridge"]; ok && net.IPAddress != "" {
|
|
||||||
// return net.IPAddress, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if container is in network mode host
|
|
||||||
if container.HostConfig.NetworkMode == "host" {
|
|
||||||
return "localhost", nil
|
|
||||||
} else if container.HostConfig.NetworkMode == "bridge" || container.HostConfig.NetworkMode == "default" || container.HostConfig.NetworkMode == "" {
|
|
||||||
// if container is in network mode bridge or default or not set
|
|
||||||
|
|
||||||
for _, net := range container.NetworkSettings.Networks {
|
|
||||||
// if this network is using the bridge driver
|
|
||||||
if net.IPAddress != "" {
|
|
||||||
return net.IPAddress, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if strings.HasPrefix(string(container.HostConfig.NetworkMode), "container:") {
|
|
||||||
// if container is in network mode container:<container_name>
|
|
||||||
|
|
||||||
// get the container name
|
|
||||||
otherContainerName := strings.TrimPrefix(string(container.HostConfig.NetworkMode), "container:")
|
|
||||||
// get the ip of the other container
|
|
||||||
ip, err := _getContainerIPByName(otherContainerName)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return ip, nil
|
|
||||||
} else {
|
|
||||||
// if container is in network mode <network_name>
|
|
||||||
|
|
||||||
// get the network name
|
|
||||||
networkName := string(container.HostConfig.NetworkMode)
|
|
||||||
// get the network
|
|
||||||
network, err := DockerClient.NetworkInspect(DockerContext, networkName, types.NetworkInspectOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
// get the ip of the container in the network
|
|
||||||
for _, containerEP := range network.Containers {
|
|
||||||
if containerEP.Name == container.Name {
|
|
||||||
return network.IPAM.Config[0].Gateway, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, if nothing, return the IP of the first network we find
|
// Next, prioritize "bridge"
|
||||||
|
if net, ok := container.NetworkSettings.Networks["bridge"]; ok && net.IPAddress != "" {
|
||||||
|
return net.IPAddress, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, return the IP of the first network we find
|
||||||
for _, net := range container.NetworkSettings.Networks {
|
for _, net := range container.NetworkSettings.Networks {
|
||||||
if net.IPAddress != "" {
|
if net.IPAddress != "" {
|
||||||
return net.IPAddress, nil
|
return net.IPAddress, nil
|
||||||
|
|
|
@ -41,11 +41,7 @@ func startHTTPServer(router *mux.Router) error {
|
||||||
DisableGeneralOptionsHandler: true,
|
DisableGeneralOptionsHandler: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.Getenv("HOSTNAME") != "" {
|
docker.CheckPorts()
|
||||||
docker.CheckPorts()
|
|
||||||
} else {
|
|
||||||
proxy.InitInternalTCPProxy()
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.Log("Listening to HTTP on : 0.0.0.0:" + serverPortHTTP)
|
utils.Log("Listening to HTTP on : 0.0.0.0:" + serverPortHTTP)
|
||||||
|
|
||||||
|
@ -123,11 +119,7 @@ func startHTTPSServer(router *mux.Router) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect ports
|
// Redirect ports
|
||||||
if os.Getenv("HOSTNAME") != "" {
|
docker.CheckPorts()
|
||||||
docker.CheckPorts()
|
|
||||||
} else {
|
|
||||||
proxy.InitInternalTCPProxy()
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.Log("Now listening to HTTPS on :" + serverPortHTTPS)
|
utils.Log("Now listening to HTTPS on :" + serverPortHTTPS)
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,8 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
utils.Log("Starting...")
|
utils.Log("Starting...")
|
||||||
|
|
||||||
// utils.ReBootstrapContainer = docker.BootstrapContainerFromTags
|
utils.ReBootstrapContainer = docker.BootstrapContainerFromTags
|
||||||
utils.PushShieldMetrics = metrics.PushShieldMetrics
|
utils.PushShieldMetrics = metrics.PushShieldMetrics
|
||||||
utils.GetContainerIPByName = docker.GetContainerIPByName
|
|
||||||
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
||||||
|
@ -32,7 +31,7 @@ func main() {
|
||||||
|
|
||||||
docker.DockerListenEvents()
|
docker.DockerListenEvents()
|
||||||
|
|
||||||
// docker.BootstrapAllContainersFromTags()
|
docker.BootstrapAllContainersFromTags()
|
||||||
|
|
||||||
docker.RemoveSelfUpdater()
|
docker.RemoveSelfUpdater()
|
||||||
|
|
||||||
|
|
|
@ -1,142 +0,0 @@
|
||||||
package proxy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/azukaar/cosmos-server/src/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
activeProxies map[string]chan bool
|
|
||||||
proxiesLock sync.Mutex
|
|
||||||
)
|
|
||||||
|
|
||||||
func handleClient(client net.Conn, server net.Conn, stop chan bool) {
|
|
||||||
defer client.Close()
|
|
||||||
defer server.Close()
|
|
||||||
|
|
||||||
// Forward data between client and server, and watch for stop signal
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
io.Copy(server, client)
|
|
||||||
done <- struct{}{}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
io.Copy(client, server)
|
|
||||||
done <- struct{}{}
|
|
||||||
}()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-stop:
|
|
||||||
return
|
|
||||||
case <-done:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func startProxy(listenAddr string, target string, stop chan bool) {
|
|
||||||
listener, err := net.Listen("tcp", listenAddr)
|
|
||||||
if err != nil {
|
|
||||||
utils.Error("Failed to listen on " + listenAddr, err)
|
|
||||||
}
|
|
||||||
defer listener.Close()
|
|
||||||
|
|
||||||
utils.Log("Proxy listening on "+listenAddr+", forwarding to " + target)
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-stop:
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
client, err := listener.Accept()
|
|
||||||
if err != nil {
|
|
||||||
utils.Error("Failed to accept connection: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
server, err := net.Dial("tcp", target)
|
|
||||||
if err != nil {
|
|
||||||
utils.Error("Failed to connect to server: %v", err)
|
|
||||||
client.Close()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
go handleClient(client, server, stop)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func initInternalPortProxy(ports []string, destination string) {
|
|
||||||
proxiesLock.Lock()
|
|
||||||
defer proxiesLock.Unlock()
|
|
||||||
|
|
||||||
// Initialize activeProxies map if it's nil
|
|
||||||
if activeProxies == nil {
|
|
||||||
activeProxies = make(map[string]chan bool)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop any existing proxies that are not in the new list
|
|
||||||
for port, stop := range activeProxies {
|
|
||||||
if !contains(ports, port) {
|
|
||||||
close(stop)
|
|
||||||
delete(activeProxies, port)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start new proxies for ports in the list that aren't already running
|
|
||||||
for _, port := range ports {
|
|
||||||
if _, exists := activeProxies[port]; !exists {
|
|
||||||
utils.Log("Network Starting internal proxy for port " + port)
|
|
||||||
stop := make(chan bool)
|
|
||||||
activeProxies[port] = stop
|
|
||||||
go startProxy(":"+port, destination, stop)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to check if a slice contains a string
|
|
||||||
func contains(slice []string, item string) bool {
|
|
||||||
for _, a := range slice {
|
|
||||||
if a == item {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitInternalTCPProxy() {
|
|
||||||
utils.Log("Network: Initializing internal TCP proxy")
|
|
||||||
|
|
||||||
config := utils.GetMainConfig()
|
|
||||||
expectedPorts := []string{}
|
|
||||||
isHTTPS := utils.IsHTTPS
|
|
||||||
HTTPPort := config.HTTPConfig.HTTPPort
|
|
||||||
HTTPSPort := config.HTTPConfig.HTTPSPort
|
|
||||||
routes := config.HTTPConfig.ProxyConfig.Routes
|
|
||||||
targetPort := HTTPPort
|
|
||||||
if isHTTPS {
|
|
||||||
targetPort = HTTPSPort
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, route := range routes {
|
|
||||||
if route.UseHost && strings.Contains(route.Host, ":") {
|
|
||||||
hostname := route.Host
|
|
||||||
port := strings.Split(hostname, ":")[1]
|
|
||||||
expectedPorts = append(expectedPorts, port)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// append hostname port
|
|
||||||
hostname := config.HTTPConfig.Hostname
|
|
||||||
if strings.Contains(hostname, ":") {
|
|
||||||
hostnameport := strings.Split(hostname, ":")[1]
|
|
||||||
if hostnameport != targetPort {
|
|
||||||
expectedPorts = append(expectedPorts, hostnameport)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initInternalPortProxy(expectedPorts, "localhost:"+targetPort)
|
|
||||||
}
|
|
|
@ -91,7 +91,7 @@ func UserRegister(w http.ResponseWriter, req *http.Request) {
|
||||||
"RegisterKeyExp": time.Time{},
|
"RegisterKeyExp": time.Time{},
|
||||||
"RegisteredAt": RegisteredAt,
|
"RegisteredAt": RegisteredAt,
|
||||||
"LastPasswordChangedAt": time.Now(),
|
"LastPasswordChangedAt": time.Now(),
|
||||||
"PassowrdCycle": user.PasswordCycle + 1,
|
"PasswordCycle": user.PasswordCycle + 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ import (
|
||||||
|
|
||||||
|
|
||||||
var client *mongo.Client
|
var client *mongo.Client
|
||||||
var IsDBaContainer bool
|
|
||||||
|
|
||||||
func DB() error {
|
func DB() error {
|
||||||
if(GetMainConfig().DisableUserManagement) {
|
if(GetMainConfig().DisableUserManagement) {
|
||||||
|
@ -39,19 +38,6 @@ func DB() error {
|
||||||
|
|
||||||
opts := options.Client().ApplyURI(mongoURL).SetRetryWrites(true).SetWriteConcern(writeconcern.New(writeconcern.WMajority()))
|
opts := options.Client().ApplyURI(mongoURL).SetRetryWrites(true).SetWriteConcern(writeconcern.New(writeconcern.WMajority()))
|
||||||
|
|
||||||
IsDBaContainer = false
|
|
||||||
|
|
||||||
if os.Getenv("HOSTNAME") == "" {
|
|
||||||
hostname := opts.Hosts[0]
|
|
||||||
Log("Getting Mongo DB IP from name : " + hostname)
|
|
||||||
ip, _ := GetContainerIPByName(hostname)
|
|
||||||
if ip != "" {
|
|
||||||
IsDBaContainer = true
|
|
||||||
opts.SetHosts([]string{ip + ":27017"})
|
|
||||||
Log("Mongo DB IP : " + ip)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err = mongo.Connect(context.TODO(), opts)
|
client, err = mongo.Connect(context.TODO(), opts)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -33,8 +33,7 @@ var NeedsRestart = false
|
||||||
var UpdateAvailable = map[string]bool{}
|
var UpdateAvailable = map[string]bool{}
|
||||||
|
|
||||||
var RestartHTTPServer func()
|
var RestartHTTPServer func()
|
||||||
// var ReBootstrapContainer func(string) error
|
var ReBootstrapContainer func(string) error
|
||||||
var GetContainerIPByName func(string) (string, error)
|
|
||||||
|
|
||||||
var LetsEncryptErrors = []string{}
|
var LetsEncryptErrors = []string{}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue