func init() { config.AddRequiredDirectory( 0750, filepath.Join(config.ContainerBasePath(), "env", "contents"), filepath.Join(config.ContainerBasePath(), "ports", "descriptions"), filepath.Join(config.ContainerBasePath(), "ports", "interfaces"), ) config.AddRequiredDirectory( 0755, filepath.Join(config.SystemdBasePath(), "container-active.target.wants"), ) }
func init() { handler := &containerPermission{} AddPermissionHandler("", handler) AddPermissionHandler(ContainerPermissionType, handler) // Register the required configuration directories config.AddRequiredDirectory( 0755, config.ContainerBasePath(), filepath.Join(config.ContainerBasePath(), "access", "containers", "ssh"), filepath.Join(config.ContainerBasePath(), "keys", "public"), ) }
func init() { config.AddRequiredDirectory( 0755, config.ContainerBasePath(), filepath.Join(config.ContainerBasePath(), "home"), filepath.Join(config.ContainerBasePath(), "units"), ) config.AddRequiredDirectory( 0750, filepath.Join(config.ContainerBasePath(), "targets"), filepath.Join(config.ContainerBasePath(), "slices"), ) }
func init() { // Register the required configuration directories config.AddRequiredDirectory( 0755, filepath.Join(config.ContainerBasePath(), "access", "git"), ) }
func disableAllUnits() { systemd := systemd.Connection() for _, path := range []string{ filepath.Join(config.ContainerBasePath(), "units"), } { filepath.Walk(path, func(p string, info os.FileInfo, err error) error { if os.IsNotExist(err) { return nil } if err != nil { log.Printf("init: Can't read %s: %v", p, err) return nil } if info.IsDir() { return nil } if !isSystemdFile(p) { return nil } fmt.Printf("Stopping and disabling %s\n", filepath.Base(p)) if status, err := systemd.StopUnit(filepath.Base(p), "fail"); err != nil { log.Printf("init: Unable to stop %s: %v, %+v", p, status, err) } if _, err := systemd.DisableUnitFiles([]string{p}, false); err != nil { log.Printf("init: Unable to disable %s: %+v", p, err) } return nil }) if err := systemd.Reload(); err != nil { log.Printf("init: systemd reload failed: %+v", err) } } }
func (i RepoIdentifier) GitAccessPathFor(name string, write bool) string { var access string if write { access = ".write" } else { access = ".read" } return utils.IsolateContentPathWithPerm(filepath.Join(config.ContainerBasePath(), "access", "git"), string(i), name+access, 0775) }
func GetDockerContainerPacketCounts(d *docker.DockerClient) (map[containers.Identifier]int, error) { serviceFiles, err := filepath.Glob(filepath.Join(gearconfig.ContainerBasePath(), "units", "**", containers.IdentifierPrefix+"*.service")) if err != nil { return nil, err } ids := make([]string, 0) packetCount := make(map[containers.Identifier]int) for _, s := range serviceFiles { id := filepath.Base(s) if strings.HasPrefix(id, containers.IdentifierPrefix) && strings.HasSuffix(id, ".service") { id = id[len(containers.IdentifierPrefix):(len(id) - len(".service"))] if id, err := containers.NewIdentifier(id); err == nil { ids = append(ids, string(id)) packetCount[id] = 0 } } } containerIPs, err := d.GetContainerIPs(ids) if err != nil { return nil, err } cmd := exec.Command("/sbin/iptables-save", "-c") output, err := cmd.Output() if err != nil { return nil, err } scan := bufio.NewScanner(bytes.NewBuffer(output)) for scan.Scan() { line := scan.Text() if strings.Contains(line, "-A DOCKER ! -i docker0") && strings.Contains(line, "-j DNAT") { //Example: [0:0] -A DOCKER ! -i docker0 -p tcp -m tcp --dport 4000 -j DNAT --to-destination 172.17.0.3:8080 items := strings.Fields(line) packets, _ := strconv.Atoi(strings.Split(items[0], ":")[0][1:]) destIp := strings.Split(items[15], ":")[0] id, _ := containers.NewIdentifier(containerIPs[destIp]) packetCount[id] = packetCount[id] + packets } if strings.Contains(line, "-A OUTPUT -d 127.0.0.1/32 -p tcp -m tcp --dport") && strings.Contains(line, "-m comment --comment ") { //Example: [5850:394136] -A OUTPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 4000 -m comment --comment 0001 -j ACCEPT items := strings.Fields(line) packets, _ := strconv.Atoi(strings.Split(items[0], ":")[0][1:]) if id, err := containers.NewIdentifier(items[14]); err == nil { packetCount[id] = packetCount[id] + packets } } } return packetCount, nil }
// Removes unused definition files by checking what definition files // are actually in use in the service file. func (r *UnitFilesCleanup) Clean(ctx *CleanerContext) { if !ctx.Repair { return } ctx.LogInfo.Println("--- UNIT FILES REPAIR ---") unitsPath := filepath.Join(config.ContainerBasePath(), "units") filepath.Walk(unitsPath, func(path string, info os.FileInfo, err error) error { if os.IsNotExist(err) { return nil } if err != nil { ctx.LogError.Printf("repair_unit_files: Can't read %s: %v", path, err) return nil } if info.IsDir() { return nil } if filepath.Ext(path) != ".service" { return nil } props, er := systemd.GetUnitFileProperties(path) if er != nil { ctx.LogError.Println("Failed to get unit file properties") return er } // X-ContainerRequestId property has the name of the definition file in use. currDefinitionFile, ok := props["X-ContainerRequestId"] if !ok { return nil } containerId, ok := props["X-ContainerId"] if !ok { return nil } definitionsDirPath := filepath.Join(filepath.Dir(path), containerId) removeFilesExcluding(currDefinitionFile, definitionsDirPath, r.unusedFor, ctx) // TODO: Also remove empty directories. // TODO: Validate the ports and other information in the systemd file. return nil }) }
func InitializeSystemdFile(fType SystemdFileType, name string, template *template.Template, values interface{}, start bool) error { var partPath string var ext string switch { case fType == TargetType: partPath = "targets" ext = ".target" case fType == SliceType: partPath = "slices" ext = ".slice" case fType == UnitType: partPath = "units" ext = ".service" } path := filepath.Join(config.ContainerBasePath(), partPath, name+ext) unit, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0666) if os.IsExist(err) { return nil } else if err != nil { return err } if errs := template.Execute(unit, values); errs != nil { log.Printf("gear: Unable to write %s %s: %v", fType, name, errs) return nil } if errc := unit.Close(); errc != nil { log.Printf("gear: Unable to close target %s %s: %v", fType, name, errc) return nil } if start { log.Printf("systemd: Starting %s", path) _, err = StartAndEnableUnit(Connection(), name+ext, path, "fail") return err } else { return EnableAndReloadUnit(Connection(), name+ext, path) } return nil }
// Remove port allocations that don't point to systemd definition files. func (r *PortsCleanup) Clean(ctx *CleanerContext) { ctx.LogInfo.Println("--- PORTS CLEANUP ---") portsPath := filepath.Join(config.ContainerBasePath(), "ports", "interfaces") filepath.Walk(portsPath, func(path string, fi os.FileInfo, err error) error { if os.IsNotExist(err) { return nil } if err != nil { ctx.LogError.Printf("Can't read %s: %v", path, err) return nil } if fi.IsDir() { return nil } if fi.Mode()&os.ModeSymlink == os.ModeSymlink { unitPath, err := os.Readlink(path) if err != nil { ctx.LogError.Printf("Failed to read the link: %v", err) return nil } if _, err := os.Stat(unitPath); os.IsNotExist(err) { ctx.LogInfo.Printf("Recovering port %v as it does not point to a definition file.", path) if !ctx.DryRun { if err = os.Remove(path); err != nil { ctx.LogError.Printf("Failed to remove %s: %v", path, err) } } return nil } } return nil }) }
func (i Identifier) VersionedUnitPathFor(suffix string) string { return utils.IsolateContentPathWithPerm(filepath.Join(config.ContainerBasePath(), "units"), string(i), suffix, 0775) }
func init() { // Bind mounted into the router config.AddRequiredDirectory(0755, filepath.Join(config.ContainerBasePath(), "router")) }
func (i Identifier) PortDescriptionPathFor() string { return utils.IsolateContentPath(filepath.Join(config.ContainerBasePath(), "ports", "descriptions"), string(i), "") }
func init() { // Bind mounted into the githost config.AddRequiredDirectory(0755, filepath.Join(config.ContainerBasePath(), "git")) }
func publicKeyPathFor(f utils.Fingerprint) string { return utils.IsolateContentPathWithPerm(filepath.Join(config.ContainerBasePath(), "keys", "public"), f.ToShortName(), "", 0775) }
func (i RepoIdentifier) RepositoryPathFor() string { return filepath.Join(config.ContainerBasePath(), "git", string(i)) }
func (i RepoIdentifier) HomePath() string { return utils.IsolateContentPathWithPerm(filepath.Join(config.ContainerBasePath(), fmt.Sprintf("%shome", RepoIdentifierPrefix)), string(i), "home", 0775) }
func (i Identifier) NetworkLinksPathFor() string { return utils.IsolateContentPath(filepath.Join(config.ContainerBasePath(), "ports", "links"), string(i), "") }
func (i RepoIdentifier) UnitPathFor() string { base := utils.IsolateContentPath(filepath.Join(config.ContainerBasePath(), "units"), string(i), "") return filepath.Join(filepath.Dir(base), i.UnitNameFor()) }
func (i Identifier) SocketUnitPathFor() string { base := utils.IsolateContentPathWithPerm(filepath.Join(config.ContainerBasePath(), "units"), string(i), "", 0775) return filepath.Join(filepath.Dir(base), i.SocketUnitNameFor()) }
func (i RepoIdentifier) SshAccessBasePath() string { return utils.IsolateContentPathWithPerm(filepath.Join(config.ContainerBasePath(), "access", "git"), string(i), "", 0775) }
func SshAccessPathFor(i containers.Identifier, name string) string { return utils.IsolateContentPathWithPerm(filepath.Join(config.ContainerBasePath(), "access", "containers", "ssh"), string(i), name, 0775) }
func (d Device) DevicePath() string { return filepath.Join(config.ContainerBasePath(), "ports", "interfaces", string(d)) }
func verifyDataPaths() error { for _, path := range []string{ config.ContainerBasePath(), filepath.Join(config.ContainerBasePath(), "home"), filepath.Join(config.ContainerBasePath(), "git"), filepath.Join(config.ContainerBasePath(), "units"), filepath.Join(config.ContainerBasePath(), "access", "git"), filepath.Join(config.ContainerBasePath(), "access", "containers", "ssh"), filepath.Join(config.ContainerBasePath(), "keys", "public"), } { if err := checkPath(path, os.FileMode(0755), true); err != nil { return err } if err := selinux.RestoreCon(path, false); err != nil { return err } } for _, path := range []string{ filepath.Join(config.ContainerBasePath(), "targets"), filepath.Join(config.ContainerBasePath(), "slices"), filepath.Join(config.ContainerBasePath(), "env", "contents"), filepath.Join(config.ContainerBasePath(), "ports", "descriptions"), filepath.Join(config.ContainerBasePath(), "ports", "interfaces"), } { if err := checkPath(path, os.FileMode(0750), true); err != nil { return err } if err := selinux.RestoreCon(path, false); err != nil { return err } } return nil }
func (i Identifier) EnvironmentPathFor() string { return utils.IsolateContentPath(filepath.Join(config.ContainerBasePath(), "env", "contents"), string(i), "") }
func init() { homePath := filepath.Join(config.ContainerBasePath(), "home") AddCleaner(&HomeCleanup{homePath: homePath}) }
func (i Identifier) BaseHomePath() string { return utils.IsolateContentPathWithPerm(filepath.Join(config.ContainerBasePath(), "home"), string(i), "", 0775) }
func (i Identifier) BackendPathfor() string { return utils.IsolateContentPath(filepath.Join(config.ContainerBasePath(), "routes", "backends"), string(i), "") }