package manifest import ( "path/filepath" "github.com/osbuild/osbuild-composer/internal/common" "github.com/osbuild/osbuild-composer/internal/osbuild" "github.com/osbuild/osbuild-composer/internal/platform" "github.com/osbuild/osbuild-composer/internal/rpmmd" ) // An OSTreeCommitServer contains an nginx server serving // an embedded ostree commit. type OSTreeCommitServer struct { Base // Packages to install in addition to the ones required by the // pipeline. ExtraPackages []string // Extra repositories to install packages from ExtraRepos []rpmmd.RepoConfig // TODO: should this be configurable? Language string platform platform.Platform repos []rpmmd.RepoConfig packageSpecs []rpmmd.PackageSpec commitPipeline *OSTreeCommit nginxConfigPath string listenPort string } // NewOSTreeCommitServer creates a new pipeline. The content // is built from repos and packages, which must contain nginx. commitPipeline // is a pipeline producing an ostree commit to be served. nginxConfigPath // is the path to the main nginx config file and listenPort is the port // nginx will be listening on. func NewOSTreeCommitServer(m *Manifest, buildPipeline *Build, platform platform.Platform, repos []rpmmd.RepoConfig, commitPipeline *OSTreeCommit, nginxConfigPath, listenPort string) *OSTreeCommitServer { p := &OSTreeCommitServer{ Base: NewBase(m, "container-tree", buildPipeline), platform: platform, repos: repos, commitPipeline: commitPipeline, nginxConfigPath: nginxConfigPath, listenPort: listenPort, Language: "en_US", } if commitPipeline.Base.manifest != m { panic("commit pipeline from different manifest") } buildPipeline.addDependent(p) m.addPipeline(p) return p } func (p *OSTreeCommitServer) getPackageSetChain() []rpmmd.PackageSet { packages := []string{"nginx"} return []rpmmd.PackageSet{ { Include: append(packages, p.ExtraPackages...), Repositories: append(p.repos, p.ExtraRepos...), }, } } func (p *OSTreeCommitServer) getBuildPackages() []string { packages := []string{ "rpm", "rpm-ostree", } return packages } func (p *OSTreeCommitServer) getPackageSpecs() []rpmmd.PackageSpec { return p.packageSpecs } func (p *OSTreeCommitServer) serializeStart(packages []rpmmd.PackageSpec) { if len(p.packageSpecs) > 0 { panic("double call to serializeStart()") } p.packageSpecs = packages } func (p *OSTreeCommitServer) serializeEnd() { if len(p.packageSpecs) == 0 { panic("serializeEnd() call when serialization not in progress") } p.packageSpecs = nil } func (p *OSTreeCommitServer) serialize() osbuild.Pipeline { if len(p.packageSpecs) == 0 { panic("serialization not started") } pipeline := p.Base.serialize() pipeline.AddStage(osbuild.NewRPMStage(osbuild.NewRPMStageOptions(p.repos), osbuild.NewRpmStageSourceFilesInputs(p.packageSpecs))) pipeline.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: p.Language})) htmlRoot := "/usr/share/nginx/html" repoPath := filepath.Join(htmlRoot, "repo") pipeline.AddStage(osbuild.NewOSTreeInitStage(&osbuild.OSTreeInitStageOptions{Path: repoPath})) pipeline.AddStage(osbuild.NewOSTreePullStage( &osbuild.OSTreePullStageOptions{Repo: repoPath}, osbuild.NewOstreePullStageInputs("org.osbuild.pipeline", "name:"+p.commitPipeline.Name(), p.commitPipeline.ref), )) // make nginx log and lib directories world writeable, otherwise nginx can't start in // an unprivileged container pipeline.AddStage(osbuild.NewChmodStage(chmodStageOptions("/var/log/nginx", "a+rwX", true))) pipeline.AddStage(osbuild.NewChmodStage(chmodStageOptions("/var/lib/nginx", "a+rwX", true))) pipeline.AddStage(osbuild.NewNginxConfigStage(nginxConfigStageOptions(p.nginxConfigPath, htmlRoot, p.listenPort))) return pipeline } func nginxConfigStageOptions(path, htmlRoot, listen string) *osbuild.NginxConfigStageOptions { // configure nginx to work in an unprivileged container cfg := &osbuild.NginxConfig{ Listen: listen, Root: htmlRoot, Daemon: common.BoolToPtr(false), PID: "/tmp/nginx.pid", } return &osbuild.NginxConfigStageOptions{ Path: path, Config: cfg, } } func chmodStageOptions(path, mode string, recursive bool) *osbuild.ChmodStageOptions { return &osbuild.ChmodStageOptions{ Items: map[string]osbuild.ChmodStagePathOptions{ path: {Mode: mode, Recursive: recursive}, }, } } func (p *OSTreeCommitServer) GetPlatform() platform.Platform { return p.platform }